@aura3d/rendering 1.3.3 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ForwardPass.js +7 -1
- package/dist/ForwardPass.js.map +1 -1
- package/dist/MorphTarget.d.ts +1 -0
- package/dist/MorphTarget.d.ts.map +1 -1
- package/dist/MorphTarget.js.map +1 -1
- package/dist/Renderer.js +7 -1
- package/dist/Renderer.js.map +1 -1
- package/package.json +38 -4
- package/src/ArchitecturalLightingFixtures.ts +0 -241
- package/src/ArchitecturalMaterialCatalog.ts +0 -130
- package/src/ArchitecturalMeasurementFixtures.ts +0 -155
- package/src/BRDFLut.ts +0 -47
- package/src/CameraFraming.ts +0 -200
- package/src/CanonicalSceneFixtures.ts +0 -95
- package/src/CascadedShadowMaps.ts +0 -449
- package/src/ColorManagement.ts +0 -127
- package/src/CullingFixtures.ts +0 -280
- package/src/DecalGeometry.ts +0 -26
- package/src/DepthPass.ts +0 -110
- package/src/EnvironmentBackgroundPass.ts +0 -194
- package/src/EnvironmentBackgroundResources.ts +0 -309
- package/src/EnvironmentLighting.ts +0 -96
- package/src/EnvironmentMapResources.ts +0 -1026
- package/src/EnvironmentPipeline.ts +0 -69
- package/src/EnvironmentPlatform.ts +0 -1306
- package/src/EnvironmentPreset.ts +0 -155
- package/src/Exposure.ts +0 -66
- package/src/ExternalParityRenderPreset.ts +0 -725
- package/src/ForwardPass.ts +0 -1663
- package/src/FrameVisualMetrics.ts +0 -301
- package/src/Geometry.ts +0 -461
- package/src/GeometryPrimitives.ts +0 -2
- package/src/HDRRenderPipeline.ts +0 -94
- package/src/IBL.ts +0 -86
- package/src/IndexBuffer.ts +0 -57
- package/src/InstancedPBRMaterial.ts +0 -186
- package/src/InstancedUnlitMaterial.ts +0 -60
- package/src/Instancing.ts +0 -19
- package/src/LightCollector.ts +0 -82
- package/src/LightUniforms.ts +0 -47
- package/src/LightingDebug.ts +0 -80
- package/src/LightingDefaults.ts +0 -79
- package/src/LightingRig.ts +0 -301
- package/src/LineGeometry.ts +0 -2
- package/src/Material.ts +0 -209
- package/src/MaterialBinding.ts +0 -131
- package/src/MaterialInstance.ts +0 -59
- package/src/MaterialPresets.ts +0 -272
- package/src/MorphTarget.ts +0 -123
- package/src/MorphTargetPlan.ts +0 -178
- package/src/MorphUnlitMaterial.ts +0 -60
- package/src/NormalMappedPBRMaterial.ts +0 -188
- package/src/OceanFixtures.ts +0 -318
- package/src/PBRLightingDefaults.ts +0 -12
- package/src/PBRMaterial.ts +0 -442
- package/src/PMREM.ts +0 -53
- package/src/PbrReference.ts +0 -681
- package/src/PostProcessPass.ts +0 -2507
- package/src/ProceduralTextureFixtures.ts +0 -393
- package/src/ProductTurntableFixtures.ts +0 -815
- package/src/Raycaster.ts +0 -21
- package/src/ReflectionProbe.ts +0 -13
- package/src/ReflectionSurfaces.ts +0 -219
- package/src/RenderBackend.ts +0 -43
- package/src/RenderDebugViews.ts +0 -138
- package/src/RenderDevice.ts +0 -836
- package/src/RenderGraph.ts +0 -194
- package/src/RenderPass.ts +0 -27
- package/src/RenderPipeline.ts +0 -101
- package/src/RenderQueue.ts +0 -12
- package/src/RenderState.ts +0 -12
- package/src/Renderer.ts +0 -2626
- package/src/RendererDebugOverlay.ts +0 -80
- package/src/RendererFeatureGates.ts +0 -150
- package/src/RendererPostprocessPlan.ts +0 -279
- package/src/RendererTiming.ts +0 -251
- package/src/RendererVisualPipelineReport.ts +0 -836
- package/src/ResourceLifecycle.ts +0 -21
- package/src/Sampler.ts +0 -37
- package/src/SceneOptimization.ts +0 -518
- package/src/ShaderChunks.ts +0 -393
- package/src/ShaderLibrary.ts +0 -2766
- package/src/ShaderModule.ts +0 -36
- package/src/ShaderPreprocessor.ts +0 -260
- package/src/ShaderReflection.ts +0 -201
- package/src/ShadowMap.ts +0 -237
- package/src/ShadowPass.ts +0 -198
- package/src/ShadowProjection.ts +0 -115
- package/src/SkinnedLitMaterial.ts +0 -397
- package/src/SkinnedUnlitMaterial.ts +0 -63
- package/src/SkinningBounds.ts +0 -131
- package/src/SpaceEnvironmentFixtures.ts +0 -200
- package/src/SpriteGeometry.ts +0 -21
- package/src/StereoCameraRig.ts +0 -127
- package/src/StereoEffects.ts +0 -274
- package/src/TerrainFixtures.ts +0 -180
- package/src/Texture.ts +0 -307
- package/src/TextureBinding.ts +0 -91
- package/src/TexturedPBRMaterial.ts +0 -1112
- package/src/TexturedUnlitMaterial.ts +0 -67
- package/src/ToneMapping.ts +0 -105
- package/src/UniformBinder.ts +0 -16
- package/src/UniformLayout.ts +0 -129
- package/src/UnlitMaterial.ts +0 -75
- package/src/VegetationFixtures.ts +0 -314
- package/src/VertexBuffer.ts +0 -120
- package/src/VertexFormat.ts +0 -171
- package/src/VoxelWorldFixtures.ts +0 -280
- package/src/WeatherFixtures.ts +0 -223
- package/src/WebGL2Device.ts +0 -2280
- package/src/WebGL2StateCache.ts +0 -330
- package/src/WebGPUDevice.ts +0 -2877
- package/src/WebGPURenderToTextureProof.ts +0 -139
- package/src/advanced-runtime/AdvancedRenderer.ts +0 -73
- package/src/advanced-runtime/index.ts +0 -9
- package/src/animation/AnimationMaterialStyle.ts +0 -32
- package/src/animation/AnimationRenderPreset.ts +0 -45
- package/src/animation/AnimationToonMaterial.ts +0 -387
- package/src/animation/AnimationVisualQuality.ts +0 -71
- package/src/animation/applyAnimationRenderPreset.ts +0 -180
- package/src/animation/index.ts +0 -5
- package/src/cinematic/BloomPass.ts +0 -26
- package/src/cinematic/CinematicDepthComposition.ts +0 -30
- package/src/cinematic/CinematicEvidence.ts +0 -123
- package/src/cinematic/CinematicLightingRig.ts +0 -144
- package/src/cinematic/CinematicMaterialPresets.ts +0 -130
- package/src/cinematic/CinematicPostProcess.ts +0 -83
- package/src/cinematic/DepthHazePass.ts +0 -30
- package/src/cinematic/EmissivePracticalLightSystem.ts +0 -45
- package/src/cinematic/FilmGrainPass.ts +0 -24
- package/src/cinematic/FogVolumeSystem.ts +0 -30
- package/src/cinematic/GlowCardSystem.ts +0 -44
- package/src/cinematic/RainParticleSystem.ts +0 -151
- package/src/cinematic/VignettePass.ts +0 -25
- package/src/cinematic/WetReflectionApproximation.ts +0 -27
- package/src/cinematic/index.ts +0 -14
- package/src/effects/CollisionModule.ts +0 -64
- package/src/effects/ColorModule.ts +0 -60
- package/src/effects/ForceModule.ts +0 -25
- package/src/effects/GPUParticleBackend.ts +0 -569
- package/src/effects/Particle.ts +0 -108
- package/src/effects/ParticleDiagnostics.ts +0 -224
- package/src/effects/ParticleEffectPresets.ts +0 -147
- package/src/effects/ParticleEmitter.ts +0 -326
- package/src/effects/ParticleModule.ts +0 -26
- package/src/effects/ParticleRenderPass.ts +0 -117
- package/src/effects/ParticleRenderer.ts +0 -132
- package/src/effects/ParticleSystem.ts +0 -333
- package/src/effects/SizeModule.ts +0 -56
- package/src/effects/TrailModule.ts +0 -72
- package/src/effects/VelocityModule.ts +0 -75
- package/src/effects/index.ts +0 -15
- package/src/index.ts +0 -925
- package/src/materials/AlphaSorting.ts +0 -30
- package/src/materials/MaterialExtensions.ts +0 -42
- package/src/materials/PhysicalMaterial.ts +0 -133
- package/src/materials/TransmissionPass.ts +0 -51
- package/src/performance/BVH.ts +0 -18
- package/src/performance/Batcher.ts +0 -2
- package/src/performance/FrustumCuller.ts +0 -9
- package/src/performance/LOD.ts +0 -20
- package/src/performance/Octree.ts +0 -10
- package/src/performance/RenderItemSorting.ts +0 -170
- package/src/performance/RendererStats.ts +0 -43
- package/src/performance/ResourceBudget.ts +0 -44
- package/src/postprocess/BloomPass.ts +0 -28
- package/src/postprocess/CinematicDiagnostics.ts +0 -642
- package/src/postprocess/ColorGradingPass.ts +0 -24
- package/src/postprocess/DepthOfFieldPass.ts +0 -12
- package/src/postprocess/EffectComposer.ts +0 -349
- package/src/postprocess/SSAOPass.ts +0 -20
- package/src/postprocess/index.ts +0 -34
- package/src/production-runtime/AnimationControlsPipeline.ts +0 -77
- package/src/production-runtime/PBRHDRPipeline.ts +0 -381
- package/src/production-runtime/ProductionEffectsPipeline.ts +0 -85
- package/src/production-runtime/ProductionRendererTypes.ts +0 -136
- package/src/production-runtime/ProductionRuntimeRenderer.ts +0 -172
- package/src/production-runtime/ProductionWebGL2Renderer.ts +0 -313
- package/src/production-runtime/ProductionWebGPURenderer.ts +0 -396
- package/src/production-runtime/TransmissionBackdropCapture.ts +0 -130
- package/src/production-runtime/animation/MorphTargetRenderer.ts +0 -2
- package/src/production-runtime/animation/SkinningRenderer.ts +0 -2
- package/src/production-runtime/backends/RendererBackend.ts +0 -17
- package/src/production-runtime/backends/WebGL2RendererBackend.ts +0 -30
- package/src/production-runtime/backends/WebGPURendererBackend.ts +0 -24
- package/src/production-runtime/backends/webgl2/WebGL2Buffer.ts +0 -2
- package/src/production-runtime/backends/webgl2/WebGL2Capabilities.ts +0 -2
- package/src/production-runtime/backends/webgl2/WebGL2RenderTarget.ts +0 -2
- package/src/production-runtime/backends/webgl2/WebGL2Shader.ts +0 -2
- package/src/production-runtime/backends/webgl2/WebGL2StateCache.ts +0 -1
- package/src/production-runtime/backends/webgl2/WebGL2Texture.ts +0 -2
- package/src/production-runtime/backends/webgpu/WebGPUBuffer.ts +0 -2
- package/src/production-runtime/backends/webgpu/WebGPUCapabilities.ts +0 -2
- package/src/production-runtime/backends/webgpu/WebGPURenderTarget.ts +0 -2
- package/src/production-runtime/backends/webgpu/WebGPUShader.ts +0 -2
- package/src/production-runtime/backends/webgpu/WebGPUTexture.ts +0 -2
- package/src/production-runtime/color/ColorManagement.ts +0 -3
- package/src/production-runtime/color/ToneMapping.ts +0 -7
- package/src/production-runtime/diagnostics/FrameCapture.ts +0 -2
- package/src/production-runtime/diagnostics/GPUCapabilities.ts +0 -2
- package/src/production-runtime/diagnostics/RendererStats.ts +0 -2
- package/src/production-runtime/environment/EnvironmentMap.ts +0 -1
- package/src/production-runtime/environment/HDRLoader.ts +0 -57
- package/src/production-runtime/environment/PMREMGenerator.ts +0 -713
- package/src/production-runtime/framegraph/FrameGraph.ts +0 -18
- package/src/production-runtime/framegraph/RenderPass.ts +0 -15
- package/src/production-runtime/geometry/ProjectedDecalGeometry.ts +0 -439
- package/src/production-runtime/index.ts +0 -127
- package/src/production-runtime/lights/LightManager.ts +0 -7
- package/src/production-runtime/lights/ShadowMapRenderer.ts +0 -5
- package/src/production-runtime/materials/GLTFMaterialAdapter.ts +0 -6
- package/src/production-runtime/materials/GLTFPBRMaterialAdapter.ts +0 -2
- package/src/production-runtime/materials/MaterialCompiler.ts +0 -7
- package/src/production-runtime/materials/MaterialTextureBindings.ts +0 -5
- package/src/production-runtime/materials/PBRMaterial.ts +0 -2
- package/src/production-runtime/materials/PBRShaderFeatures.ts +0 -2
- package/src/production-runtime/passes/ContactShadowPass.ts +0 -184
- package/src/production-runtime/passes/DepthPrepass.ts +0 -7
- package/src/production-runtime/passes/OpaquePass.ts +0 -7
- package/src/production-runtime/passes/ShadowPass.ts +0 -7
- package/src/production-runtime/passes/SkyboxPass.ts +0 -7
- package/src/production-runtime/passes/ToneMappingPass.ts +0 -7
- package/src/production-runtime/passes/TransparentPass.ts +0 -7
- package/src/production-runtime/postprocess/BloomPass.ts +0 -51
- package/src/production-runtime/postprocess/ColorGradingPass.ts +0 -49
- package/src/production-runtime/postprocess/DOFPass.ts +0 -47
- package/src/production-runtime/postprocess/FXAAPass.ts +0 -53
- package/src/production-runtime/postprocess/ProductionEffectComposer.ts +0 -78
- package/src/production-runtime/postprocess/ProductionPostProcessTypes.ts +0 -174
- package/src/production-runtime/postprocess/SSAOPass.ts +0 -45
- package/src/production-runtime/resources/GPUBuffer.ts +0 -2
- package/src/production-runtime/resources/GPUTexture.ts +0 -2
- package/src/production-runtime/resources/RenderTarget.ts +0 -3
- package/src/production-runtime/resources/ResourceCache.ts +0 -7
- package/src/production-runtime/scene/Camera.ts +0 -1
- package/src/production-runtime/scene/Lights.ts +0 -2
- package/src/production-runtime/scene/RenderableMesh.ts +0 -2
- package/src/production-runtime/scene/RenderablePrimitive.ts +0 -1
- package/src/production-runtime/scene/RenderableScene.ts +0 -4
- package/src/production-runtime/shaders/ShaderProgramLibrary.ts +0 -7
- package/src/production-runtime/shaders/chunks/brdf.glsl +0 -2
- package/src/production-runtime/shaders/chunks/ibl.glsl +0 -3
- package/src/production-runtime/shaders/chunks/pbr.frag.glsl +0 -47
- package/src/production-runtime/shaders/chunks/pbr.vert.glsl +0 -8
- package/src/production-runtime/shaders/chunks/shadows.glsl +0 -2
- package/src/production-runtime/shaders/wgsl/pbr.wgsl +0 -3
- package/src/production-runtime/shaders/wgsl/postprocess.wgsl +0 -2
- package/src/production-runtime/shaders/wgsl/skybox.wgsl +0 -2
- package/src/shaders/depth.frag.glsl +0 -5
- package/src/shaders/depth.vert.glsl +0 -8
- package/src/shaders/pbr-direct.frag.glsl +0 -687
- package/src/shaders/pbr-direct.vert.glsl +0 -18
- package/src/shaders/unlit.frag.glsl +0 -18
- package/src/shaders/unlit.vert.glsl +0 -13
- package/src/shadows/CascadedShadowPipeline.ts +0 -53
- package/src/shadows/ContactShadows.ts +0 -106
- package/src/shadows/ShadowDebugViews.ts +0 -46
- package/src/threejs-compatibility/InstancingSystem.ts +0 -17
- package/src/threejs-compatibility/LightingSystem.ts +0 -22
- package/src/threejs-compatibility/MaterialSystem.ts +0 -9
- package/src/threejs-compatibility/RenderTargetSystem.ts +0 -35
- package/src/threejs-compatibility/RendererDiagnostics.ts +0 -61
- package/src/threejs-compatibility/SceneRenderer.ts +0 -34
- package/src/threejs-compatibility/ShadowSystem.ts +0 -19
- package/src/threejs-compatibility/TextureSystem.ts +0 -19
- package/src/threejs-compatibility/ThreeCompatRenderer.ts +0 -90
- package/src/threejs-compatibility/TransparencySystem.ts +0 -19
- package/src/threejs-compatibility/index.ts +0 -29
- package/src/threejs-compatibility/performance/BVH.ts +0 -14
- package/src/threejs-compatibility/performance/FrustumCulling.ts +0 -10
- package/src/threejs-compatibility/performance/Instancing.ts +0 -4
- package/src/threejs-compatibility/performance/LODSystem.ts +0 -16
- package/src/threejs-compatibility/performance/OcclusionCulling.ts +0 -6
- package/src/threejs-compatibility/performance/RaycastAcceleration.ts +0 -12
- package/src/threejs-compatibility/performance/RendererProfiler.ts +0 -19
- package/src/threejs-compatibility/performance/TextureStreaming.ts +0 -4
- package/src/threejs-compatibility/performance/index.ts +0 -12
- package/src/threejs-compatibility/postprocess/BloomPass.ts +0 -16
- package/src/threejs-compatibility/postprocess/ColorGradingPass.ts +0 -16
- package/src/threejs-compatibility/postprocess/DepthOfFieldPass.ts +0 -21
- package/src/threejs-compatibility/postprocess/EffectComposer.ts +0 -14
- package/src/threejs-compatibility/postprocess/FXAAPass.ts +0 -15
- package/src/threejs-compatibility/postprocess/MotionBlurPass.ts +0 -20
- package/src/threejs-compatibility/postprocess/OutlinePass.ts +0 -21
- package/src/threejs-compatibility/postprocess/PostProcessTypes.ts +0 -169
- package/src/threejs-compatibility/postprocess/RenderPass.ts +0 -9
- package/src/threejs-compatibility/postprocess/SMAAPass.ts +0 -15
- package/src/threejs-compatibility/postprocess/SSAOPass.ts +0 -21
- package/src/threejs-compatibility/postprocess/ShaderPass.ts +0 -7
- package/src/threejs-compatibility/postprocess/TAAPass.ts +0 -15
- package/src/threejs-compatibility/postprocess/VignettePass.ts +0 -16
- package/src/threejs-compatibility/postprocess/index.ts +0 -15
- package/src/threejs-compatibility/shaders/NodeMaterial.ts +0 -21
- package/src/threejs-compatibility/shaders/RawShaderMaterial.ts +0 -6
- package/src/threejs-compatibility/shaders/ShaderDiagnostics.ts +0 -17
- package/src/threejs-compatibility/shaders/ShaderMaterial.ts +0 -18
- package/src/threejs-compatibility/shaders/ThreeCompatShaderChunks.ts +0 -6
- package/src/threejs-compatibility/shaders/Uniforms.ts +0 -18
- package/src/threejs-compatibility/shaders/index.ts +0 -9
- package/src/threejs-compatibility/vfx/GPUPointCloud.ts +0 -7
- package/src/threejs-compatibility/vfx/LineRenderer.ts +0 -13
- package/src/threejs-compatibility/vfx/ParticleSystem.ts +0 -23
- package/src/threejs-compatibility/vfx/SpriteSystem.ts +0 -14
- package/src/threejs-compatibility/vfx/TrailRenderer.ts +0 -8
- package/src/threejs-compatibility/vfx/VFXDiagnostics.ts +0 -23
- package/src/threejs-compatibility/vfx/index.ts +0 -9
- package/src/threejs-example-parity/index.ts +0 -205
- package/src/webgpu/WebGPUBuffer.ts +0 -1
- package/src/webgpu/WebGPUCompute.ts +0 -2
- package/src/webgpu/WebGPUPipelineCache.ts +0 -15
- package/src/webgpu/WebGPUPostProcess.ts +0 -2
- package/src/webgpu/WebGPUTexture.ts +0 -2
- package/tsconfig.json +0 -26
- package/vitest.config.ts +0 -20
package/src/Geometry.ts
DELETED
|
@@ -1,461 +0,0 @@
|
|
|
1
|
-
import { IndexBuffer } from "./IndexBuffer";
|
|
2
|
-
import { type PrimitiveTopology } from "./RenderDevice";
|
|
3
|
-
import { VertexBuffer } from "./VertexBuffer";
|
|
4
|
-
import { VertexFormat } from "./VertexFormat";
|
|
5
|
-
|
|
6
|
-
export interface Bounds3 {
|
|
7
|
-
readonly min: readonly [number, number, number];
|
|
8
|
-
readonly max: readonly [number, number, number];
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface CylinderGeometryOptions {
|
|
12
|
-
readonly radius?: number;
|
|
13
|
-
readonly height?: number;
|
|
14
|
-
readonly segments?: number;
|
|
15
|
-
readonly capped?: boolean;
|
|
16
|
-
readonly textured?: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface CapsuleGeometryOptions {
|
|
20
|
-
readonly radius?: number;
|
|
21
|
-
readonly height?: number;
|
|
22
|
-
readonly segments?: number;
|
|
23
|
-
readonly rings?: number;
|
|
24
|
-
readonly textured?: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface WideLineSegment {
|
|
28
|
-
readonly start: readonly [number, number, number];
|
|
29
|
-
readonly end: readonly [number, number, number];
|
|
30
|
-
readonly width: number;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface UVSphereGeometryOptions {
|
|
34
|
-
readonly textured?: boolean;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export class Geometry {
|
|
38
|
-
constructor(
|
|
39
|
-
public readonly vertexBuffer: VertexBuffer,
|
|
40
|
-
public readonly indexBuffer: IndexBuffer | null = null,
|
|
41
|
-
public readonly topology: PrimitiveTopology = "triangles",
|
|
42
|
-
public readonly bounds: Bounds3 = computeBounds(vertexBuffer)
|
|
43
|
-
) {}
|
|
44
|
-
|
|
45
|
-
static triangle(): Geometry {
|
|
46
|
-
const vertices = new VertexBuffer(VertexFormat.P3, 3);
|
|
47
|
-
vertices.setAttribute(0, "position", [-0.5, -0.5, 0]);
|
|
48
|
-
vertices.setAttribute(1, "position", [0.5, -0.5, 0]);
|
|
49
|
-
vertices.setAttribute(2, "position", [0, 0.5, 0]);
|
|
50
|
-
return new Geometry(vertices, new IndexBuffer([0, 1, 2], 3));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
static lineSegments(positions: readonly (readonly [number, number, number])[]): Geometry {
|
|
54
|
-
if (positions.length === 0 || positions.length % 2 !== 0) {
|
|
55
|
-
throw new Error("Line segment geometry requires one or more pairs of positions");
|
|
56
|
-
}
|
|
57
|
-
const vertices = new VertexBuffer(VertexFormat.P3, positions.length);
|
|
58
|
-
positions.forEach((position, index) => {
|
|
59
|
-
if (position.length !== 3 || !Number.isFinite(position[0]) || !Number.isFinite(position[1]) || !Number.isFinite(position[2])) {
|
|
60
|
-
throw new Error(`Line segment position ${index} must be a finite vec3`);
|
|
61
|
-
}
|
|
62
|
-
vertices.setAttribute(index, "position", position);
|
|
63
|
-
});
|
|
64
|
-
return new Geometry(vertices, null, "lines");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
static wideLineSegments(segments: readonly WideLineSegment[]): Geometry {
|
|
68
|
-
if (segments.length === 0) {
|
|
69
|
-
throw new Error("Wide line geometry requires at least one segment");
|
|
70
|
-
}
|
|
71
|
-
const vertices = new VertexBuffer(VertexFormat.P3, segments.length * 4);
|
|
72
|
-
const indices: number[] = [];
|
|
73
|
-
segments.forEach((segment, segmentIndex) => {
|
|
74
|
-
validateWideLineSegment(segment, segmentIndex);
|
|
75
|
-
const [sx, sy, sz] = segment.start;
|
|
76
|
-
const [ex, ey, ez] = segment.end;
|
|
77
|
-
const dx = ex - sx;
|
|
78
|
-
const dy = ey - sy;
|
|
79
|
-
const dz = ez - sz;
|
|
80
|
-
const length = Math.hypot(dx, dy, dz);
|
|
81
|
-
const up = Math.abs(dz / length) > 0.92 ? [0, 1, 0] as const : [0, 0, 1] as const;
|
|
82
|
-
const nx = dy * up[2] - dz * up[1];
|
|
83
|
-
const ny = dz * up[0] - dx * up[2];
|
|
84
|
-
const nz = dx * up[1] - dy * up[0];
|
|
85
|
-
const normalLength = Math.hypot(nx, ny, nz);
|
|
86
|
-
const halfWidth = segment.width * 0.5;
|
|
87
|
-
const ox = nx / normalLength * halfWidth;
|
|
88
|
-
const oy = ny / normalLength * halfWidth;
|
|
89
|
-
const oz = nz / normalLength * halfWidth;
|
|
90
|
-
const base = segmentIndex * 4;
|
|
91
|
-
vertices.setAttribute(base, "position", [sx - ox, sy - oy, sz - oz]);
|
|
92
|
-
vertices.setAttribute(base + 1, "position", [sx + ox, sy + oy, sz + oz]);
|
|
93
|
-
vertices.setAttribute(base + 2, "position", [ex + ox, ey + oy, ez + oz]);
|
|
94
|
-
vertices.setAttribute(base + 3, "position", [ex - ox, ey - oy, ez - oz]);
|
|
95
|
-
indices.push(base, base + 1, base + 2, base, base + 2, base + 3);
|
|
96
|
-
});
|
|
97
|
-
return new Geometry(vertices, new IndexBuffer(indices, segments.length * 4), "triangles");
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
static points(positions: readonly (readonly [number, number, number])[]): Geometry {
|
|
101
|
-
if (positions.length === 0) {
|
|
102
|
-
throw new Error("Point geometry requires at least one position");
|
|
103
|
-
}
|
|
104
|
-
const vertices = new VertexBuffer(VertexFormat.P3, positions.length);
|
|
105
|
-
positions.forEach((position, index) => {
|
|
106
|
-
if (position.length !== 3 || !Number.isFinite(position[0]) || !Number.isFinite(position[1]) || !Number.isFinite(position[2])) {
|
|
107
|
-
throw new Error(`Point position ${index} must be a finite vec3`);
|
|
108
|
-
}
|
|
109
|
-
vertices.setAttribute(index, "position", position);
|
|
110
|
-
});
|
|
111
|
-
return new Geometry(vertices, null, "points");
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
static litTriangle(): Geometry {
|
|
115
|
-
const vertices = new VertexBuffer(VertexFormat.P3N3, 3);
|
|
116
|
-
vertices.setAttribute(0, "position", [-0.5, -0.5, 0]);
|
|
117
|
-
vertices.setAttribute(0, "normal", [0, 0, 1]);
|
|
118
|
-
vertices.setAttribute(1, "position", [0.5, -0.5, 0]);
|
|
119
|
-
vertices.setAttribute(1, "normal", [0, 0, 1]);
|
|
120
|
-
vertices.setAttribute(2, "position", [0, 0.5, 0]);
|
|
121
|
-
vertices.setAttribute(2, "normal", [0, 0, 1]);
|
|
122
|
-
return new Geometry(vertices, new IndexBuffer([0, 1, 2], 3));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
static litCube(size = 1): Geometry {
|
|
126
|
-
if (size <= 0) {
|
|
127
|
-
throw new Error("Lit cube size must be positive");
|
|
128
|
-
}
|
|
129
|
-
const half = size / 2;
|
|
130
|
-
const faces: readonly {
|
|
131
|
-
readonly normal: readonly [number, number, number];
|
|
132
|
-
readonly corners: readonly (readonly [number, number, number])[];
|
|
133
|
-
}[] = [
|
|
134
|
-
{ normal: [0, 0, 1], corners: [[-half, -half, half], [half, -half, half], [half, half, half], [-half, half, half]] },
|
|
135
|
-
{ normal: [0, 0, -1], corners: [[half, -half, -half], [-half, -half, -half], [-half, half, -half], [half, half, -half]] },
|
|
136
|
-
{ normal: [1, 0, 0], corners: [[half, -half, half], [half, -half, -half], [half, half, -half], [half, half, half]] },
|
|
137
|
-
{ normal: [-1, 0, 0], corners: [[-half, -half, -half], [-half, -half, half], [-half, half, half], [-half, half, -half]] },
|
|
138
|
-
{ normal: [0, 1, 0], corners: [[-half, half, half], [half, half, half], [half, half, -half], [-half, half, -half]] },
|
|
139
|
-
{ normal: [0, -1, 0], corners: [[-half, -half, -half], [half, -half, -half], [half, -half, half], [-half, -half, half]] }
|
|
140
|
-
];
|
|
141
|
-
const vertices = new VertexBuffer(VertexFormat.P3N3, faces.length * 4);
|
|
142
|
-
const indices: number[] = [];
|
|
143
|
-
faces.forEach((face, faceIndex) => {
|
|
144
|
-
const offset = faceIndex * 4;
|
|
145
|
-
face.corners.forEach((position, cornerIndex) => {
|
|
146
|
-
vertices.setAttribute(offset + cornerIndex, "position", position);
|
|
147
|
-
vertices.setAttribute(offset + cornerIndex, "normal", face.normal);
|
|
148
|
-
});
|
|
149
|
-
indices.push(offset, offset + 1, offset + 2, offset, offset + 2, offset + 3);
|
|
150
|
-
});
|
|
151
|
-
return new Geometry(vertices, new IndexBuffer(indices, faces.length * 4));
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
static texturedCube(size = 1): Geometry {
|
|
155
|
-
if (size <= 0) {
|
|
156
|
-
throw new Error("Textured cube size must be positive");
|
|
157
|
-
}
|
|
158
|
-
const half = size / 2;
|
|
159
|
-
const uv: readonly (readonly [number, number])[] = [[0, 0], [1, 0], [1, 1], [0, 1]];
|
|
160
|
-
const faces: readonly {
|
|
161
|
-
readonly normal: readonly [number, number, number];
|
|
162
|
-
readonly tangent: readonly [number, number, number, number];
|
|
163
|
-
readonly corners: readonly (readonly [number, number, number])[];
|
|
164
|
-
}[] = [
|
|
165
|
-
{ normal: [0, 0, 1], tangent: [1, 0, 0, 1], corners: [[-half, -half, half], [half, -half, half], [half, half, half], [-half, half, half]] },
|
|
166
|
-
{ normal: [0, 0, -1], tangent: [-1, 0, 0, 1], corners: [[half, -half, -half], [-half, -half, -half], [-half, half, -half], [half, half, -half]] },
|
|
167
|
-
{ normal: [1, 0, 0], tangent: [0, 0, -1, 1], corners: [[half, -half, half], [half, -half, -half], [half, half, -half], [half, half, half]] },
|
|
168
|
-
{ normal: [-1, 0, 0], tangent: [0, 0, 1, 1], corners: [[-half, -half, -half], [-half, -half, half], [-half, half, half], [-half, half, -half]] },
|
|
169
|
-
{ normal: [0, 1, 0], tangent: [1, 0, 0, 1], corners: [[-half, half, half], [half, half, half], [half, half, -half], [-half, half, -half]] },
|
|
170
|
-
{ normal: [0, -1, 0], tangent: [1, 0, 0, 1], corners: [[-half, -half, -half], [half, -half, -half], [half, -half, half], [-half, -half, half]] }
|
|
171
|
-
];
|
|
172
|
-
const vertices = new VertexBuffer(VertexFormat.P3N3T4T2, faces.length * 4);
|
|
173
|
-
const indices: number[] = [];
|
|
174
|
-
faces.forEach((face, faceIndex) => {
|
|
175
|
-
const offset = faceIndex * 4;
|
|
176
|
-
face.corners.forEach((position, cornerIndex) => {
|
|
177
|
-
vertices.setAttribute(offset + cornerIndex, "position", position);
|
|
178
|
-
vertices.setAttribute(offset + cornerIndex, "normal", face.normal);
|
|
179
|
-
vertices.setAttribute(offset + cornerIndex, "tangent", face.tangent);
|
|
180
|
-
vertices.setAttribute(offset + cornerIndex, "uv", uv[cornerIndex]!);
|
|
181
|
-
});
|
|
182
|
-
indices.push(offset, offset + 1, offset + 2, offset, offset + 2, offset + 3);
|
|
183
|
-
});
|
|
184
|
-
return new Geometry(vertices, new IndexBuffer(indices, faces.length * 4));
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
static uvSphere(radius = 0.5, segments = 48, rings = 24, options: UVSphereGeometryOptions = {}): Geometry {
|
|
188
|
-
if (radius <= 0) {
|
|
189
|
-
throw new Error("Sphere radius must be positive");
|
|
190
|
-
}
|
|
191
|
-
if (!Number.isInteger(segments) || !Number.isInteger(rings) || segments < 3 || rings < 2) {
|
|
192
|
-
throw new Error("Sphere segments and rings must be integers with segments >= 3 and rings >= 2");
|
|
193
|
-
}
|
|
194
|
-
const textured = options.textured === true;
|
|
195
|
-
const vertexCount = (rings + 1) * (segments + 1);
|
|
196
|
-
const vertices = new VertexBuffer(textured ? VertexFormat.P3N3T4T2 : VertexFormat.P3N3, vertexCount);
|
|
197
|
-
let vertex = 0;
|
|
198
|
-
for (let ring = 0; ring <= rings; ring += 1) {
|
|
199
|
-
const v = ring / rings;
|
|
200
|
-
const theta = v * Math.PI;
|
|
201
|
-
const sinTheta = Math.sin(theta);
|
|
202
|
-
const cosTheta = Math.cos(theta);
|
|
203
|
-
for (let segment = 0; segment <= segments; segment += 1) {
|
|
204
|
-
const u = segment / segments;
|
|
205
|
-
const phi = u * Math.PI * 2;
|
|
206
|
-
const nx = Math.cos(phi) * sinTheta;
|
|
207
|
-
const ny = cosTheta;
|
|
208
|
-
const nz = Math.sin(phi) * sinTheta;
|
|
209
|
-
vertices.setAttribute(vertex, "position", [nx * radius, ny * radius, nz * radius]);
|
|
210
|
-
vertices.setAttribute(vertex, "normal", [nx, ny, nz]);
|
|
211
|
-
if (textured) {
|
|
212
|
-
vertices.setAttribute(vertex, "tangent", [-Math.sin(phi), 0, Math.cos(phi), 1]);
|
|
213
|
-
vertices.setAttribute(vertex, "uv", [u, v]);
|
|
214
|
-
}
|
|
215
|
-
vertex += 1;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
const indices: number[] = [];
|
|
219
|
-
const stride = segments + 1;
|
|
220
|
-
for (let ring = 0; ring < rings; ring += 1) {
|
|
221
|
-
for (let segment = 0; segment < segments; segment += 1) {
|
|
222
|
-
const a = ring * stride + segment;
|
|
223
|
-
const b = a + stride;
|
|
224
|
-
indices.push(a, a + 1, b, a + 1, b + 1, b);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
return new Geometry(vertices, new IndexBuffer(indices, vertexCount));
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
static cylinder(options: CylinderGeometryOptions = {}): Geometry {
|
|
231
|
-
const radius = options.radius ?? 0.5;
|
|
232
|
-
const height = options.height ?? 1;
|
|
233
|
-
const segments = options.segments ?? 48;
|
|
234
|
-
const capped = options.capped ?? true;
|
|
235
|
-
validatePositiveFinite(radius, "Cylinder radius");
|
|
236
|
-
validatePositiveFinite(height, "Cylinder height");
|
|
237
|
-
validateSegments(segments, "Cylinder segments", 3);
|
|
238
|
-
const half = height / 2;
|
|
239
|
-
const textured = options.textured === true;
|
|
240
|
-
const vertices: GeneratedVertex[] = [];
|
|
241
|
-
const indices: number[] = [];
|
|
242
|
-
|
|
243
|
-
for (let segment = 0; segment <= segments; segment += 1) {
|
|
244
|
-
const u = segment / segments;
|
|
245
|
-
const angle = u * Math.PI * 2;
|
|
246
|
-
const cos = Math.cos(angle);
|
|
247
|
-
const sin = Math.sin(angle);
|
|
248
|
-
const normal: Vec3 = [cos, 0, sin];
|
|
249
|
-
const tangent: Vec4 = [-sin, 0, cos, 1];
|
|
250
|
-
vertices.push(makeGeneratedVertex([cos * radius, -half, sin * radius], normal, [u, 0], tangent, textured));
|
|
251
|
-
vertices.push(makeGeneratedVertex([cos * radius, half, sin * radius], normal, [u, 1], tangent, textured));
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
for (let segment = 0; segment < segments; segment += 1) {
|
|
255
|
-
const base = segment * 2;
|
|
256
|
-
indices.push(base, base + 3, base + 2, base, base + 1, base + 3);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (capped) {
|
|
260
|
-
const bottomCenter = vertices.length;
|
|
261
|
-
vertices.push(makeGeneratedVertex([0, -half, 0], [0, -1, 0], [0.5, 0.5], [1, 0, 0, 1], textured));
|
|
262
|
-
const bottomStart = vertices.length;
|
|
263
|
-
for (let segment = 0; segment <= segments; segment += 1) {
|
|
264
|
-
const u = segment / segments;
|
|
265
|
-
const angle = u * Math.PI * 2;
|
|
266
|
-
const cos = Math.cos(angle);
|
|
267
|
-
const sin = Math.sin(angle);
|
|
268
|
-
vertices.push(makeGeneratedVertex([cos * radius, -half, sin * radius], [0, -1, 0], [0.5 + cos * 0.5, 0.5 + sin * 0.5], [1, 0, 0, 1], textured));
|
|
269
|
-
}
|
|
270
|
-
for (let segment = 0; segment < segments; segment += 1) {
|
|
271
|
-
indices.push(bottomCenter, bottomStart + segment, bottomStart + segment + 1);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const topCenter = vertices.length;
|
|
275
|
-
vertices.push(makeGeneratedVertex([0, half, 0], [0, 1, 0], [0.5, 0.5], [1, 0, 0, 1], textured));
|
|
276
|
-
const topStart = vertices.length;
|
|
277
|
-
for (let segment = 0; segment <= segments; segment += 1) {
|
|
278
|
-
const u = segment / segments;
|
|
279
|
-
const angle = u * Math.PI * 2;
|
|
280
|
-
const cos = Math.cos(angle);
|
|
281
|
-
const sin = Math.sin(angle);
|
|
282
|
-
vertices.push(makeGeneratedVertex([cos * radius, half, sin * radius], [0, 1, 0], [0.5 + cos * 0.5, 0.5 + sin * 0.5], [1, 0, 0, 1], textured));
|
|
283
|
-
}
|
|
284
|
-
for (let segment = 0; segment < segments; segment += 1) {
|
|
285
|
-
indices.push(topCenter, topStart + segment + 1, topStart + segment);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return generatedGeometry(vertices, indices, textured);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
static capsule(options: CapsuleGeometryOptions = {}): Geometry {
|
|
293
|
-
const radius = options.radius ?? 0.5;
|
|
294
|
-
const height = options.height ?? 1.8;
|
|
295
|
-
const segments = options.segments ?? 48;
|
|
296
|
-
const rings = options.rings ?? 12;
|
|
297
|
-
validatePositiveFinite(radius, "Capsule radius");
|
|
298
|
-
validatePositiveFinite(height, "Capsule height");
|
|
299
|
-
if (height < radius * 2) {
|
|
300
|
-
throw new Error("Capsule height must be at least diameter");
|
|
301
|
-
}
|
|
302
|
-
validateSegments(segments, "Capsule segments", 3);
|
|
303
|
-
validateSegments(rings, "Capsule rings", 2);
|
|
304
|
-
const cylinderHalf = height / 2 - radius;
|
|
305
|
-
const textured = options.textured === true;
|
|
306
|
-
const vertices: GeneratedVertex[] = [];
|
|
307
|
-
const indices: number[] = [];
|
|
308
|
-
const ringDescriptors: { readonly theta: number; readonly centerOffset: number }[] = [];
|
|
309
|
-
|
|
310
|
-
for (let ring = 0; ring <= rings; ring += 1) {
|
|
311
|
-
ringDescriptors.push({ theta: (ring / rings) * (Math.PI / 2), centerOffset: cylinderHalf });
|
|
312
|
-
}
|
|
313
|
-
for (let ring = 0; ring <= rings; ring += 1) {
|
|
314
|
-
ringDescriptors.push({ theta: Math.PI / 2 + (ring / rings) * (Math.PI / 2), centerOffset: -cylinderHalf });
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
ringDescriptors.forEach((descriptor, ringIndex) => {
|
|
318
|
-
const radial = Math.sin(descriptor.theta);
|
|
319
|
-
const yNormal = Math.cos(descriptor.theta);
|
|
320
|
-
const y = descriptor.centerOffset + yNormal * radius;
|
|
321
|
-
const v = ringIndex / Math.max(1, ringDescriptors.length - 1);
|
|
322
|
-
for (let segment = 0; segment <= segments; segment += 1) {
|
|
323
|
-
const u = segment / segments;
|
|
324
|
-
const angle = u * Math.PI * 2;
|
|
325
|
-
const cos = Math.cos(angle);
|
|
326
|
-
const sin = Math.sin(angle);
|
|
327
|
-
const normal: Vec3 = normalize3([cos * radial, yNormal, sin * radial]);
|
|
328
|
-
const tangent: Vec4 = [-sin, 0, cos, 1];
|
|
329
|
-
vertices.push(makeGeneratedVertex([cos * radial * radius, y, sin * radial * radius], normal, [u, v], tangent, textured));
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
const stride = segments + 1;
|
|
334
|
-
for (let ring = 0; ring < ringDescriptors.length - 1; ring += 1) {
|
|
335
|
-
for (let segment = 0; segment < segments; segment += 1) {
|
|
336
|
-
const a = ring * stride + segment;
|
|
337
|
-
const b = a + stride;
|
|
338
|
-
indices.push(a, a + 1, b, a + 1, b + 1, b);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return generatedGeometry(vertices, indices, textured);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
static cube(size = 1): Geometry {
|
|
346
|
-
if (size <= 0) {
|
|
347
|
-
throw new Error("Cube size must be positive");
|
|
348
|
-
}
|
|
349
|
-
const half = size / 2;
|
|
350
|
-
const positions: readonly (readonly [number, number, number])[] = [
|
|
351
|
-
[-half, -half, -half],
|
|
352
|
-
[half, -half, -half],
|
|
353
|
-
[half, half, -half],
|
|
354
|
-
[-half, half, -half],
|
|
355
|
-
[-half, -half, half],
|
|
356
|
-
[half, -half, half],
|
|
357
|
-
[half, half, half],
|
|
358
|
-
[-half, half, half]
|
|
359
|
-
];
|
|
360
|
-
const vertices = new VertexBuffer(VertexFormat.P3, positions.length);
|
|
361
|
-
positions.forEach((position, index) => vertices.setAttribute(index, "position", position));
|
|
362
|
-
const indices = [
|
|
363
|
-
0, 1, 2, 0, 2, 3,
|
|
364
|
-
4, 6, 5, 4, 7, 6,
|
|
365
|
-
0, 4, 5, 0, 5, 1,
|
|
366
|
-
1, 5, 6, 1, 6, 2,
|
|
367
|
-
2, 6, 7, 2, 7, 3,
|
|
368
|
-
3, 7, 4, 3, 4, 0
|
|
369
|
-
];
|
|
370
|
-
return new Geometry(vertices, new IndexBuffer(indices, positions.length));
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
dispose(): void {
|
|
374
|
-
this.vertexBuffer.dispose();
|
|
375
|
-
this.indexBuffer?.dispose();
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
function validateWideLineSegment(segment: WideLineSegment, index: number): void {
|
|
380
|
-
if (segment.start.length !== 3 || segment.end.length !== 3) {
|
|
381
|
-
throw new Error(`Wide line segment ${index} endpoints must be vec3 values`);
|
|
382
|
-
}
|
|
383
|
-
if ([...segment.start, ...segment.end].some((value) => !Number.isFinite(value))) {
|
|
384
|
-
throw new Error(`Wide line segment ${index} endpoints must be finite`);
|
|
385
|
-
}
|
|
386
|
-
if (!Number.isFinite(segment.width) || segment.width <= 0) {
|
|
387
|
-
throw new Error(`Wide line segment ${index} width must be finite and positive`);
|
|
388
|
-
}
|
|
389
|
-
if (Math.hypot(
|
|
390
|
-
segment.end[0] - segment.start[0],
|
|
391
|
-
segment.end[1] - segment.start[1],
|
|
392
|
-
segment.end[2] - segment.start[2]
|
|
393
|
-
) <= 1e-8) {
|
|
394
|
-
throw new Error(`Wide line segment ${index} must have non-zero length`);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
export function computeBounds(vertexBuffer: VertexBuffer): Bounds3 {
|
|
399
|
-
if (!vertexBuffer.format.hasAttribute("position")) {
|
|
400
|
-
throw new Error("Cannot compute geometry bounds without position attribute");
|
|
401
|
-
}
|
|
402
|
-
const min: [number, number, number] = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY];
|
|
403
|
-
const max: [number, number, number] = [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY];
|
|
404
|
-
for (let i = 0; i < vertexBuffer.vertexCount; i += 1) {
|
|
405
|
-
const [x = 0, y = 0, z = 0] = vertexBuffer.getAttribute(i, "position");
|
|
406
|
-
min[0] = Math.min(min[0], x);
|
|
407
|
-
min[1] = Math.min(min[1], y);
|
|
408
|
-
min[2] = Math.min(min[2], z);
|
|
409
|
-
max[0] = Math.max(max[0], x);
|
|
410
|
-
max[1] = Math.max(max[1], y);
|
|
411
|
-
max[2] = Math.max(max[2], z);
|
|
412
|
-
}
|
|
413
|
-
return { min, max };
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
type Vec2 = readonly [number, number];
|
|
417
|
-
type Vec3 = readonly [number, number, number];
|
|
418
|
-
type Vec4 = readonly [number, number, number, number];
|
|
419
|
-
|
|
420
|
-
interface GeneratedVertex {
|
|
421
|
-
readonly position: Vec3;
|
|
422
|
-
readonly normal: Vec3;
|
|
423
|
-
readonly uv?: Vec2;
|
|
424
|
-
readonly tangent?: Vec4;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
function generatedGeometry(vertices: readonly GeneratedVertex[], indices: readonly number[], textured: boolean): Geometry {
|
|
428
|
-
const format = textured ? VertexFormat.P3N3T4T2 : VertexFormat.P3N3;
|
|
429
|
-
const buffer = new VertexBuffer(format, vertices.length);
|
|
430
|
-
vertices.forEach((vertex, index) => {
|
|
431
|
-
buffer.setAttribute(index, "position", vertex.position);
|
|
432
|
-
buffer.setAttribute(index, "normal", vertex.normal);
|
|
433
|
-
if (textured) {
|
|
434
|
-
buffer.setAttribute(index, "tangent", vertex.tangent ?? [1, 0, 0, 1]);
|
|
435
|
-
buffer.setAttribute(index, "uv", vertex.uv ?? [0, 0]);
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
return new Geometry(buffer, new IndexBuffer([...indices], vertices.length));
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
function makeGeneratedVertex(position: Vec3, normal: Vec3, uv: Vec2, tangent: Vec4, textured: boolean): GeneratedVertex {
|
|
442
|
-
return textured ? { position, normal, uv, tangent } : { position, normal };
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
function validatePositiveFinite(value: number, label: string): void {
|
|
446
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
447
|
-
throw new Error(`${label} must be finite and positive`);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
function validateSegments(value: number, label: string, minimum: number): void {
|
|
452
|
-
if (!Number.isInteger(value) || value < minimum) {
|
|
453
|
-
throw new Error(`${label} must be an integer >= ${minimum}`);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
function normalize3(value: Vec3): Vec3 {
|
|
458
|
-
const length = Math.hypot(value[0], value[1], value[2]);
|
|
459
|
-
if (length <= 1e-8) return [0, 1, 0];
|
|
460
|
-
return [value[0] / length, value[1] / length, value[2] / length];
|
|
461
|
-
}
|
package/src/HDRRenderPipeline.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { RenderDeviceError, type RenderDevice, type RenderTarget } from "./RenderDevice";
|
|
2
|
-
import { ToneMappingPass, type BloomOptions } from "./PostProcessPass";
|
|
3
|
-
import { createExternalParityColorManagementPolicy, type A3DColorManagementPolicy } from "./ColorManagement";
|
|
4
|
-
import { createExternalParityToneMappingPolicy, type ExternalParityToneMappingIntent, type ExternalParityToneMappingPolicy } from "./ToneMapping";
|
|
5
|
-
|
|
6
|
-
export type ExternalParityHdrRenderTargetFormat = "rgba16f" | "rgba32f" | "rgba8";
|
|
7
|
-
export type ExternalParityHdrPipelineMode = "hdr" | "ldr-fallback";
|
|
8
|
-
|
|
9
|
-
export interface ExternalParityHdrPipelineDescriptor {
|
|
10
|
-
readonly width: number;
|
|
11
|
-
readonly height: number;
|
|
12
|
-
readonly intent?: ExternalParityToneMappingIntent;
|
|
13
|
-
readonly preferredFormat?: Extract<ExternalParityHdrRenderTargetFormat, "rgba16f" | "rgba32f">;
|
|
14
|
-
readonly allowLdrFallback?: boolean;
|
|
15
|
-
readonly bloom?: BloomOptions | false;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface ExternalParityHdrPipeline {
|
|
19
|
-
readonly mode: ExternalParityHdrPipelineMode;
|
|
20
|
-
readonly format: ExternalParityHdrRenderTargetFormat;
|
|
21
|
-
readonly colorTarget: RenderTarget;
|
|
22
|
-
readonly displayTarget: RenderTarget;
|
|
23
|
-
readonly colorManagement: A3DColorManagementPolicy;
|
|
24
|
-
readonly toneMapping: ExternalParityToneMappingPolicy;
|
|
25
|
-
readonly bloom: BloomOptions | false;
|
|
26
|
-
readonly warnings: readonly string[];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function createExternalParityHdrPipeline(device: RenderDevice, descriptor: ExternalParityHdrPipelineDescriptor): ExternalParityHdrPipeline {
|
|
30
|
-
validateDimensions(descriptor.width, descriptor.height);
|
|
31
|
-
const colorManagement = createExternalParityColorManagementPolicy({
|
|
32
|
-
outputColorSpace: "srgb",
|
|
33
|
-
allowLdrFallback: descriptor.allowLdrFallback ?? true
|
|
34
|
-
});
|
|
35
|
-
const toneMapping = createExternalParityToneMappingPolicy(descriptor.intent ?? "product-catalog");
|
|
36
|
-
const capabilities = new Set(device.info.capabilities ?? []);
|
|
37
|
-
const supportsHdr = capabilities.has("hdr-render-targets") || device.kind === "mock";
|
|
38
|
-
const preferredFormat = descriptor.preferredFormat ?? "rgba16f";
|
|
39
|
-
const allowLdrFallback = descriptor.allowLdrFallback ?? true;
|
|
40
|
-
const format: ExternalParityHdrRenderTargetFormat = supportsHdr ? preferredFormat : "rgba8";
|
|
41
|
-
if (!supportsHdr && !allowLdrFallback) {
|
|
42
|
-
throw new RenderDeviceError("ExternalParity HDR pipeline requires HDR render targets or an explicit LDR fallback.", "EXTERNAL_PARITY_HDR_UNSUPPORTED", {
|
|
43
|
-
backend: device.kind
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const colorTarget = device.createRenderTarget({
|
|
48
|
-
width: descriptor.width,
|
|
49
|
-
height: descriptor.height,
|
|
50
|
-
label: "external-parity-hdr-color",
|
|
51
|
-
format,
|
|
52
|
-
depth: "texture"
|
|
53
|
-
});
|
|
54
|
-
const displayTarget = device.createRenderTarget({
|
|
55
|
-
width: descriptor.width,
|
|
56
|
-
height: descriptor.height,
|
|
57
|
-
label: "external-parity-display-color",
|
|
58
|
-
format: "rgba8"
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
mode: supportsHdr ? "hdr" : "ldr-fallback",
|
|
63
|
-
format,
|
|
64
|
-
colorTarget,
|
|
65
|
-
displayTarget,
|
|
66
|
-
colorManagement,
|
|
67
|
-
toneMapping,
|
|
68
|
-
bloom: descriptor.bloom ?? false,
|
|
69
|
-
warnings: supportsHdr
|
|
70
|
-
? []
|
|
71
|
-
: ["Backend does not expose HDR render targets; using LDR fallback with linear lighting policy and explicit tone mapping."]
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function executeExternalParityToneMapPass(device: RenderDevice, pipeline: ExternalParityHdrPipeline): ToneMappingPass {
|
|
76
|
-
const pass = new ToneMappingPass({
|
|
77
|
-
source: pipeline.colorTarget,
|
|
78
|
-
target: pipeline.displayTarget,
|
|
79
|
-
exposure: pipeline.toneMapping.exposure,
|
|
80
|
-
whitePoint: pipeline.toneMapping.whitePoint,
|
|
81
|
-
gamma: pipeline.toneMapping.gamma,
|
|
82
|
-
operator: pipeline.toneMapping.operator,
|
|
83
|
-
inputColorSpace: pipeline.toneMapping.inputColorSpace,
|
|
84
|
-
outputColorSpace: pipeline.toneMapping.outputColorSpace
|
|
85
|
-
});
|
|
86
|
-
pass.execute({ device, width: pipeline.colorTarget.width, height: pipeline.colorTarget.height });
|
|
87
|
-
return pass;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function validateDimensions(width: number, height: number): void {
|
|
91
|
-
if (!Number.isInteger(width) || !Number.isInteger(height) || width <= 0 || height <= 0) {
|
|
92
|
-
throw new Error("ExternalParity HDR pipeline dimensions must be positive integers.");
|
|
93
|
-
}
|
|
94
|
-
}
|
package/src/IBL.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createEnvironmentMapResourceSet,
|
|
3
|
-
type EnvironmentMapResourceSet,
|
|
4
|
-
type LinearHdrEnvironmentMapSource
|
|
5
|
-
} from "./EnvironmentMapResources";
|
|
6
|
-
import { createExternalParityGeneratedHdrEnvironmentMapSource, type ExternalParityEnvironmentPreset } from "./ExternalParityRenderPreset";
|
|
7
|
-
import { createExternalParityBrdfLut, type ExternalParityBrdfLut } from "./BRDFLut";
|
|
8
|
-
import { createExternalParityPmrem, type ExternalParityPmrem } from "./PMREM";
|
|
9
|
-
|
|
10
|
-
export interface ExternalParityIblOptions {
|
|
11
|
-
readonly preset: ExternalParityEnvironmentPreset;
|
|
12
|
-
readonly width?: number;
|
|
13
|
-
readonly height?: number;
|
|
14
|
-
readonly rotation?: number;
|
|
15
|
-
readonly intensity?: number;
|
|
16
|
-
readonly backgroundIntensity?: number;
|
|
17
|
-
readonly sourceQuality?: "bootstrap-generated" | "licensed-hdr";
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface ExternalParityIblResourceSet {
|
|
21
|
-
readonly preset: ExternalParityEnvironmentPreset;
|
|
22
|
-
readonly source: LinearHdrEnvironmentMapSource;
|
|
23
|
-
readonly resources: EnvironmentMapResourceSet;
|
|
24
|
-
readonly pmrem: ExternalParityPmrem;
|
|
25
|
-
readonly brdfLut: ExternalParityBrdfLut;
|
|
26
|
-
readonly rotation: number;
|
|
27
|
-
readonly intensity: number;
|
|
28
|
-
readonly backgroundIntensity: number;
|
|
29
|
-
readonly diagnostics: {
|
|
30
|
-
readonly sourceQuality: "bootstrap-generated" | "licensed-hdr";
|
|
31
|
-
readonly notFlagshipProof: boolean;
|
|
32
|
-
readonly hdrSource: boolean;
|
|
33
|
-
readonly maxLinearValue: number;
|
|
34
|
-
readonly diffuseIrradiance: boolean;
|
|
35
|
-
readonly specularPrefilter: boolean;
|
|
36
|
-
readonly brdfLut: boolean;
|
|
37
|
-
readonly environmentRotation: boolean;
|
|
38
|
-
readonly environmentIntensity: boolean;
|
|
39
|
-
readonly backgroundSeparation: boolean;
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function createExternalParityIblResources(options: ExternalParityIblOptions): ExternalParityIblResourceSet {
|
|
44
|
-
const source = createExternalParityGeneratedHdrEnvironmentMapSource(options.preset, options.width ?? 128, options.height ?? 64);
|
|
45
|
-
const resources = createEnvironmentMapResourceSet({ ...source, encoding: "linear-hdr" }, {
|
|
46
|
-
outputColorSpace: "srgb",
|
|
47
|
-
exposure: 1,
|
|
48
|
-
toneMapping: "reinhard",
|
|
49
|
-
specularLevels: 6,
|
|
50
|
-
specularBlurRadius: 3,
|
|
51
|
-
irradianceWidth: 16,
|
|
52
|
-
irradianceHeight: 8,
|
|
53
|
-
irradianceBlurRadius: 8,
|
|
54
|
-
brdfLutSize: 64
|
|
55
|
-
});
|
|
56
|
-
const pmrem = createExternalParityPmrem(resources.base, {
|
|
57
|
-
levels: 6,
|
|
58
|
-
blurRadius: 3,
|
|
59
|
-
textureLabel: `external-parity-${options.preset}-pmrem`
|
|
60
|
-
});
|
|
61
|
-
const brdfLut = createExternalParityBrdfLut(64);
|
|
62
|
-
const sourceQuality = options.sourceQuality ?? "bootstrap-generated";
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
preset: options.preset,
|
|
66
|
-
source,
|
|
67
|
-
resources,
|
|
68
|
-
pmrem,
|
|
69
|
-
brdfLut,
|
|
70
|
-
rotation: options.rotation ?? 0,
|
|
71
|
-
intensity: options.intensity ?? 1,
|
|
72
|
-
backgroundIntensity: options.backgroundIntensity ?? 0.35,
|
|
73
|
-
diagnostics: {
|
|
74
|
-
sourceQuality,
|
|
75
|
-
notFlagshipProof: sourceQuality !== "licensed-hdr",
|
|
76
|
-
hdrSource: resources.diagnostics.hdrSource,
|
|
77
|
-
maxLinearValue: resources.diagnostics.maxLinearValue,
|
|
78
|
-
diffuseIrradiance: resources.diffuseIrradiance.width > 0 && resources.diffuseIrradiance.height > 0,
|
|
79
|
-
specularPrefilter: resources.specularMipLevels.length >= 4 && pmrem.diagnostics.directionalReflectionReady,
|
|
80
|
-
brdfLut: brdfLut.diagnostics.nonZeroPixels > 0 && brdfLut.diagnostics.monotonicRoughnessTrend,
|
|
81
|
-
environmentRotation: Number.isFinite(options.rotation ?? 0),
|
|
82
|
-
environmentIntensity: Number.isFinite(options.intensity ?? 1) && (options.intensity ?? 1) > 0,
|
|
83
|
-
backgroundSeparation: Number.isFinite(options.backgroundIntensity ?? 0.35) && (options.backgroundIntensity ?? 0.35) !== (options.intensity ?? 1)
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
}
|