├── .eslintrc.cjs ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ └── bug_report.md ├── .gitignore ├── .npmignore ├── .prettierrc ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── ROADMAP.md ├── dist ├── esm │ ├── core │ │ ├── DOM │ │ │ ├── DOMElement.mjs │ │ │ └── DOMFrustum.mjs │ │ ├── bindGroups │ │ │ ├── BindGroup.mjs │ │ │ └── TextureBindGroup.mjs │ │ ├── bindings │ │ │ ├── Binding.mjs │ │ │ ├── BufferBinding.mjs │ │ │ ├── SamplerBinding.mjs │ │ │ ├── TextureBinding.mjs │ │ │ ├── WritableBufferBinding.mjs │ │ │ ├── bufferElements │ │ │ │ ├── BufferArrayElement.mjs │ │ │ │ ├── BufferElement.mjs │ │ │ │ └── BufferInterleavedArrayElement.mjs │ │ │ └── utils.mjs │ │ ├── buffers │ │ │ ├── Buffer.mjs │ │ │ └── utils.mjs │ │ ├── cameras │ │ │ ├── Camera.mjs │ │ │ ├── OrthographicCamera.mjs │ │ │ └── PerspectiveCamera.mjs │ │ ├── computePasses │ │ │ └── ComputePass.mjs │ │ ├── geometries │ │ │ ├── Geometry.mjs │ │ │ ├── IndexedGeometry.mjs │ │ │ └── PlaneGeometry.mjs │ │ ├── lights │ │ │ ├── AmbientLight.mjs │ │ │ ├── DirectionalLight.mjs │ │ │ ├── Light.mjs │ │ │ ├── PointLight.mjs │ │ │ └── SpotLight.mjs │ │ ├── materials │ │ │ ├── ComputeMaterial.mjs │ │ │ ├── Material.mjs │ │ │ ├── RenderMaterial.mjs │ │ │ └── utils.mjs │ │ ├── meshes │ │ │ ├── FullscreenPlane.mjs │ │ │ ├── Mesh.mjs │ │ │ └── mixins │ │ │ │ ├── MeshBaseMixin.mjs │ │ │ │ └── ProjectedMeshBaseMixin.mjs │ │ ├── objects3D │ │ │ ├── Object3D.mjs │ │ │ └── ProjectedObject3D.mjs │ │ ├── pipelines │ │ │ ├── ComputePipelineEntry.mjs │ │ │ ├── PipelineEntry.mjs │ │ │ ├── PipelineManager.mjs │ │ │ └── RenderPipelineEntry.mjs │ │ ├── renderPasses │ │ │ ├── RenderBundle.mjs │ │ │ ├── RenderPass.mjs │ │ │ ├── RenderTarget.mjs │ │ │ └── ShaderPass.mjs │ │ ├── renderers │ │ │ ├── GPUCameraRenderer.mjs │ │ │ ├── GPUDeviceManager.mjs │ │ │ ├── GPURenderer.mjs │ │ │ └── utils.mjs │ │ ├── samplers │ │ │ └── Sampler.mjs │ │ ├── scenes │ │ │ └── Scene.mjs │ │ ├── shaders │ │ │ ├── chunks │ │ │ │ ├── fragment │ │ │ │ │ ├── body │ │ │ │ │ │ ├── apply-directional-shadows.mjs │ │ │ │ │ │ ├── apply-point-shadows.mjs │ │ │ │ │ │ ├── apply-spot-shadows.mjs │ │ │ │ │ │ ├── apply-tone-mapping.mjs │ │ │ │ │ │ ├── declare-attributes-vars.mjs │ │ │ │ │ │ ├── declare-material-vars.mjs │ │ │ │ │ │ ├── get-IBL-GGX-Fresnel.mjs │ │ │ │ │ │ ├── get-IBL-indirect-irradiance.mjs │ │ │ │ │ │ ├── get-IBL-indirect-radiance.mjs │ │ │ │ │ │ ├── get-IBL-volume-refraction.mjs │ │ │ │ │ │ ├── get-PBR-shading.mjs │ │ │ │ │ │ ├── get-PCF-shadows.mjs │ │ │ │ │ │ ├── get-base-color.mjs │ │ │ │ │ │ ├── get-emissive-occlusion.mjs │ │ │ │ │ │ ├── get-lambert-shading.mjs │ │ │ │ │ │ ├── get-metallic-roughness.mjs │ │ │ │ │ │ ├── get-normal-tangent-bitangent.mjs │ │ │ │ │ │ ├── get-phong-shading.mjs │ │ │ │ │ │ ├── get-specular.mjs │ │ │ │ │ │ └── get-transmission-thickness.mjs │ │ │ │ │ └── head │ │ │ │ │ │ ├── RE-indirect-diffuse.mjs │ │ │ │ │ │ ├── RE-indirect-specular.mjs │ │ │ │ │ │ ├── get-IBL-GGX-Fresnel.mjs │ │ │ │ │ │ ├── get-IBL-indirect-irradiance.mjs │ │ │ │ │ │ ├── get-IBL-indirect-radiance.mjs │ │ │ │ │ │ ├── get-IBL-transmission.mjs │ │ │ │ │ │ ├── get-PBR-direct.mjs │ │ │ │ │ │ ├── get-PCF-base-shadow-contribution.mjs │ │ │ │ │ │ ├── get-PCF-directional-shadow-contribution.mjs │ │ │ │ │ │ ├── get-PCF-directional-shadows.mjs │ │ │ │ │ │ ├── get-PCF-point-shadow-contribution.mjs │ │ │ │ │ │ ├── get-PCF-point-shadows.mjs │ │ │ │ │ │ ├── get-PCF-spot-shadow-contribution.mjs │ │ │ │ │ │ ├── get-PCF-spot-shadows.mjs │ │ │ │ │ │ ├── get-fragment-input-struct.mjs │ │ │ │ │ │ ├── get-lambert-direct.mjs │ │ │ │ │ │ ├── get-lights-infos.mjs │ │ │ │ │ │ ├── get-phong-direct.mjs │ │ │ │ │ │ ├── get-uv-cover-helper.mjs │ │ │ │ │ │ └── get-vertex-to-UV-coords-helpers.mjs │ │ │ │ ├── shading │ │ │ │ │ ├── PBR-shading.mjs │ │ │ │ │ ├── lambert-shading.mjs │ │ │ │ │ └── phong-shading.mjs │ │ │ │ ├── utils │ │ │ │ │ ├── BRDF_GGX.mjs │ │ │ │ │ ├── common.mjs │ │ │ │ │ ├── constants.mjs │ │ │ │ │ ├── generate-TBN.mjs │ │ │ │ │ ├── hammersley-2D.mjs │ │ │ │ │ └── tone-mapping-utils.mjs │ │ │ │ └── vertex │ │ │ │ │ ├── body │ │ │ │ │ ├── declare-attributes-vars.mjs │ │ │ │ │ ├── get-morph-targets.mjs │ │ │ │ │ ├── get-vertex-output.mjs │ │ │ │ │ ├── get-vertex-skinned-position-normal.mjs │ │ │ │ │ └── get-vertex-transformed-position-normal.mjs │ │ │ │ │ └── head │ │ │ │ │ ├── get-normal-helpers.mjs │ │ │ │ │ ├── get-position-helpers.mjs │ │ │ │ │ ├── get-vertex-output-struct-content.mjs │ │ │ │ │ └── get-vertex-output-struct.mjs │ │ │ ├── default-material-helpers.mjs │ │ │ ├── full │ │ │ │ ├── compute │ │ │ │ │ ├── compute-BRDF-LUT.mjs │ │ │ │ │ ├── compute-diffuse-from-specular-cubemap.mjs │ │ │ │ │ └── compute-specular-cubemap-from-HDR.mjs │ │ │ │ ├── fragment │ │ │ │ │ ├── get-PBR-fragment-shader-code.mjs │ │ │ │ │ ├── get-default-fragment-code.mjs │ │ │ │ │ ├── get-default-normal-fragment-code.mjs │ │ │ │ │ ├── get-default-point-shadow-depth-fragment-code.mjs │ │ │ │ │ ├── get-default-shader-pass-fragment-code.mjs │ │ │ │ │ ├── get-fragment-shader-code.mjs │ │ │ │ │ ├── get-lambert-fragment-shader-code.mjs │ │ │ │ │ ├── get-phong-fragment-shader-code.mjs │ │ │ │ │ └── get-unlit-fragment-shader-code.mjs │ │ │ │ └── vertex │ │ │ │ │ ├── get-default-directional-shadow-depth-vertex-shader-code.mjs │ │ │ │ │ ├── get-default-point-shadow-depth-vertex-shader-code.mjs │ │ │ │ │ ├── get-default-projected-vertex-shader-code.mjs │ │ │ │ │ ├── get-default-spot-shadow-depth-vertex-shader-code.mjs │ │ │ │ │ ├── get-default-vertex-shader-code.mjs │ │ │ │ │ └── get-vertex-shader-code.mjs │ │ │ └── shader-chunks.mjs │ │ ├── shadows │ │ │ ├── DirectionalShadow.mjs │ │ │ ├── PointShadow.mjs │ │ │ ├── Shadow.mjs │ │ │ └── SpotShadow.mjs │ │ └── textures │ │ │ ├── MediaTexture.mjs │ │ │ ├── Texture.mjs │ │ │ └── utils.mjs │ ├── curtains │ │ ├── GPUCurtains.mjs │ │ ├── meshes │ │ │ ├── DOMMesh.mjs │ │ │ └── Plane.mjs │ │ ├── objects3D │ │ │ └── DOMObject3D.mjs │ │ ├── renderers │ │ │ └── GPUCurtainsRenderer.mjs │ │ └── textures │ │ │ └── DOMTexture.mjs │ ├── extras │ │ ├── animations │ │ │ ├── KeyframesAnimation.mjs │ │ │ └── TargetsAnimationsManager.mjs │ │ ├── buffers │ │ │ └── IndirectBuffer.mjs │ │ ├── controls │ │ │ └── OrbitControls.mjs │ │ ├── environmentMap │ │ │ └── EnvironmentMap.mjs │ │ ├── geometries │ │ │ ├── BoxGeometry.mjs │ │ │ └── SphereGeometry.mjs │ │ ├── gltf │ │ │ └── GLTFScenesManager.mjs │ │ ├── loaders │ │ │ ├── GLTFLoader.mjs │ │ │ └── HDRLoader.mjs │ │ ├── meshes │ │ │ ├── LitMesh.mjs │ │ │ └── PingPongPlane.mjs │ │ └── raycaster │ │ │ └── Raycaster.mjs │ ├── index.mjs │ ├── math │ │ ├── Box3.mjs │ │ ├── Mat3.mjs │ │ ├── Mat4.mjs │ │ ├── Quat.mjs │ │ ├── Vec2.mjs │ │ ├── Vec3.mjs │ │ └── color-utils.mjs │ └── utils │ │ ├── CacheManager.mjs │ │ ├── ResizeManager.mjs │ │ ├── ScrollManager.mjs │ │ ├── TasksQueueManager.mjs │ │ ├── utils.mjs │ │ └── webgpu-constants.mjs ├── gpu-curtains.umd.js ├── gpu-curtains.umd.min.js ├── gpu-curtains.umd.min.js.map └── types │ ├── core │ ├── DOM │ │ ├── DOMElement.d.ts │ │ └── DOMFrustum.d.ts │ ├── bindGroups │ │ ├── BindGroup.d.ts │ │ └── TextureBindGroup.d.ts │ ├── bindings │ │ ├── Binding.d.ts │ │ ├── BufferBinding.d.ts │ │ ├── SamplerBinding.d.ts │ │ ├── TextureBinding.d.ts │ │ ├── WritableBufferBinding.d.ts │ │ ├── bufferElements │ │ │ ├── BufferArrayElement.d.ts │ │ │ ├── BufferElement.d.ts │ │ │ └── BufferInterleavedArrayElement.d.ts │ │ └── utils.d.ts │ ├── buffers │ │ ├── Buffer.d.ts │ │ └── utils.d.ts │ ├── cameras │ │ ├── Camera.d.ts │ │ ├── OrthographicCamera.d.ts │ │ └── PerspectiveCamera.d.ts │ ├── computePasses │ │ └── ComputePass.d.ts │ ├── geometries │ │ ├── Geometry.d.ts │ │ ├── IndexedGeometry.d.ts │ │ └── PlaneGeometry.d.ts │ ├── lights │ │ ├── AmbientLight.d.ts │ │ ├── DirectionalLight.d.ts │ │ ├── Light.d.ts │ │ ├── PointLight.d.ts │ │ └── SpotLight.d.ts │ ├── materials │ │ ├── ComputeMaterial.d.ts │ │ ├── Material.d.ts │ │ ├── RenderMaterial.d.ts │ │ └── utils.d.ts │ ├── meshes │ │ ├── FullscreenPlane.d.ts │ │ ├── Mesh.d.ts │ │ └── mixins │ │ │ ├── MeshBaseMixin.d.ts │ │ │ └── ProjectedMeshBaseMixin.d.ts │ ├── objects3D │ │ ├── Object3D.d.ts │ │ └── ProjectedObject3D.d.ts │ ├── pipelines │ │ ├── ComputePipelineEntry.d.ts │ │ ├── PipelineEntry.d.ts │ │ ├── PipelineManager.d.ts │ │ └── RenderPipelineEntry.d.ts │ ├── renderPasses │ │ ├── RenderBundle.d.ts │ │ ├── RenderPass.d.ts │ │ ├── RenderTarget.d.ts │ │ └── ShaderPass.d.ts │ ├── renderers │ │ ├── GPUCameraRenderer.d.ts │ │ ├── GPUDeviceManager.d.ts │ │ ├── GPURenderer.d.ts │ │ └── utils.d.ts │ ├── samplers │ │ └── Sampler.d.ts │ ├── scenes │ │ └── Scene.d.ts │ ├── shaders │ │ ├── chunks │ │ │ ├── fragment │ │ │ │ ├── body │ │ │ │ │ ├── apply-directional-shadows.d.ts │ │ │ │ │ ├── apply-point-shadows.d.ts │ │ │ │ │ ├── apply-spot-shadows.d.ts │ │ │ │ │ ├── apply-tone-mapping.d.ts │ │ │ │ │ ├── declare-attributes-vars.d.ts │ │ │ │ │ ├── declare-material-vars.d.ts │ │ │ │ │ ├── get-IBL-GGX-Fresnel.d.ts │ │ │ │ │ ├── get-IBL-indirect-irradiance.d.ts │ │ │ │ │ ├── get-IBL-indirect-radiance.d.ts │ │ │ │ │ ├── get-IBL-volume-refraction.d.ts │ │ │ │ │ ├── get-PBR-shading.d.ts │ │ │ │ │ ├── get-PCF-shadows.d.ts │ │ │ │ │ ├── get-base-color.d.ts │ │ │ │ │ ├── get-emissive-occlusion.d.ts │ │ │ │ │ ├── get-lambert-shading.d.ts │ │ │ │ │ ├── get-metallic-roughness.d.ts │ │ │ │ │ ├── get-normal-tangent-bitangent.d.ts │ │ │ │ │ ├── get-pbr-shading.d.ts │ │ │ │ │ ├── get-phong-shading.d.ts │ │ │ │ │ ├── get-specular.d.ts │ │ │ │ │ └── get-transmission-thickness.d.ts │ │ │ │ └── head │ │ │ │ │ ├── RE-indirect-diffuse.d.ts │ │ │ │ │ ├── RE-indirect-specular.d.ts │ │ │ │ │ ├── get-IBL-GGX-Fresnel.d.ts │ │ │ │ │ ├── get-IBL-indirect-irradiance.d.ts │ │ │ │ │ ├── get-IBL-indirect-radiance.d.ts │ │ │ │ │ ├── get-IBL-transmission.d.ts │ │ │ │ │ ├── get-PBR-direct.d.ts │ │ │ │ │ ├── get-PCF-base-shadow-contribution.d.ts │ │ │ │ │ ├── get-PCF-directional-shadow-contribution.d.ts │ │ │ │ │ ├── get-PCF-directional-shadows.d.ts │ │ │ │ │ ├── get-PCF-point-shadow-contribution.d.ts │ │ │ │ │ ├── get-PCF-point-shadows.d.ts │ │ │ │ │ ├── get-PCF-spot-shadow-contribution.d.ts │ │ │ │ │ ├── get-PCF-spot-shadows.d.ts │ │ │ │ │ ├── get-fragment-input-struct.d.ts │ │ │ │ │ ├── get-lambert-direct.d.ts │ │ │ │ │ ├── get-lights-infos.d.ts │ │ │ │ │ ├── get-phong-direct.d.ts │ │ │ │ │ ├── get-uv-cover-helper.d.ts │ │ │ │ │ └── get-vertex-to-UV-coords-helpers.d.ts │ │ │ ├── shading │ │ │ │ ├── PBR-shading.d.ts │ │ │ │ ├── lambert-shading.d.ts │ │ │ │ ├── pbr-shading.d.ts │ │ │ │ └── phong-shading.d.ts │ │ │ ├── utils │ │ │ │ ├── BRDF_GGX.d.ts │ │ │ │ ├── common.d.ts │ │ │ │ ├── constants.d.ts │ │ │ │ ├── generate-TBN.d.ts │ │ │ │ ├── hammersley-2D.d.ts │ │ │ │ └── tone-mapping-utils.d.ts │ │ │ └── vertex │ │ │ │ ├── body │ │ │ │ ├── declare-attributes-vars.d.ts │ │ │ │ ├── get-morph-targets.d.ts │ │ │ │ ├── get-vertex-output.d.ts │ │ │ │ ├── get-vertex-skinned-position-normal.d.ts │ │ │ │ └── get-vertex-transformed-position-normal.d.ts │ │ │ │ └── head │ │ │ │ ├── get-normal-helpers.d.ts │ │ │ │ ├── get-position-helpers.d.ts │ │ │ │ ├── get-vertex-output-struct-content.d.ts │ │ │ │ └── get-vertex-output-struct.d.ts │ │ ├── default-material-helpers.d.ts │ │ ├── full │ │ │ ├── compute │ │ │ │ ├── compute-BRDF-LUT.d.ts │ │ │ │ ├── compute-diffuse-from-specular-cubemap.d.ts │ │ │ │ └── compute-specular-cubemap-from-HDR.d.ts │ │ │ ├── fragment │ │ │ │ ├── get-PBR-fragment-shader-code.d.ts │ │ │ │ ├── get-default-fragment-code.d.ts │ │ │ │ ├── get-default-normal-fragment-code.d.ts │ │ │ │ ├── get-default-point-shadow-depth-fragment-code.d.ts │ │ │ │ ├── get-default-shader-pass-fragment-code.d.ts │ │ │ │ ├── get-fragment-shader-code.d.ts │ │ │ │ ├── get-lambert-fragment-shader-code.d.ts │ │ │ │ ├── get-pbr-fragment-shader-code.d.ts │ │ │ │ ├── get-phong-fragment-shader-code.d.ts │ │ │ │ └── get-unlit-fragment-shader-code.d.ts │ │ │ └── vertex │ │ │ │ ├── get-default-directional-shadow-depth-vertex-shader-code.d.ts │ │ │ │ ├── get-default-point-shadow-depth-vertex-shader-code.d.ts │ │ │ │ ├── get-default-projected-vertex-shader-code.d.ts │ │ │ │ ├── get-default-spot-shadow-depth-vertex-shader-code.d.ts │ │ │ │ ├── get-default-vertex-shader-code.d.ts │ │ │ │ └── get-vertex-shader-code.d.ts │ │ └── shader-chunks.d.ts │ ├── shadows │ │ ├── DirectionalShadow.d.ts │ │ ├── PointShadow.d.ts │ │ ├── Shadow.d.ts │ │ └── SpotShadow.d.ts │ └── textures │ │ ├── MediaTexture.d.ts │ │ ├── Texture.d.ts │ │ └── utils.d.ts │ ├── curtains │ ├── GPUCurtains.d.ts │ ├── meshes │ │ ├── DOMMesh.d.ts │ │ └── Plane.d.ts │ ├── objects3D │ │ └── DOMObject3D.d.ts │ ├── renderers │ │ └── GPUCurtainsRenderer.d.ts │ └── textures │ │ └── DOMTexture.d.ts │ ├── extras │ ├── animations │ │ ├── KeyframesAnimation.d.ts │ │ └── TargetsAnimationsManager.d.ts │ ├── buffers │ │ └── IndirectBuffer.d.ts │ ├── controls │ │ └── OrbitControls.d.ts │ ├── environmentMap │ │ └── EnvironmentMap.d.ts │ ├── geometries │ │ ├── BoxGeometry.d.ts │ │ └── SphereGeometry.d.ts │ ├── gltf │ │ └── GLTFScenesManager.d.ts │ ├── loaders │ │ ├── GLTFLoader.d.ts │ │ └── HDRLoader.d.ts │ ├── meshes │ │ ├── LitMesh.d.ts │ │ └── PingPongPlane.d.ts │ └── raycaster │ │ └── Raycaster.d.ts │ ├── index.d.ts │ ├── math │ ├── Box3.d.ts │ ├── Mat3.d.ts │ ├── Mat4.d.ts │ ├── Quat.d.ts │ ├── Vec2.d.ts │ ├── Vec3.d.ts │ └── color-utils.d.ts │ ├── types │ ├── BindGroups.d.ts │ ├── Geometries.d.ts │ ├── Materials.d.ts │ ├── PipelineEntries.d.ts │ ├── Textures.d.ts │ ├── gltf │ │ ├── GLTF.d.ts │ │ ├── GLTFExtensions.d.ts │ │ └── GLTFScenesManager.d.ts │ └── index.d.ts │ └── utils │ ├── CacheManager.d.ts │ ├── ResizeManager.d.ts │ ├── ScrollManager.d.ts │ ├── TasksQueueManager.d.ts │ ├── utils.d.ts │ └── webgpu-constants.d.ts ├── docs ├── .nojekyll ├── assets │ ├── favicon.png │ ├── hierarchy.js │ ├── highlight.css │ ├── icons.js │ ├── icons.svg │ ├── main.js │ ├── navigation.js │ ├── search.js │ └── style.css ├── classes │ ├── core_DOM_DOMElement.DOMElement.html │ ├── core_DOM_DOMFrustum.DOMFrustum.html │ ├── core_bindGroups_BindGroup.BindGroup.html │ ├── core_bindGroups_TextureBindGroup.TextureBindGroup.html │ ├── core_bindings_Binding.Binding.html │ ├── core_bindings_BufferBinding.BufferBinding.html │ ├── core_bindings_SamplerBinding.SamplerBinding.html │ ├── core_bindings_TextureBinding.TextureBinding.html │ ├── core_bindings_WritableBufferBinding.WritableBufferBinding.html │ ├── core_bindings_bufferElements_BufferArrayElement.BufferArrayElement.html │ ├── core_bindings_bufferElements_BufferElement.BufferElement.html │ ├── core_bindings_bufferElements_BufferInterleavedArrayElement.BufferInterleavedArrayElement.html │ ├── core_buffers_Buffer.Buffer.html │ ├── core_cameras_Camera.Camera.html │ ├── core_cameras_OrthographicCamera.OrthographicCamera.html │ ├── core_cameras_PerspectiveCamera.PerspectiveCamera.html │ ├── core_computePasses_ComputePass.ComputePass.html │ ├── core_geometries_Geometry.Geometry.html │ ├── core_geometries_IndexedGeometry.IndexedGeometry.html │ ├── core_geometries_PlaneGeometry.PlaneGeometry.html │ ├── core_lights_AmbientLight.AmbientLight.html │ ├── core_lights_DirectionalLight.DirectionalLight.html │ ├── core_lights_Light.Light.html │ ├── core_lights_PointLight.PointLight.html │ ├── core_lights_SpotLight.SpotLight.html │ ├── core_materials_ComputeMaterial.ComputeMaterial.html │ ├── core_materials_Material.Material.html │ ├── core_materials_RenderMaterial.RenderMaterial.html │ ├── core_meshes_FullscreenPlane.FullscreenPlane.html │ ├── core_meshes_Mesh.Mesh.html │ ├── core_meshes_mixins_MeshBaseMixin.MeshBaseClass.html │ ├── core_meshes_mixins_ProjectedMeshBaseMixin.ProjectedMeshBaseClass.html │ ├── core_objects3D_Object3D.Object3D.html │ ├── core_objects3D_ProjectedObject3D.ProjectedObject3D.html │ ├── core_pipelines_ComputePipelineEntry.ComputePipelineEntry.html │ ├── core_pipelines_PipelineEntry.PipelineEntry.html │ ├── core_pipelines_PipelineManager.PipelineManager.html │ ├── core_pipelines_RenderPipelineEntry.RenderPipelineEntry.html │ ├── core_renderPasses_RenderBundle.RenderBundle.html │ ├── core_renderPasses_RenderPass.RenderPass.html │ ├── core_renderPasses_RenderTarget.RenderTarget.html │ ├── core_renderPasses_ShaderPass.ShaderPass.html │ ├── core_renderers_GPUCameraRenderer.GPUCameraRenderer.html │ ├── core_renderers_GPUDeviceManager.GPUDeviceManager.html │ ├── core_renderers_GPURenderer.GPURenderer.html │ ├── core_samplers_Sampler.Sampler.html │ ├── core_scenes_Scene.Scene.html │ ├── core_shadows_DirectionalShadow.DirectionalShadow.html │ ├── core_shadows_PointShadow.PointShadow.html │ ├── core_shadows_Shadow.Shadow.html │ ├── core_shadows_SpotShadow.SpotShadow.html │ ├── core_textures_MediaTexture.MediaTexture.html │ ├── core_textures_Texture.Texture.html │ ├── curtains_GPUCurtains.GPUCurtains.html │ ├── curtains_meshes_DOMMesh.DOMMesh.html │ ├── curtains_meshes_Plane.Plane.html │ ├── curtains_objects3D_DOMObject3D.DOMObject3D.html │ ├── curtains_renderers_GPUCurtainsRenderer.GPUCurtainsRenderer.html │ ├── curtains_textures_DOMTexture.DOMTexture.html │ ├── extras_animations_KeyframesAnimation.KeyframesAnimation.html │ ├── extras_animations_TargetsAnimationsManager.TargetsAnimationsManager.html │ ├── extras_buffers_IndirectBuffer.IndirectBuffer.html │ ├── extras_controls_OrbitControls.OrbitControls.html │ ├── extras_environmentMap_EnvironmentMap.EnvironmentMap.html │ ├── extras_geometries_BoxGeometry.BoxGeometry.html │ ├── extras_geometries_SphereGeometry.SphereGeometry.html │ ├── extras_gltf_GLTFScenesManager.GLTFScenesManager.html │ ├── extras_loaders_GLTFLoader.GLTFLoader.html │ ├── extras_loaders_HDRLoader.HDRLoader.html │ ├── extras_meshes_LitMesh.LitMesh.html │ ├── extras_meshes_PingPongPlane.PingPongPlane.html │ ├── extras_raycaster_Raycaster.Raycaster.html │ ├── math_Box3.Box3.html │ ├── math_Mat3.Mat3.html │ ├── math_Mat4.Mat4.html │ ├── math_Quat.Quat.html │ ├── math_Vec2.Vec2.html │ ├── math_Vec3.Vec3.html │ ├── utils_CacheManager.CacheManager.html │ ├── utils_ResizeManager.ResizeManager.html │ ├── utils_ScrollManager.ScrollManager.html │ └── utils_TasksQueueManager.TasksQueueManager.html ├── documents │ ├── Core_concepts.Bindings_and_bind_groups.html │ ├── Core_concepts.The_renderers,_scene_rendering_and_camera.html │ ├── Core_concepts.html │ ├── Getting_started.3D_engine_usage.html │ ├── Getting_started.DOM_syncing_usage.html │ └── Getting_started.html ├── functions │ ├── core_bindings_utils.getBindGroupLayoutBindingType.html │ ├── core_bindings_utils.getBindGroupLayoutTextureBindingCacheKey.html │ ├── core_bindings_utils.getBindGroupLayoutTextureBindingType.html │ ├── core_bindings_utils.getBindingVisibility.html │ ├── core_bindings_utils.getBindingWGSLVarType.html │ ├── core_bindings_utils.getBufferLayout.html │ ├── core_bindings_utils.getTextureBindingWGSLVarType.html │ ├── core_buffers_utils.getBufferUsages.html │ ├── core_materials_utils.compareRenderingOptions.html │ ├── core_meshes_mixins_MeshBaseMixin.MeshBaseMixin.html │ ├── core_meshes_mixins_ProjectedMeshBaseMixin.ProjectedMeshBaseMixin.html │ ├── core_renderers_utils.isCameraRenderer.html │ ├── core_renderers_utils.isCurtainsRenderer.html │ ├── core_renderers_utils.isProjectedMesh.html │ ├── core_renderers_utils.isRenderer.html │ ├── core_shaders_chunks_fragment_body_apply-tone-mapping.applyToneMapping.html │ ├── core_shaders_chunks_fragment_body_declare-attributes-vars.declareAttributesVars.html │ ├── core_shaders_chunks_fragment_body_declare-material-vars.declareMaterialVars.html │ ├── core_shaders_chunks_fragment_body_get-IBL-GGX-Fresnel.getIBLGGXFresnel.html │ ├── core_shaders_chunks_fragment_body_get-IBL-indirect-irradiance.getIBLIndirectIrradiance.html │ ├── core_shaders_chunks_fragment_body_get-IBL-indirect-radiance.getIBLIndirectRadiance.html │ ├── core_shaders_chunks_fragment_body_get-IBL-volume-refraction.getIBLVolumeRefraction.html │ ├── core_shaders_chunks_fragment_body_get-PBR-shading.getPBRShading.html │ ├── core_shaders_chunks_fragment_body_get-base-color.getBaseColor.html │ ├── core_shaders_chunks_fragment_body_get-emissive-occlusion.getEmissiveOcclusion.html │ ├── core_shaders_chunks_fragment_body_get-lambert-shading.getLambertShading.html │ ├── core_shaders_chunks_fragment_body_get-metallic-roughness.getMetallicRoughness.html │ ├── core_shaders_chunks_fragment_body_get-normal-tangent-bitangent.getNormalTangentBitangent.html │ ├── core_shaders_chunks_fragment_body_get-pbr-shading.getPBRShading.html │ ├── core_shaders_chunks_fragment_body_get-phong-shading.getPhongShading.html │ ├── core_shaders_chunks_fragment_body_get-specular.getSpecular.html │ ├── core_shaders_chunks_fragment_body_get-transmission-thickness.getTransmissionThickness.html │ ├── core_shaders_chunks_fragment_head_get-PCF-directional-shadows.getPCFDirectionalShadows.html │ ├── core_shaders_chunks_fragment_head_get-PCF-point-shadows.getPCFPointShadows.html │ ├── core_shaders_chunks_fragment_head_get-PCF-spot-shadows.getPCFSpotShadows.html │ ├── core_shaders_chunks_fragment_head_get-fragment-input-struct.getFragmentInputStruct.html │ ├── core_shaders_chunks_shading_PBR-shading.getPBR.html │ ├── core_shaders_chunks_shading_lambert-shading.getLambert.html │ ├── core_shaders_chunks_shading_pbr-shading.getPBR.html │ ├── core_shaders_chunks_shading_phong-shading.getPhong.html │ ├── core_shaders_chunks_vertex_body_declare-attributes-vars.declareAttributesVars.html │ ├── core_shaders_chunks_vertex_body_get-morph-targets.getMorphTargets.html │ ├── core_shaders_chunks_vertex_body_get-vertex-output.getVertexOutput.html │ ├── core_shaders_chunks_vertex_body_get-vertex-skinned-position-normal.getVertexSkinnedPositionNormal.html │ ├── core_shaders_chunks_vertex_body_get-vertex-transformed-position-normal.getVertexTransformedPositionNormal.html │ ├── core_shaders_chunks_vertex_head_get-vertex-output-struct-content.getVertexOutputStructContent.html │ ├── core_shaders_chunks_vertex_head_get-vertex-output-struct.getVertexOutputStruct.html │ ├── core_shaders_default-material-helpers.patchAdditionalChunks.html │ ├── core_shaders_full_compute_compute-diffuse-from-specular-cubemap.computeDiffuseFromSpecularCubemap.html │ ├── core_shaders_full_fragment_get-PBR-fragment-shader-code.getPBRFragmentShaderCode.html │ ├── core_shaders_full_fragment_get-default-point-shadow-depth-fragment-code.getDefaultPointShadowDepthFs.html │ ├── core_shaders_full_fragment_get-fragment-shader-code.getFragmentShaderCode.html │ ├── core_shaders_full_fragment_get-lambert-fragment-shader-code.getLambertFragmentShaderCode.html │ ├── core_shaders_full_fragment_get-pbr-fragment-shader-code.getPbrFragmentShaderCode.html │ ├── core_shaders_full_fragment_get-phong-fragment-shader-code.getPhongFragmentShaderCode.html │ ├── core_shaders_full_fragment_get-unlit-fragment-shader-code.getUnlitFragmentShaderCode.html │ ├── core_shaders_full_vertex_get-default-directional-shadow-depth-vertex-shader-code.getDefaultDirectionalShadowDepthVs.html │ ├── core_shaders_full_vertex_get-default-point-shadow-depth-vertex-shader-code.getDefaultPointShadowDepthVs.html │ ├── core_shaders_full_vertex_get-default-spot-shadow-depth-vertex-shader-code.getDefaultSpotShadowDepthVs.html │ ├── core_shaders_full_vertex_get-vertex-shader-code.getVertexShaderCode.html │ ├── core_textures_utils.getDefaultMediaTextureUsage.html │ ├── core_textures_utils.getDefaultTextureUsage.html │ ├── core_textures_utils.getNumMipLevels.html │ ├── core_textures_utils.getTextureUsages.html │ ├── math_color-utils.linearTosRGB.html │ ├── math_color-utils.linearTosRGBFloat.html │ ├── math_color-utils.sRGBToLinear.html │ ├── math_color-utils.sRGBToLinearFloat.html │ ├── utils_utils.generateUUID.html │ ├── utils_utils.throwError.html │ ├── utils_utils.throwWarning.html │ ├── utils_utils.toCamelCase.html │ └── utils_utils.toKebabCase.html ├── hierarchy.html ├── index.html ├── interfaces │ ├── core_DOM_DOMElement.DOMElementBoundingRect.html │ ├── core_DOM_DOMElement.DOMElementParams.html │ ├── core_DOM_DOMElement.DOMPosition.html │ ├── core_DOM_DOMElement.RectBBox.html │ ├── core_DOM_DOMElement.RectCoords.html │ ├── core_DOM_DOMElement.RectSize.html │ ├── core_DOM_DOMFrustum.DOMFrustumParams.html │ ├── core_bindGroups_TextureBindGroup.TextureBindGroupParams.html │ ├── core_bindings_Binding.BindingParams.html │ ├── core_bindings_BufferBinding.BufferBindingBaseParams.html │ ├── core_bindings_BufferBinding.BufferBindingChildrenBinding.html │ ├── core_bindings_BufferBinding.BufferBindingInput.html │ ├── core_bindings_BufferBinding.BufferBindingParams.html │ ├── core_bindings_SamplerBinding.SamplerBindingParams.html │ ├── core_bindings_TextureBinding.TextureBindingParams.html │ ├── core_bindings_WritableBufferBinding.WritableBufferBindingParams.html │ ├── core_bindings_bufferElements_BufferArrayElement.BufferArrayElementParams.html │ ├── core_bindings_bufferElements_BufferElement.BufferElementAlignment.html │ ├── core_bindings_bufferElements_BufferElement.BufferElementAlignmentPosition.html │ ├── core_bindings_bufferElements_BufferElement.BufferElementParams.html │ ├── core_buffers_Buffer.BufferParams.html │ ├── core_cameras_Camera.CameraBaseOptions.html │ ├── core_cameras_Camera.CameraOptions.html │ ├── core_cameras_Camera.CameraParams.html │ ├── core_cameras_OrthographicCamera.OrthographicCameraBaseOptions.html │ ├── core_cameras_OrthographicCamera.OrthographicCameraOptions.html │ ├── core_cameras_OrthographicCamera.OrthographicCameraParams.html │ ├── core_cameras_PerspectiveCamera.PerspectiveCameraBaseOptions.html │ ├── core_cameras_PerspectiveCamera.PerspectiveCameraOptions.html │ ├── core_cameras_PerspectiveCamera.PerspectiveCameraParams.html │ ├── core_computePasses_ComputePass.ComputePassOptions.html │ ├── core_computePasses_ComputePass.ComputePassParams.html │ ├── core_geometries_IndexedGeometry.IndexBuffer.html │ ├── core_geometries_IndexedGeometry.IndexedGeometryIndexBufferOptions.html │ ├── core_geometries_PlaneGeometry.PlaneGeometryParams.html │ ├── core_lights_DirectionalLight.DirectionalLightBaseParams.html │ ├── core_lights_Light.LightBaseParams.html │ ├── core_lights_Light.LightParams.html │ ├── core_lights_PointLight.PointLightBaseParams.html │ ├── core_lights_SpotLight.SpotLightBaseParams.html │ ├── core_meshes_mixins_MeshBaseMixin.MeshBaseOptions.html │ ├── core_meshes_mixins_MeshBaseMixin.MeshBaseParams.html │ ├── core_meshes_mixins_MeshBaseMixin.MeshBaseRenderParams.html │ ├── core_meshes_mixins_ProjectedMeshBaseMixin.ProjectedMeshBaseOptions.html │ ├── core_meshes_mixins_ProjectedMeshBaseMixin.ProjectedMeshBaseParams.html │ ├── core_meshes_mixins_ProjectedMeshBaseMixin.ProjectedMeshParameters.html │ ├── core_meshes_mixins_ProjectedMeshBaseMixin.ProjectedRenderMaterialParams.html │ ├── core_objects3D_Object3D.Object3DTransformMatrix.html │ ├── core_objects3D_Object3D.Object3DTransforms.html │ ├── core_objects3D_ProjectedObject3D.Object3DNormalMatrix.html │ ├── core_renderPasses_RenderBundle.RenderBundleOptions.html │ ├── core_renderPasses_RenderBundle.RenderBundleParams.html │ ├── core_renderPasses_RenderPass.ColorAttachmentParams.html │ ├── core_renderPasses_RenderPass.RenderPassOptions.html │ ├── core_renderPasses_RenderPass.RenderPassParams.html │ ├── core_renderPasses_RenderPass.RenderPassViewport.html │ ├── core_renderPasses_RenderTarget.RenderTargetOptions.html │ ├── core_renderPasses_RenderTarget.RenderTargetParams.html │ ├── core_renderPasses_ShaderPass.ShaderPassBaseParams.html │ ├── core_renderPasses_ShaderPass.ShaderPassOptions.html │ ├── core_renderPasses_ShaderPass.ShaderPassParams.html │ ├── core_renderers_GPUCameraRenderer.GPUCameraLightsRendererParams.html │ ├── core_renderers_GPUCameraRenderer.GPUCameraRendererLightParams.html │ ├── core_renderers_GPUCameraRenderer.GPUCameraRendererOptions.html │ ├── core_renderers_GPUCameraRenderer.GPUCameraRendererParams.html │ ├── core_renderers_GPUCameraRenderer.LightParams.html │ ├── core_renderers_GPUDeviceManager.GPUDeviceManagerBaseParams.html │ ├── core_renderers_GPUDeviceManager.GPUDeviceManagerParams.html │ ├── core_renderers_GPUDeviceManager.GPUDeviceManagerSetupParams.html │ ├── core_renderers_GPURenderer.GPURendererContextOptions.html │ ├── core_renderers_GPURenderer.GPURendererContextParams.html │ ├── core_renderers_GPURenderer.GPURendererOptions.html │ ├── core_renderers_GPURenderer.GPURendererParams.html │ ├── core_samplers_Sampler.SamplerOptions.html │ ├── core_samplers_Sampler.SamplerParams.html │ ├── core_scenes_Scene.ProjectionStack.html │ ├── core_scenes_Scene.RenderPassEntry.html │ ├── core_shaders_chunks_fragment_body_declare-material-vars.DeclareMaterialVarsParams.html │ ├── core_shaders_chunks_shading_PBR-shading.GetPBRShadingParams.html │ ├── core_shaders_chunks_shading_lambert-shading.GetShadingParams.html │ ├── core_shaders_chunks_shading_pbr-shading.GetPBRShadingParams.html │ ├── core_shaders_default-material-helpers.AdditionalChunks.html │ ├── core_shaders_full_fragment_get-fragment-shader-code.FragmentShaderInputBaseParams.html │ ├── core_shaders_full_fragment_get-fragment-shader-code.FragmentShaderInputParams.html │ ├── core_shaders_full_fragment_get-fragment-shader-code.LambertFragmentShaderInputParams.html │ ├── core_shaders_full_fragment_get-fragment-shader-code.PBRFragmentShaderInputParams.html │ ├── core_shaders_full_fragment_get-fragment-shader-code.PhongFragmentShaderInputParams.html │ ├── core_shaders_full_fragment_get-fragment-shader-code.UnlitFragmentShaderInputParams.html │ ├── core_shaders_full_vertex_get-vertex-shader-code.VertexShaderInputBaseParams.html │ ├── core_shaders_full_vertex_get-vertex-shader-code.VertexShaderInputParams.html │ ├── core_shadows_DirectionalShadow.DirectionalShadowParams.html │ ├── core_shadows_PointShadow.PointShadowParams.html │ ├── core_shadows_Shadow.ShadowBaseParams.html │ ├── core_shadows_SpotShadow.SpotShadowParams.html │ ├── core_textures_MediaTexture.MediaTextureOptions.html │ ├── core_textures_MediaTexture.MediaTextureParams.html │ ├── core_textures_MediaTexture.MediaTextureSource.html │ ├── core_textures_Texture.TextureBaseParams.html │ ├── core_textures_Texture.TextureParams.html │ ├── curtains_GPUCurtains.GPUCurtainsOptions.html │ ├── curtains_GPUCurtains.GPUCurtainsParams.html │ ├── curtains_meshes_DOMMesh.DOMMeshBaseParams.html │ ├── curtains_meshes_DOMMesh.DOMMeshParams.html │ ├── curtains_meshes_Plane.PlaneParams.html │ ├── curtains_objects3D_DOMObject3D.DOMObject3DParams.html │ ├── curtains_objects3D_DOMObject3D.DOMObject3DSize.html │ ├── curtains_objects3D_DOMObject3D.DOMObject3DTransforms.html │ ├── curtains_textures_DOMTexture.DOMTextureParams.html │ ├── extras_animations_KeyframesAnimation.KeyframesAnimationParams.html │ ├── extras_animations_TargetsAnimationsManager.Target.html │ ├── extras_animations_TargetsAnimationsManager.TargetsAnimationsManagerParams.html │ ├── extras_buffers_IndirectBuffer.IndirectBufferOptions.html │ ├── extras_buffers_IndirectBuffer.IndirectBufferParams.html │ ├── extras_controls_OrbitControls.OrbitControlsBaseParams.html │ ├── extras_controls_OrbitControls.OrbitControlsParams.html │ ├── extras_environmentMap_EnvironmentMap.ComputePassTextureParams.html │ ├── extras_environmentMap_EnvironmentMap.ComputeTextureBaseParams.html │ ├── extras_environmentMap_EnvironmentMap.DiffuseTextureParams.html │ ├── extras_environmentMap_EnvironmentMap.EnvironmentMapOptions.html │ ├── extras_environmentMap_EnvironmentMap.EnvironmentMapParams.html │ ├── extras_environmentMap_EnvironmentMap.LUTTextureParams.html │ ├── extras_environmentMap_EnvironmentMap.SpecularTextureParams.html │ ├── extras_geometries_BoxGeometry.BoxGeometryParams.html │ ├── extras_geometries_SphereGeometry.SphereGeometryParams.html │ ├── extras_loaders_GLTFLoader.GPUCurtainsGLTF.html │ ├── extras_loaders_HDRLoader.HDRImageData.html │ ├── extras_meshes_LitMesh.GetLitMeshMaterialUniform.html │ ├── extras_meshes_LitMesh.GetMaterialTexturesDescriptors.html │ ├── extras_meshes_LitMesh.LambertTexturesDescriptors.html │ ├── extras_meshes_LitMesh.LitMeshMaterialParams.html │ ├── extras_meshes_LitMesh.LitMeshMaterialUniformParams.html │ ├── extras_meshes_LitMesh.LitMeshParameters.html │ ├── extras_meshes_LitMesh.PBRTexturesDescriptors.html │ ├── extras_meshes_LitMesh.PhongTexturesDescriptors.html │ ├── extras_meshes_LitMesh.ShaderTextureDescriptor.html │ ├── extras_meshes_LitMesh.UnlitTexturesDescriptors.html │ ├── extras_meshes_PingPongPlane.PingPongPlaneParams.html │ ├── extras_raycaster_Raycaster.Intersection.html │ ├── math_Mat4.PerspectiveProjectionParams.html │ ├── types_BindGroups.BindGroupEntries.html │ ├── types_BindGroups.BindGroupInputs.html │ ├── types_BindGroups.BindGroupParams.html │ ├── types_BindGroups.Input.html │ ├── types_BindGroups.InputBase.html │ ├── types_Geometries.GeometryBuffer.html │ ├── types_Geometries.GeometryOptions.html │ ├── types_Geometries.IndirectDrawParams.html │ ├── types_Geometries.VertexBuffer.html │ ├── types_Geometries.VertexBufferAttribute.html │ ├── types_Geometries.VertexBufferAttributeParams.html │ ├── types_Geometries.VertexBufferParams.html │ ├── types_Materials.ComputeMaterialOptions.html │ ├── types_Materials.ComputeMaterialParams.html │ ├── types_Materials.MaterialBaseOptions.html │ ├── types_Materials.MaterialBaseParams.html │ ├── types_Materials.MaterialInputBindingsParams.html │ ├── types_Materials.MaterialOptions.html │ ├── types_Materials.MaterialParams.html │ ├── types_Materials.MaterialShaders.html │ ├── types_Materials.RenderMaterialAttributes.html │ ├── types_Materials.RenderMaterialBaseParams.html │ ├── types_Materials.RenderMaterialBaseRenderingOptions.html │ ├── types_Materials.RenderMaterialOptions.html │ ├── types_Materials.RenderMaterialParams.html │ ├── types_Materials.RenderMaterialRenderingOptions.html │ ├── types_Materials.ShaderOptions.html │ ├── types_PipelineEntries.PipelineEntryOptions.html │ ├── types_PipelineEntries.PipelineEntryParams.html │ ├── types_PipelineEntries.PipelineEntryShader.html │ ├── types_PipelineEntries.PipelineEntryShaders.html │ ├── types_PipelineEntries.PipelineEntryStatus.html │ ├── types_PipelineEntries.RenderPipelineEntryOptions.html │ ├── types_PipelineEntries.RenderPipelineEntryParams.html │ ├── types_PipelineEntries.RenderPipelineRenderingOptions.html │ ├── types_Textures.ExternalTextureParamsBase.html │ ├── types_Textures.MediaTextureBaseParams.html │ ├── types_Textures.SceneObjectTextureOptions.html │ ├── types_Textures.TextureSize.html │ ├── types_Textures.TextureVisibility.html │ ├── types_gltf_GLTF.GLTF.IAccessor.html │ ├── types_gltf_GLTF.GLTF.IAccessorSparse.html │ ├── types_gltf_GLTF.GLTF.IAccessorSparseIndices.html │ ├── types_gltf_GLTF.GLTF.IAccessorSparseValues.html │ ├── types_gltf_GLTF.GLTF.IAnimation.html │ ├── types_gltf_GLTF.GLTF.IAnimationChannel.html │ ├── types_gltf_GLTF.GLTF.IAnimationChannelTarget.html │ ├── types_gltf_GLTF.GLTF.IAnimationSampler.html │ ├── types_gltf_GLTF.GLTF.IAsset.html │ ├── types_gltf_GLTF.GLTF.IBuffer.html │ ├── types_gltf_GLTF.GLTF.IBufferView.html │ ├── types_gltf_GLTF.GLTF.ICamera.html │ ├── types_gltf_GLTF.GLTF.ICameraOrthographic.html │ ├── types_gltf_GLTF.GLTF.ICameraPerspective.html │ ├── types_gltf_GLTF.GLTF.IChildRootProperty.html │ ├── types_gltf_GLTF.GLTF.IGLTF.html │ ├── types_gltf_GLTF.GLTF.IImage.html │ ├── types_gltf_GLTF.GLTF.IMaterial.html │ ├── types_gltf_GLTF.GLTF.IMaterialNormalTextureInfo.html │ ├── types_gltf_GLTF.GLTF.IMaterialOcclusionTextureInfo.html │ ├── types_gltf_GLTF.GLTF.IMaterialPbrMetallicRoughness.html │ ├── types_gltf_GLTF.GLTF.IMesh.html │ ├── types_gltf_GLTF.GLTF.IMeshPrimitive.html │ ├── types_gltf_GLTF.GLTF.INode.html │ ├── types_gltf_GLTF.GLTF.IProperty.html │ ├── types_gltf_GLTF.GLTF.ISampler.html │ ├── types_gltf_GLTF.GLTF.IScene.html │ ├── types_gltf_GLTF.GLTF.ISkin.html │ ├── types_gltf_GLTF.GLTF.ITexture.html │ ├── types_gltf_GLTF.GLTF.ITextureInfo.html │ ├── types_gltf_GLTFExtensions.GLTFLightsPunctual.html │ ├── types_gltf_GLTFExtensions.GLTFLightsPunctualExtension.html │ ├── types_gltf_GLTFExtensions.GLTFMaterialsDispersionExtension.html │ ├── types_gltf_GLTFExtensions.GLTFMaterialsEmissiveStrengthExtension.html │ ├── types_gltf_GLTFExtensions.GLTFMaterialsIorExtension.html │ ├── types_gltf_GLTFExtensions.GLTFMaterialsSpecularExtension.html │ ├── types_gltf_GLTFExtensions.GLTFMaterialsTransmissionExtension.html │ ├── types_gltf_GLTFExtensions.GLTFMaterialsVariants.html │ ├── types_gltf_GLTFExtensions.GLTFMaterialsVolumeExtension.html │ ├── types_gltf_GLTFExtensions.GLTFMeshGPUInstancingExtension.html │ ├── types_gltf_GLTFExtensions.GLTFTextureTransform.html │ ├── types_gltf_GLTFExtensions.GLTFTextureWebP.html │ ├── types_gltf_GLTFExtensions.GLTFVariants.html │ ├── types_gltf_GLTFScenesManager.ChildDescriptor.html │ ├── types_gltf_GLTFScenesManager.MaterialTextureDescriptor.html │ ├── types_gltf_GLTFScenesManager.MeshDescriptor.html │ ├── types_gltf_GLTFScenesManager.MeshDescriptorMaterialParams.html │ ├── types_gltf_GLTFScenesManager.PrimitiveInstanceDescriptor.html │ ├── types_gltf_GLTFScenesManager.ScenesManager.html │ ├── types_gltf_GLTFScenesManager.SkinDefinition.html │ ├── utils_ResizeManager.ResizeManagerEntry.html │ ├── utils_ScrollManager.ScrollManagerParams.html │ └── utils_TasksQueueManager.TaskQueueItem.html ├── media │ ├── CONTRIBUTING.md │ └── ROADMAP.md ├── modules.html ├── modules │ ├── core_DOM_DOMElement.html │ ├── core_DOM_DOMFrustum.html │ ├── core_bindGroups_BindGroup.html │ ├── core_bindGroups_TextureBindGroup.html │ ├── core_bindings_Binding.html │ ├── core_bindings_BufferBinding.html │ ├── core_bindings_SamplerBinding.html │ ├── core_bindings_TextureBinding.html │ ├── core_bindings_WritableBufferBinding.html │ ├── core_bindings_bufferElements_BufferArrayElement.html │ ├── core_bindings_bufferElements_BufferElement.html │ ├── core_bindings_bufferElements_BufferInterleavedArrayElement.html │ ├── core_bindings_utils.html │ ├── core_buffers_Buffer.html │ ├── core_buffers_utils.html │ ├── core_cameras_Camera.html │ ├── core_cameras_OrthographicCamera.html │ ├── core_cameras_PerspectiveCamera.html │ ├── core_computePasses_ComputePass.html │ ├── core_geometries_Geometry.html │ ├── core_geometries_IndexedGeometry.html │ ├── core_geometries_PlaneGeometry.html │ ├── core_lights_AmbientLight.html │ ├── core_lights_DirectionalLight.html │ ├── core_lights_Light.html │ ├── core_lights_PointLight.html │ ├── core_lights_SpotLight.html │ ├── core_materials_ComputeMaterial.html │ ├── core_materials_Material.html │ ├── core_materials_RenderMaterial.html │ ├── core_materials_utils.html │ ├── core_meshes_FullscreenPlane.html │ ├── core_meshes_Mesh.html │ ├── core_meshes_mixins_MeshBaseMixin.html │ ├── core_meshes_mixins_ProjectedMeshBaseMixin.html │ ├── core_objects3D_Object3D.html │ ├── core_objects3D_ProjectedObject3D.html │ ├── core_pipelines_ComputePipelineEntry.html │ ├── core_pipelines_PipelineEntry.html │ ├── core_pipelines_PipelineManager.html │ ├── core_pipelines_RenderPipelineEntry.html │ ├── core_renderPasses_RenderBundle.html │ ├── core_renderPasses_RenderPass.html │ ├── core_renderPasses_RenderTarget.html │ ├── core_renderPasses_ShaderPass.html │ ├── core_renderers_GPUCameraRenderer.html │ ├── core_renderers_GPUDeviceManager.html │ ├── core_renderers_GPURenderer.html │ ├── core_renderers_utils.html │ ├── core_samplers_Sampler.html │ ├── core_scenes_Scene.html │ ├── core_shaders_chunks_fragment_body_apply-directional-shadows.html │ ├── core_shaders_chunks_fragment_body_apply-point-shadows.html │ ├── core_shaders_chunks_fragment_body_apply-spot-shadows.html │ ├── core_shaders_chunks_fragment_body_apply-tone-mapping.html │ ├── core_shaders_chunks_fragment_body_declare-attributes-vars.html │ ├── core_shaders_chunks_fragment_body_declare-material-vars.html │ ├── core_shaders_chunks_fragment_body_get-IBL-GGX-Fresnel.html │ ├── core_shaders_chunks_fragment_body_get-IBL-indirect-irradiance.html │ ├── core_shaders_chunks_fragment_body_get-IBL-indirect-radiance.html │ ├── core_shaders_chunks_fragment_body_get-IBL-volume-refraction.html │ ├── core_shaders_chunks_fragment_body_get-PBR-shading.html │ ├── core_shaders_chunks_fragment_body_get-PCF-shadows.html │ ├── core_shaders_chunks_fragment_body_get-base-color.html │ ├── core_shaders_chunks_fragment_body_get-emissive-occlusion.html │ ├── core_shaders_chunks_fragment_body_get-lambert-shading.html │ ├── core_shaders_chunks_fragment_body_get-metallic-roughness.html │ ├── core_shaders_chunks_fragment_body_get-normal-tangent-bitangent.html │ ├── core_shaders_chunks_fragment_body_get-pbr-shading.html │ ├── core_shaders_chunks_fragment_body_get-phong-shading.html │ ├── core_shaders_chunks_fragment_body_get-specular.html │ ├── core_shaders_chunks_fragment_body_get-transmission-thickness.html │ ├── core_shaders_chunks_fragment_head_RE-indirect-diffuse.html │ ├── core_shaders_chunks_fragment_head_RE-indirect-specular.html │ ├── core_shaders_chunks_fragment_head_get-IBL-GGX-Fresnel.html │ ├── core_shaders_chunks_fragment_head_get-IBL-indirect-irradiance.html │ ├── core_shaders_chunks_fragment_head_get-IBL-indirect-radiance.html │ ├── core_shaders_chunks_fragment_head_get-IBL-transmission.html │ ├── core_shaders_chunks_fragment_head_get-PBR-direct.html │ ├── core_shaders_chunks_fragment_head_get-PCF-base-shadow-contribution.html │ ├── core_shaders_chunks_fragment_head_get-PCF-directional-shadow-contribution.html │ ├── core_shaders_chunks_fragment_head_get-PCF-directional-shadows.html │ ├── core_shaders_chunks_fragment_head_get-PCF-point-shadow-contribution.html │ ├── core_shaders_chunks_fragment_head_get-PCF-point-shadows.html │ ├── core_shaders_chunks_fragment_head_get-PCF-spot-shadow-contribution.html │ ├── core_shaders_chunks_fragment_head_get-PCF-spot-shadows.html │ ├── core_shaders_chunks_fragment_head_get-fragment-input-struct.html │ ├── core_shaders_chunks_fragment_head_get-lambert-direct.html │ ├── core_shaders_chunks_fragment_head_get-lights-infos.html │ ├── core_shaders_chunks_fragment_head_get-phong-direct.html │ ├── core_shaders_chunks_fragment_head_get-uv-cover-helper.html │ ├── core_shaders_chunks_fragment_head_get-vertex-to-UV-coords-helpers.html │ ├── core_shaders_chunks_shading_PBR-shading.html │ ├── core_shaders_chunks_shading_lambert-shading.html │ ├── core_shaders_chunks_shading_pbr-shading.html │ ├── core_shaders_chunks_shading_phong-shading.html │ ├── core_shaders_chunks_utils_BRDF_GGX.html │ ├── core_shaders_chunks_utils_common.html │ ├── core_shaders_chunks_utils_constants.html │ ├── core_shaders_chunks_utils_generate-TBN.html │ ├── core_shaders_chunks_utils_hammersley-2D.html │ ├── core_shaders_chunks_utils_tone-mapping-utils.html │ ├── core_shaders_chunks_vertex_body_declare-attributes-vars.html │ ├── core_shaders_chunks_vertex_body_get-morph-targets.html │ ├── core_shaders_chunks_vertex_body_get-vertex-output.html │ ├── core_shaders_chunks_vertex_body_get-vertex-skinned-position-normal.html │ ├── core_shaders_chunks_vertex_body_get-vertex-transformed-position-normal.html │ ├── core_shaders_chunks_vertex_head_get-normal-helpers.html │ ├── core_shaders_chunks_vertex_head_get-position-helpers.html │ ├── core_shaders_chunks_vertex_head_get-vertex-output-struct-content.html │ ├── core_shaders_chunks_vertex_head_get-vertex-output-struct.html │ ├── core_shaders_default-material-helpers.html │ ├── core_shaders_full_compute_compute-BRDF-LUT.html │ ├── core_shaders_full_compute_compute-diffuse-from-specular-cubemap.html │ ├── core_shaders_full_compute_compute-specular-cubemap-from-HDR.html │ ├── core_shaders_full_fragment_get-PBR-fragment-shader-code.html │ ├── core_shaders_full_fragment_get-default-fragment-code.html │ ├── core_shaders_full_fragment_get-default-normal-fragment-code.html │ ├── core_shaders_full_fragment_get-default-point-shadow-depth-fragment-code.html │ ├── core_shaders_full_fragment_get-default-shader-pass-fragment-code.html │ ├── core_shaders_full_fragment_get-fragment-shader-code.html │ ├── core_shaders_full_fragment_get-lambert-fragment-shader-code.html │ ├── core_shaders_full_fragment_get-pbr-fragment-shader-code.html │ ├── core_shaders_full_fragment_get-phong-fragment-shader-code.html │ ├── core_shaders_full_fragment_get-unlit-fragment-shader-code.html │ ├── core_shaders_full_vertex_get-default-directional-shadow-depth-vertex-shader-code.html │ ├── core_shaders_full_vertex_get-default-point-shadow-depth-vertex-shader-code.html │ ├── core_shaders_full_vertex_get-default-projected-vertex-shader-code.html │ ├── core_shaders_full_vertex_get-default-spot-shadow-depth-vertex-shader-code.html │ ├── core_shaders_full_vertex_get-default-vertex-shader-code.html │ ├── core_shaders_full_vertex_get-vertex-shader-code.html │ ├── core_shaders_shader-chunks.html │ ├── core_shadows_DirectionalShadow.html │ ├── core_shadows_PointShadow.html │ ├── core_shadows_Shadow.html │ ├── core_shadows_SpotShadow.html │ ├── core_textures_MediaTexture.html │ ├── core_textures_Texture.html │ ├── core_textures_utils.html │ ├── curtains_GPUCurtains.html │ ├── curtains_meshes_DOMMesh.html │ ├── curtains_meshes_Plane.html │ ├── curtains_objects3D_DOMObject3D.html │ ├── curtains_renderers_GPUCurtainsRenderer.html │ ├── curtains_textures_DOMTexture.html │ ├── extras_animations_KeyframesAnimation.html │ ├── extras_animations_TargetsAnimationsManager.html │ ├── extras_buffers_IndirectBuffer.html │ ├── extras_controls_OrbitControls.html │ ├── extras_environmentMap_EnvironmentMap.html │ ├── extras_geometries_BoxGeometry.html │ ├── extras_geometries_SphereGeometry.html │ ├── extras_gltf_GLTFScenesManager.html │ ├── extras_loaders_GLTFLoader.html │ ├── extras_loaders_HDRLoader.html │ ├── extras_meshes_LitMesh.html │ ├── extras_meshes_PingPongPlane.html │ ├── extras_raycaster_Raycaster.html │ ├── math_Box3.html │ ├── math_Mat3.html │ ├── math_Mat4.html │ ├── math_Quat.html │ ├── math_Vec2.html │ ├── math_Vec3.html │ ├── math_color-utils.html │ ├── types.html │ ├── types_BindGroups.html │ ├── types_Geometries.html │ ├── types_Materials.html │ ├── types_PipelineEntries.html │ ├── types_Textures.html │ ├── types_gltf_GLTF.GLTF.html │ ├── types_gltf_GLTF.html │ ├── types_gltf_GLTFExtensions.html │ ├── types_gltf_GLTFScenesManager.html │ ├── utils_CacheManager.html │ ├── utils_ResizeManager.html │ ├── utils_ScrollManager.html │ ├── utils_TasksQueueManager.html │ ├── utils_utils.html │ └── utils_webgpu-constants.html ├── sitemap.xml ├── types │ ├── core_bindings_Binding.BindingMemoryAccessType.html │ ├── core_bindings_Binding.BindingType.html │ ├── core_bindings_Binding.BufferBindingMemoryAccessType.html │ ├── core_bindings_Binding.BufferBindingType.html │ ├── core_bindings_Binding.DOMTextureBindingType.html │ ├── core_bindings_Binding.SamplerBindingType.html │ ├── core_bindings_Binding.TextureBindingType.html │ ├── core_bindings_Binding.TextureSamplerBindings.html │ ├── core_bindings_BufferBinding.AllowedBufferElement.html │ ├── core_bindings_BufferBinding.DataViewSetFunction.html │ ├── core_bindings_SamplerBinding.SamplerBindingResource.html │ ├── core_bindings_TextureBinding.TextureBindingResource.html │ ├── core_bindings_utils.BufferLayout.html │ ├── core_bindings_utils.TypedArray.html │ ├── core_bindings_utils.TypedArrayConstructor.html │ ├── core_bindings_utils.WGSLBaseVariableType.html │ ├── core_bindings_utils.WGSLVariableType.html │ ├── core_buffers_utils.BufferUsageKeys.html │ ├── core_cameras_Camera.CameraObject3DMatrices.html │ ├── core_cameras_Camera.CameraObject3DMatricesType.html │ ├── core_lights_Light.LightsType.html │ ├── core_lights_Light.ShadowCastingLights.html │ ├── core_meshes_mixins_ProjectedMeshBaseMixin.FrustumCullingCheck.html │ ├── core_objects3D_Object3D.Object3DMatrices.html │ ├── core_objects3D_Object3D.Object3DMatricesType.html │ ├── core_objects3D_ProjectedObject3D.ProjectedObject3DMatrices.html │ ├── core_objects3D_ProjectedObject3D.ProjectedObject3DMatricesType.html │ ├── core_objects3D_ProjectedObject3D.ProjectedObject3DNormalMatrix.html │ ├── core_pipelines_PipelineManager.AllowedPipelineEntries.html │ ├── core_pipelines_PipelineManager.GPUPassTypes.html │ ├── core_pipelines_PipelineManager.GPURenderPassTypes.html │ ├── core_renderers_GPUCameraRenderer.GPUCameraRendererBindings.html │ ├── core_renderers_GPUCameraRenderer.LightsBindingParams.html │ ├── core_renderers_GPUCameraRenderer.RendererCamera.html │ ├── core_renderers_GPURenderer.DOMProjectedMesh.html │ ├── core_renderers_GPURenderer.FullscreenPass.html │ ├── core_renderers_GPURenderer.ProjectedMesh.html │ ├── core_renderers_GPURenderer.RenderedMesh.html │ ├── core_renderers_GPURenderer.SceneObject.html │ ├── core_renderers_GPURenderer.SceneStackedMesh.html │ ├── core_renderers_GPURenderer.SceneStackedObject.html │ ├── core_renderers_utils.CameraRenderer.html │ ├── core_renderers_utils.Renderer.html │ ├── core_scenes_Scene.ProjectionType.html │ ├── core_scenes_Scene.RenderPassEntries.html │ ├── core_scenes_Scene.RenderPassEntriesType.html │ ├── core_scenes_Scene.Stack.html │ ├── core_shaders_shader-chunks.ProjectedShaderChunks-1.html │ ├── core_shaders_shader-chunks.ShaderChunks.html │ ├── core_shadows_Shadow.ShadowsType.html │ ├── core_textures_utils.TextureUsageKeys.html │ ├── extras_meshes_LitMesh.ColorSpace.html │ ├── extras_meshes_LitMesh.ShadingModels.html │ ├── extras_meshes_LitMesh.ToneMappings.html │ ├── math_Quat.AxisOrder.html │ ├── types_BindGroups.AllowedBindGroups.html │ ├── types_BindGroups.BindGroupBindingElement.html │ ├── types_BindGroups.BindGroupBufferBindingElement.html │ ├── types_BindGroups.BindGroupTextureSamplerElement.html │ ├── types_BindGroups.InputValue.html │ ├── types_BindGroups.ReadOnlyInputBindings.html │ ├── types_BindGroups.ReadWriteInputBindings.html │ ├── types_Geometries.GeometryBaseParams.html │ ├── types_Geometries.GeometryParams.html │ ├── types_Materials.AllowedGeometries.html │ ├── types_Materials.ComputeMaterialShadersType.html │ ├── types_Materials.FullShadersType.html │ ├── types_Materials.MaterialBindGroups.html │ ├── types_Materials.MaterialShadersType.html │ ├── types_Materials.MaterialTexture.html │ ├── types_Materials.RenderMaterialShadersType.html │ ├── types_PipelineEntries.PipelineEntryBaseParams.html │ ├── types_Textures.TextureSource.html │ ├── types_Textures.TextureSourceType.html │ ├── types_gltf_GLTF.GLTF.AccessorComponentType.html │ ├── types_gltf_GLTF.GLTF.AccessorType.html │ ├── types_gltf_GLTF.GLTF.AnimationChannelTargetPath.html │ ├── types_gltf_GLTF.GLTF.AnimationSamplerInterpolation.html │ ├── types_gltf_GLTF.GLTF.CameraType.html │ ├── types_gltf_GLTF.GLTF.MaterialAlphaMode.html │ ├── types_gltf_GLTF.GLTF.MeshPrimitiveMode.html │ ├── types_gltf_GLTF.GLTF.TextureMagFilter.html │ ├── types_gltf_GLTF.GLTF.TextureMinFilter.html │ ├── types_gltf_GLTF.GLTF.TextureWrapMode.html │ ├── types_gltf_GLTFExtensions.ExtensionKeys.html │ ├── types_gltf_GLTFExtensions.GLTFExtensions.html │ ├── types_gltf_GLTFExtensions.GLTFExtensionsMapping.html │ ├── types_gltf_GLTFExtensions.GLTFExtensionsTypes.html │ ├── types_gltf_GLTFExtensions.GLTFExtensionsUsed.html │ ├── types_gltf_GLTFExtensions.GLTFMaterialsExtensions.html │ ├── types_gltf_GLTFExtensions.GLTFMaterialsExtensionsMapping.html │ ├── types_gltf_GLTFExtensions.GLTFNodesExtensions.html │ ├── types_gltf_GLTFExtensions.GLTFNodesExtensionsMapping.html │ ├── types_gltf_GLTFExtensions.GLTFPrimitivesExtensions.html │ ├── types_gltf_GLTFExtensions.GLTFPrimitivesExtensionsMapping.html │ ├── types_gltf_GLTFExtensions.GLTFTexturesExtensions.html │ ├── types_gltf_GLTFExtensions.GLTFTexturesExtensionsMapping.html │ ├── types_gltf_GLTFExtensions.GLTFTexturesInfosExtensions.html │ ├── types_gltf_GLTFExtensions.GLTFTexturesInfosExtensionsMapping.html │ ├── types_gltf_GLTFExtensions.MaterialExtensionKeys.html │ ├── types_gltf_GLTFExtensions.NodesExtensionKeys.html │ ├── types_gltf_GLTFExtensions.PrimitivesExtensionKeys.html │ ├── types_gltf_GLTFExtensions.TexturesExtensionKeys.html │ ├── types_gltf_GLTFExtensions.TexturesInfosExtensionKeys.html │ ├── types_gltf_GLTFScenesManager.PrimitiveInstances.html │ └── utils_TasksQueueManager.TaskQueueItemParams.html └── variables │ ├── core_bindings_bufferElements_BufferElement.bytesPerRow.html │ ├── core_bindings_bufferElements_BufferElement.bytesPerSlot.html │ ├── core_bindings_bufferElements_BufferElement.slotsPerRow.html │ ├── core_shaders_chunks_fragment_body_apply-directional-shadows.applyDirectionalShadows.html │ ├── core_shaders_chunks_fragment_body_apply-point-shadows.applyPointShadows.html │ ├── core_shaders_chunks_fragment_body_apply-spot-shadows.applySpotShadows.html │ ├── core_shaders_chunks_fragment_body_get-PCF-shadows.getPCFShadows.html │ ├── core_shaders_chunks_fragment_head_RE-indirect-diffuse.REIndirectDiffuse.html │ ├── core_shaders_chunks_fragment_head_RE-indirect-specular.REIndirectSpecular.html │ ├── core_shaders_chunks_fragment_head_get-IBL-GGX-Fresnel.getIBLGGXFresnel.html │ ├── core_shaders_chunks_fragment_head_get-IBL-indirect-irradiance.getIBLIndirectIrradiance.html │ ├── core_shaders_chunks_fragment_head_get-IBL-indirect-radiance.getIBLIndirectRadiance.html │ ├── core_shaders_chunks_fragment_head_get-IBL-transmission.getIBLTransmission.html │ ├── core_shaders_chunks_fragment_head_get-PBR-direct.getPBRDirect.html │ ├── core_shaders_chunks_fragment_head_get-PCF-base-shadow-contribution.getPCFBaseShadowContribution.html │ ├── core_shaders_chunks_fragment_head_get-PCF-directional-shadow-contribution.getPCFDirectionalShadowContribution.html │ ├── core_shaders_chunks_fragment_head_get-PCF-point-shadow-contribution.getPCFPointShadowContribution.html │ ├── core_shaders_chunks_fragment_head_get-PCF-spot-shadow-contribution.getPCFSpotShadowContribution.html │ ├── core_shaders_chunks_fragment_head_get-lambert-direct.getLambertDirect.html │ ├── core_shaders_chunks_fragment_head_get-lights-infos.getLightsInfos.html │ ├── core_shaders_chunks_fragment_head_get-phong-direct.getPhongDirect.html │ ├── core_shaders_chunks_fragment_head_get-uv-cover-helper.getUVCover.html │ ├── core_shaders_chunks_fragment_head_get-vertex-to-UV-coords-helpers.getVertexToUVCoords.html │ ├── core_shaders_chunks_shading_lambert-shading.lambertUtils.html │ ├── core_shaders_chunks_utils_BRDF_GGX.BRDF_GGX.html │ ├── core_shaders_chunks_utils_common.common.html │ ├── core_shaders_chunks_utils_constants.constants.html │ ├── core_shaders_chunks_utils_generate-TBN.generateTBN.html │ ├── core_shaders_chunks_utils_hammersley-2D.hammersley2D.html │ ├── core_shaders_chunks_utils_tone-mapping-utils.toneMappingUtils.html │ ├── core_shaders_chunks_vertex_head_get-normal-helpers.getNormalHelpers.html │ ├── core_shaders_chunks_vertex_head_get-position-helpers.getPositionHelpers.html │ ├── core_shaders_full_compute_compute-BRDF-LUT.computeBRDFLUT.html │ ├── core_shaders_full_compute_compute-specular-cubemap-from-HDR.computeSpecularCubemapFromHDR.html │ ├── core_shaders_full_fragment_get-default-fragment-code.getDefaultFragmentCode.html │ ├── core_shaders_full_fragment_get-default-normal-fragment-code.getDefaultNormalFragmentCode.html │ ├── core_shaders_full_fragment_get-default-shader-pass-fragment-code.getDefaultShaderPassFragmentCode.html │ ├── core_shaders_full_vertex_get-default-projected-vertex-shader-code.getDefaultProjectedVertexShaderCode.html │ ├── core_shaders_full_vertex_get-default-vertex-shader-code.getDefaultVertexShaderCode.html │ ├── core_shaders_shader-chunks.ProjectedShaderChunks.html │ ├── core_shaders_shader-chunks.shaderChunks-1.html │ ├── utils_CacheManager.cacheManager-1.html │ ├── utils_ResizeManager.resizeManager-1.html │ ├── utils_webgpu-constants.WebGPUBufferUsageConstants.html │ ├── utils_webgpu-constants.WebGPUShaderStageConstants.html │ └── utils_webgpu-constants.WebGPUTextureUsageConstants.html ├── examples ├── ajax-navigation-with-plane-removal │ ├── beach.html │ ├── index.html │ ├── main.js │ ├── mountain.html │ ├── styles.css │ └── view-transitions-api-utils.js ├── all-kind-of-lights-with-shadows │ ├── index.html │ └── main.js ├── basic-cube │ └── index.html ├── basic-plane │ └── index.html ├── buffer-binding-wgsl-helper │ ├── index.html │ ├── main.js │ ├── sandbox.html │ └── styles.css ├── camera-renderer-object-3d-pivot │ ├── index.html │ └── main.js ├── camera-renderer-selective-dithering │ ├── index.html │ └── main.js ├── camera-renderer-transforms-bloom-pass │ ├── index.html │ └── main.js ├── canvas-text │ ├── index.html │ ├── main.js │ └── styles.css ├── cloth-simulation │ ├── index.html │ ├── main.js │ └── styles.css ├── common-styles.css ├── compute-blur │ ├── index.html │ ├── main.js │ └── styles.css ├── compute-boids │ ├── index.html │ ├── main.js │ └── styles.css ├── compute-particles │ ├── index.html │ ├── main.js │ └── styles.css ├── cubemap │ ├── assets │ │ ├── negx.jpg │ │ ├── negy.jpg │ │ ├── negz.jpg │ │ ├── posx.jpg │ │ ├── posy.jpg │ │ ├── posz.jpg │ │ └── readme.txt │ ├── index.html │ ├── main.js │ └── styles.css ├── custom-geometry │ ├── index.html │ ├── main.js │ └── styles.css ├── custom-scroll-and-transformations │ ├── index.html │ ├── main.js │ └── styles.css ├── deferred-rendering │ ├── index.html │ ├── main.js │ └── styles.css ├── dom-meshes │ ├── index.html │ ├── main.js │ └── styles.css ├── full-screen-plane-shader │ ├── index.html │ ├── main.js │ └── styles.css ├── gltf-dom-meshes │ ├── index.html │ ├── main.js │ └── styles.css ├── gltf-loader-ibl-shading │ ├── index.html │ ├── main.js │ └── styles.css ├── gltf-loader-skins-animations-shadows │ ├── index.html │ ├── main.js │ └── styles.css ├── gsap-instanced-kinetic-typography │ ├── index.html │ ├── main.js │ └── styles.css ├── index.html ├── instanced-planes │ ├── index.html │ ├── main.js │ └── styles.css ├── instanced-shadowed-particles │ ├── index.html │ ├── main.js │ ├── shaders │ │ ├── chunks │ │ │ ├── additional-vertex-particle.wgsl.js │ │ │ ├── curl-noise.wgsl.js │ │ │ ├── discard-particle-fragment.wgsl.js │ │ │ ├── get-particle-size.wgsl.js │ │ │ └── preliminary-fragment-particle.wgsl.js │ │ ├── compute-particles.wgsl.js │ │ └── shadowed-particles.wgsl.js │ └── styles.css ├── mixing-dom-synced-planes-transmissive-bubbles │ ├── index.html │ ├── main.js │ └── styles.css ├── multiple-canvases-updating-renderer │ ├── index.html │ ├── main.js │ └── styles.css ├── multiple-canvases │ ├── index.html │ ├── main.js │ └── styles.css ├── multiple-planes │ ├── index.html │ ├── main.js │ └── styles.css ├── order-independent-transparency-galaxy │ ├── index.html │ └── main.js ├── ping-pong-plane │ ├── index.html │ ├── main.js │ └── styles.css ├── planar-reflections │ ├── index.html │ └── main.js ├── post-processing-transform-origin │ ├── index.html │ ├── main.js │ └── styles.css ├── raycasting-render-bundle-phong-shading │ ├── index.html │ └── main.js ├── render-bundle-indirect-drawing-gpu-culling │ ├── index.html │ ├── main.js │ └── styles.css ├── screen-space-ambient-occlusion │ ├── index.html │ └── main.js ├── selective-shader-passes-using-render-target │ ├── index.html │ ├── main.js │ └── styles.css ├── shadow-mapping │ ├── index.html │ ├── main.js │ └── styles.css ├── sitemap.xml ├── slideshow │ ├── index.html │ ├── main.js │ └── styles.css ├── video-planes │ ├── index.html │ ├── main.js │ └── styles.css └── webcam-media-stream-ping-pong │ ├── index.html │ └── main.js ├── guides ├── 3d-engine-usage.md ├── bindings-and-bind-groups.md ├── core-concepts.md ├── dom-syncing-usage.md ├── getting-started.md └── renderers-scene-rendering-and-camera.md ├── index.html ├── package.json ├── rollup.config.js ├── sitemap.xml ├── src ├── core │ ├── DOM │ │ ├── DOMElement.ts │ │ └── DOMFrustum.ts │ ├── bindGroups │ │ ├── BindGroup.ts │ │ └── TextureBindGroup.ts │ ├── bindings │ │ ├── Binding.ts │ │ ├── BufferBinding.ts │ │ ├── SamplerBinding.ts │ │ ├── TextureBinding.ts │ │ ├── WritableBufferBinding.ts │ │ ├── bufferElements │ │ │ ├── BufferArrayElement.ts │ │ │ ├── BufferElement.ts │ │ │ └── BufferInterleavedArrayElement.ts │ │ └── utils.ts │ ├── buffers │ │ ├── Buffer.ts │ │ └── utils.ts │ ├── cameras │ │ ├── Camera.ts │ │ ├── OrthographicCamera.ts │ │ └── PerspectiveCamera.ts │ ├── computePasses │ │ └── ComputePass.ts │ ├── geometries │ │ ├── Geometry.ts │ │ ├── IndexedGeometry.ts │ │ └── PlaneGeometry.ts │ ├── lights │ │ ├── AmbientLight.ts │ │ ├── DirectionalLight.ts │ │ ├── Light.ts │ │ ├── PointLight.ts │ │ └── SpotLight.ts │ ├── materials │ │ ├── ComputeMaterial.ts │ │ ├── Material.ts │ │ ├── RenderMaterial.ts │ │ └── utils.ts │ ├── meshes │ │ ├── FullscreenPlane.ts │ │ ├── Mesh.ts │ │ └── mixins │ │ │ ├── MeshBaseMixin.ts │ │ │ └── ProjectedMeshBaseMixin.ts │ ├── objects3D │ │ ├── Object3D.ts │ │ └── ProjectedObject3D.ts │ ├── pipelines │ │ ├── ComputePipelineEntry.ts │ │ ├── PipelineEntry.ts │ │ ├── PipelineManager.ts │ │ └── RenderPipelineEntry.ts │ ├── renderPasses │ │ ├── RenderBundle.ts │ │ ├── RenderPass.ts │ │ ├── RenderTarget.ts │ │ └── ShaderPass.ts │ ├── renderers │ │ ├── GPUCameraRenderer.ts │ │ ├── GPUDeviceManager.ts │ │ ├── GPURenderer.ts │ │ └── utils.ts │ ├── samplers │ │ └── Sampler.ts │ ├── scenes │ │ └── Scene.ts │ ├── shaders │ │ ├── chunks │ │ │ ├── fragment │ │ │ │ ├── body │ │ │ │ │ ├── apply-directional-shadows.ts │ │ │ │ │ ├── apply-point-shadows.ts │ │ │ │ │ ├── apply-spot-shadows.ts │ │ │ │ │ ├── apply-tone-mapping.ts │ │ │ │ │ ├── declare-attributes-vars.ts │ │ │ │ │ ├── declare-material-vars.ts │ │ │ │ │ ├── get-IBL-GGX-Fresnel.ts │ │ │ │ │ ├── get-IBL-indirect-irradiance.ts │ │ │ │ │ ├── get-IBL-indirect-radiance.ts │ │ │ │ │ ├── get-IBL-volume-refraction.ts │ │ │ │ │ ├── get-PBR-shading.ts │ │ │ │ │ ├── get-PCF-shadows.ts │ │ │ │ │ ├── get-base-color.ts │ │ │ │ │ ├── get-emissive-occlusion.ts │ │ │ │ │ ├── get-lambert-shading.ts │ │ │ │ │ ├── get-metallic-roughness.ts │ │ │ │ │ ├── get-normal-tangent-bitangent.ts │ │ │ │ │ ├── get-phong-shading.ts │ │ │ │ │ ├── get-specular.ts │ │ │ │ │ └── get-transmission-thickness.ts │ │ │ │ └── head │ │ │ │ │ ├── RE-indirect-diffuse.ts │ │ │ │ │ ├── RE-indirect-specular.ts │ │ │ │ │ ├── get-IBL-GGX-Fresnel.ts │ │ │ │ │ ├── get-IBL-indirect-irradiance.ts │ │ │ │ │ ├── get-IBL-indirect-radiance.ts │ │ │ │ │ ├── get-IBL-transmission.ts │ │ │ │ │ ├── get-PBR-direct.ts │ │ │ │ │ ├── get-PCF-base-shadow-contribution.ts │ │ │ │ │ ├── get-PCF-directional-shadow-contribution.ts │ │ │ │ │ ├── get-PCF-directional-shadows.ts │ │ │ │ │ ├── get-PCF-point-shadow-contribution.ts │ │ │ │ │ ├── get-PCF-point-shadows.ts │ │ │ │ │ ├── get-PCF-spot-shadow-contribution.ts │ │ │ │ │ ├── get-PCF-spot-shadows.ts │ │ │ │ │ ├── get-fragment-input-struct.ts │ │ │ │ │ ├── get-lambert-direct.ts │ │ │ │ │ ├── get-lights-infos.ts │ │ │ │ │ ├── get-phong-direct.ts │ │ │ │ │ ├── get-uv-cover-helper.ts │ │ │ │ │ └── get-vertex-to-UV-coords-helpers.ts │ │ │ ├── shading │ │ │ │ ├── PBR-shading.ts │ │ │ │ ├── lambert-shading.ts │ │ │ │ └── phong-shading.ts │ │ │ ├── utils │ │ │ │ ├── BRDF_GGX.ts │ │ │ │ ├── common.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── generate-TBN.ts │ │ │ │ ├── hammersley-2D.ts │ │ │ │ └── tone-mapping-utils.ts │ │ │ └── vertex │ │ │ │ ├── body │ │ │ │ ├── declare-attributes-vars.ts │ │ │ │ ├── get-morph-targets.ts │ │ │ │ ├── get-vertex-output.ts │ │ │ │ ├── get-vertex-skinned-position-normal.ts │ │ │ │ └── get-vertex-transformed-position-normal.ts │ │ │ │ └── head │ │ │ │ ├── get-normal-helpers.ts │ │ │ │ ├── get-position-helpers.ts │ │ │ │ ├── get-vertex-output-struct-content.ts │ │ │ │ └── get-vertex-output-struct.ts │ │ ├── default-material-helpers.ts │ │ ├── full │ │ │ ├── compute │ │ │ │ ├── compute-BRDF-LUT.ts │ │ │ │ ├── compute-diffuse-from-specular-cubemap.ts │ │ │ │ └── compute-specular-cubemap-from-HDR.ts │ │ │ ├── fragment │ │ │ │ ├── get-PBR-fragment-shader-code.ts │ │ │ │ ├── get-default-fragment-code.ts │ │ │ │ ├── get-default-normal-fragment-code.ts │ │ │ │ ├── get-default-point-shadow-depth-fragment-code.ts │ │ │ │ ├── get-default-shader-pass-fragment-code.ts │ │ │ │ ├── get-fragment-shader-code.ts │ │ │ │ ├── get-lambert-fragment-shader-code.ts │ │ │ │ ├── get-phong-fragment-shader-code.ts │ │ │ │ └── get-unlit-fragment-shader-code.ts │ │ │ └── vertex │ │ │ │ ├── get-default-directional-shadow-depth-vertex-shader-code.ts │ │ │ │ ├── get-default-point-shadow-depth-vertex-shader-code.ts │ │ │ │ ├── get-default-projected-vertex-shader-code.ts │ │ │ │ ├── get-default-spot-shadow-depth-vertex-shader-code.ts │ │ │ │ ├── get-default-vertex-shader-code.ts │ │ │ │ └── get-vertex-shader-code.ts │ │ └── shader-chunks.ts │ ├── shadows │ │ ├── DirectionalShadow.ts │ │ ├── PointShadow.ts │ │ ├── Shadow.ts │ │ └── SpotShadow.ts │ └── textures │ │ ├── MediaTexture.ts │ │ ├── Texture.ts │ │ └── utils.ts ├── curtains │ ├── GPUCurtains.ts │ ├── meshes │ │ ├── DOMMesh.ts │ │ └── Plane.ts │ ├── objects3D │ │ └── DOMObject3D.ts │ ├── renderers │ │ └── GPUCurtainsRenderer.ts │ └── textures │ │ └── DOMTexture.ts ├── extras │ ├── animations │ │ ├── KeyframesAnimation.ts │ │ └── TargetsAnimationsManager.ts │ ├── buffers │ │ └── IndirectBuffer.ts │ ├── controls │ │ └── OrbitControls.ts │ ├── environmentMap │ │ └── EnvironmentMap.ts │ ├── geometries │ │ ├── BoxGeometry.ts │ │ └── SphereGeometry.ts │ ├── gltf │ │ └── GLTFScenesManager.ts │ ├── loaders │ │ ├── GLTFLoader.ts │ │ └── HDRLoader.ts │ ├── meshes │ │ ├── LitMesh.ts │ │ └── PingPongPlane.ts │ └── raycaster │ │ └── Raycaster.ts ├── index.ts ├── math │ ├── Box3.ts │ ├── Mat3.ts │ ├── Mat4.ts │ ├── Quat.ts │ ├── Vec2.ts │ ├── Vec3.ts │ └── color-utils.ts ├── types │ ├── BindGroups.ts │ ├── Geometries.ts │ ├── Materials.ts │ ├── PipelineEntries.ts │ ├── Textures.ts │ ├── gltf │ │ ├── GLTF.ts │ │ ├── GLTFExtensions.ts │ │ └── GLTFScenesManager.ts │ └── index.ts └── utils │ ├── CacheManager.ts │ ├── ResizeManager.ts │ ├── ScrollManager.ts │ ├── TasksQueueManager.ts │ ├── utils.ts │ └── webgpu-constants.ts ├── tests ├── basic-rotating-cube │ ├── index.html │ └── main.js ├── bindings-offsets │ ├── index.html │ ├── main.js │ └── styles.css ├── camera │ ├── index.html │ ├── main.js │ └── styles.css ├── canvas-resizing │ ├── index.html │ ├── main.js │ └── styles.css ├── compute-results │ ├── index.html │ ├── main.js │ └── styles.css ├── context-lost │ ├── index.html │ ├── main.js │ └── styles.css ├── cubemap-env │ ├── index.html │ ├── main.js │ └── styles.css ├── dynamic-materials-geometries │ ├── index.html │ └── main.js ├── frustum-culling │ ├── index.html │ ├── main.js │ └── styles.css ├── gltf-loader │ ├── index.html │ ├── main.js │ └── styles.css ├── gltf-shadows │ ├── assets │ │ ├── cannon_1k.hdr │ │ └── lut.png │ ├── index.html │ ├── main.js │ └── styles.css ├── gltf-skins-shadows │ ├── index.html │ ├── main.js │ └── styles.css ├── index.html ├── lights-dynamic-renderer │ ├── index.html │ ├── main.js │ └── styles.css ├── lights │ ├── index.html │ └── main.js ├── lit-meshes │ ├── index.html │ ├── main.js │ └── styles.css ├── multiple-canvases │ ├── index.html │ ├── main.js │ └── styles.css ├── objects-removal │ ├── TestComputePasses.js │ ├── TestPingPong.js │ ├── TestRenderTargets.js │ ├── compute.html │ ├── index.html │ ├── main.js │ ├── ping-pong.html │ ├── render-targets.html │ ├── styles.css │ └── view-transitions-api-utils.js ├── offscreen-canvas │ ├── index.html │ ├── init.js │ ├── main.js │ ├── styles.css │ └── worker.js ├── orbit-camera-depth-texture │ ├── index.html │ └── main.js ├── orbit-camera-selective-passes │ ├── index.html │ └── main.js ├── orbit-controls │ ├── index.html │ └── main.js ├── order-independent-transparency │ ├── index.html │ └── main.js ├── plane-transformations │ ├── index.html │ ├── main.js │ └── styles.css ├── post-processing-input-output │ ├── index.html │ └── main.js ├── post-processing-passes │ ├── index.html │ └── main.js ├── raycaster │ ├── index.html │ └── main.js ├── reflections │ ├── index.html │ └── main.js ├── render-bundles │ ├── index.html │ ├── main.js │ └── styles.css ├── reset-plane │ ├── index.html │ ├── main.js │ └── styles.css ├── scene-graph │ ├── index.html │ └── main.js ├── scroll-resize │ ├── index.html │ ├── main.js │ └── styles.css ├── shadow-mapping │ ├── index.html │ ├── main.js │ └── styles.css ├── stencil-test │ ├── index.html │ └── main.js ├── stress-test-instanced │ ├── index.html │ ├── main.js │ └── styles.css ├── stress-test-render-bundle │ ├── index.html │ ├── main.js │ └── styles.css ├── stress-test │ ├── index.html │ ├── main.js │ └── styles.css ├── textures-dom-textures │ ├── index.html │ ├── main.js │ └── styles.css ├── textures-external-textures │ ├── index.html │ ├── main.js │ └── styles.css ├── textures-media-textures │ ├── index.html │ ├── main.js │ └── styles.css ├── textures-transformations │ ├── index.html │ ├── main.js │ └── styles.css ├── transparent-meshes-sorting │ ├── index.html │ └── main.js └── umd-test │ ├── index.html │ └── main.js ├── tsconfig.json ├── typedoc.json ├── website ├── assets │ ├── favicon.png │ ├── gltf │ │ ├── Suzanne.bin │ │ ├── Suzanne.gltf │ │ ├── Suzanne_BaseColor.png │ │ └── Suzanne_MetallicRoughness.png │ ├── gpu-curtains-logo-1080-720.jpg │ ├── gpu-curtains-logo-1080-720.png │ ├── gpu-curtains-logo-1920-1280.jpg │ ├── gpu-curtains-logo-1920-1280.png │ └── hdr │ │ ├── Colorful_Studio.hdr │ │ └── cannon_1k.hdr ├── js │ ├── components │ │ ├── ComputeFeature.js │ │ ├── CurtainsClothSim.js │ │ ├── GLTFExample.js │ │ ├── IntroDOMMeshes.js │ │ └── TexturesPlanes.js │ ├── main.js │ ├── shaders │ │ ├── compute-cloth.wgsl.js │ │ ├── compute-feature-instances.wgsl.js │ │ ├── curtains-cloth.wgsl.js │ │ ├── feature-instances.wgsl.js │ │ ├── image-plane.wgsl.js │ │ └── normals-opacity-fs.wgsl.js │ └── utils │ │ └── ScrollObserver.js └── styles.css └── yarn.lock /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | ecmaVersion: 11, 5 | sourceType: 'module', 6 | }, 7 | parser: '@typescript-eslint/parser', 8 | plugins: ['@typescript-eslint'], 9 | extends: ['prettier', 'plugin:@typescript-eslint/recommended'], 10 | // add your custom rules here 11 | rules: {}, 12 | } 13 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [martinlaxenaire] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Code example** 24 | If possible, provide a minimal code example demonstrating the issue, using one of the online code editor tool (codepen, jsfiddle, codesandbox...) 25 | 26 | **Screenshots** 27 | If applicable, add screenshots to help explain your problem. 28 | 29 | **Desktop (please complete the following information):** 30 | - OS: [e.g. iOS] 31 | - Browser [e.g. chrome, safari] 32 | - Version [e.g. 22] 33 | 34 | **Smartphone (please complete the following information):** 35 | - Device: [e.g. iPhone6] 36 | - OS: [e.g. iOS8.1] 37 | - Browser [e.g. stock browser, safari] 38 | - Version [e.g. 22] 39 | 40 | **Additional context** 41 | Add any other context about the problem here. 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /node_modules 3 | /yarn-error.log 4 | /types-tests -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /examples 2 | /docs 3 | /tests 4 | /website 5 | *.html 6 | *.css -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": false, 4 | "printWidth": 120 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Martin Laxenaire 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /dist/esm/core/bindings/Binding.mjs: -------------------------------------------------------------------------------- 1 | import { toCamelCase } from '../../utils/utils.mjs'; 2 | import { getBindingVisibility } from './utils.mjs'; 3 | 4 | class Binding { 5 | /** 6 | * Binding constructor 7 | * @param parameters - {@link BindingParams | parameters} used to create our {@link Binding}. 8 | */ 9 | constructor({ 10 | label = "Uniform", 11 | name = "uniform", 12 | bindingType = "uniform", 13 | visibility = ["vertex", "fragment", "compute"] 14 | }) { 15 | this.label = label; 16 | this.name = toCamelCase(name); 17 | this.bindingType = bindingType; 18 | this.visibility = getBindingVisibility(visibility); 19 | this.options = { 20 | label, 21 | name, 22 | bindingType, 23 | visibility 24 | }; 25 | this.shouldResetBindGroup = false; 26 | this.shouldResetBindGroupLayout = false; 27 | this.cacheKey = `${bindingType},${this.visibility},`; 28 | } 29 | } 30 | 31 | export { Binding }; 32 | -------------------------------------------------------------------------------- /dist/esm/core/bindings/WritableBufferBinding.mjs: -------------------------------------------------------------------------------- 1 | import { BufferBinding } from './BufferBinding.mjs'; 2 | import { Buffer } from '../buffers/Buffer.mjs'; 3 | 4 | class WritableBufferBinding extends BufferBinding { 5 | /** 6 | * WritableBufferBinding constructor 7 | * @param parameters - {@link WritableBufferBindingParams | parameters} used to create our {@link WritableBufferBinding} 8 | */ 9 | constructor({ 10 | label = "Work", 11 | name = "work", 12 | bindingType, 13 | visibility, 14 | useStruct = true, 15 | access = "read_write", 16 | usage = [], 17 | struct = {}, 18 | childrenBindings = [], 19 | buffer = null, 20 | parent = null, 21 | minOffset = 256, 22 | offset = 0, 23 | shouldCopyResult = false 24 | }) { 25 | bindingType = "storage"; 26 | visibility = ["compute"]; 27 | super({ 28 | label, 29 | name, 30 | bindingType, 31 | visibility, 32 | useStruct, 33 | access, 34 | usage, 35 | struct, 36 | childrenBindings, 37 | buffer, 38 | parent, 39 | minOffset, 40 | offset 41 | }); 42 | this.options = { 43 | ...this.options, 44 | shouldCopyResult 45 | }; 46 | this.shouldCopyResult = shouldCopyResult; 47 | this.cacheKey += `${shouldCopyResult},`; 48 | this.resultBuffer = new Buffer(); 49 | } 50 | } 51 | 52 | export { WritableBufferBinding }; 53 | -------------------------------------------------------------------------------- /dist/esm/core/buffers/utils.mjs: -------------------------------------------------------------------------------- 1 | import { WebGPUBufferUsageConstants } from '../../utils/webgpu-constants.mjs'; 2 | 3 | const bufferUsages = /* @__PURE__ */ new Map([ 4 | ["copySrc", WebGPUBufferUsageConstants.COPY_SRC], 5 | ["copyDst", WebGPUBufferUsageConstants.COPY_DST], 6 | ["index", WebGPUBufferUsageConstants.INDEX], 7 | ["indirect", WebGPUBufferUsageConstants.INDIRECT], 8 | ["mapRead", WebGPUBufferUsageConstants.MAP_READ], 9 | ["mapWrite", WebGPUBufferUsageConstants.MAP_WRITE], 10 | ["queryResolve", WebGPUBufferUsageConstants.QUERY_RESOLVE], 11 | ["storage", WebGPUBufferUsageConstants.STORAGE], 12 | ["uniform", WebGPUBufferUsageConstants.UNIFORM], 13 | ["vertex", WebGPUBufferUsageConstants.VERTEX] 14 | ]); 15 | const getBufferUsages = (usages = []) => { 16 | return usages.reduce((acc, v) => { 17 | return acc | bufferUsages.get(v); 18 | }, 0); 19 | }; 20 | 21 | export { getBufferUsages }; 22 | -------------------------------------------------------------------------------- /dist/esm/core/lights/AmbientLight.mjs: -------------------------------------------------------------------------------- 1 | import { Light } from './Light.mjs'; 2 | import { Vec3 } from '../../math/Vec3.mjs'; 3 | 4 | class AmbientLight extends Light { 5 | /** 6 | * AmbientLight constructor 7 | * @param renderer - {@link CameraRenderer} or {@link GPUCurtains} used to create this {@link AmbientLight}. 8 | * @param parameters - {@link LightBaseParams} used to create this {@link AmbientLight}. 9 | */ 10 | constructor(renderer, { label = "AmbientLight", color = new Vec3(1), intensity = 0.1 } = {}) { 11 | const type = "ambientLights"; 12 | super(renderer, { label, color, intensity, type }); 13 | } 14 | // explicitly disable position as well 15 | /** @ignore */ 16 | applyPosition() { 17 | } 18 | } 19 | 20 | export { AmbientLight }; 21 | -------------------------------------------------------------------------------- /dist/esm/core/materials/utils.mjs: -------------------------------------------------------------------------------- 1 | const compareRenderingOptions = (newOptions = {}, baseOptions = {}) => { 2 | const renderingOptions = [ 3 | "useProjection", 4 | "transparent", 5 | "depth", 6 | "depthWriteEnabled", 7 | "depthCompare", 8 | "depthFormat", 9 | "cullMode", 10 | "sampleCount", 11 | "targets", 12 | "stencil", 13 | "verticesOrder", 14 | "topology" 15 | ]; 16 | return renderingOptions.map((key) => { 17 | if (newOptions[key] !== void 0 && baseOptions[key] === void 0 || baseOptions[key] !== void 0 && newOptions[key] === void 0) { 18 | return key; 19 | } else if (Array.isArray(newOptions[key]) || typeof newOptions[key] === "object") { 20 | return JSON.stringify(newOptions[key]) !== JSON.stringify(baseOptions[key]) ? key : false; 21 | } else { 22 | return newOptions[key] !== baseOptions[key] ? key : false; 23 | } 24 | }).filter(Boolean); 25 | }; 26 | 27 | export { compareRenderingOptions }; 28 | -------------------------------------------------------------------------------- /dist/esm/core/meshes/Mesh.mjs: -------------------------------------------------------------------------------- 1 | import { isCameraRenderer } from '../renderers/utils.mjs'; 2 | import { ProjectedObject3D } from '../objects3D/ProjectedObject3D.mjs'; 3 | import { ProjectedMeshBaseMixin } from './mixins/ProjectedMeshBaseMixin.mjs'; 4 | 5 | class Mesh extends ProjectedMeshBaseMixin(ProjectedObject3D) { 6 | /** 7 | * Mesh constructor 8 | * @param renderer - {@link CameraRenderer} object or {@link GPUCurtains} class object used to create this {@link Mesh}. 9 | * @param parameters - {@link ProjectedMeshParameters | parameters} use to create this {@link Mesh}. 10 | */ 11 | constructor(renderer, parameters = {}) { 12 | renderer = isCameraRenderer(renderer, parameters.label ? parameters.label + " Mesh" : "Mesh"); 13 | super(renderer, null, parameters); 14 | this.type = "Mesh"; 15 | } 16 | } 17 | 18 | export { Mesh }; 19 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/apply-directional-shadows.mjs: -------------------------------------------------------------------------------- 1 | const applyDirectionalShadows = ( 2 | /* wgsl */ 3 | ` 4 | directLight.color *= directionalShadows[i]; 5 | ` 6 | ); 7 | 8 | export { applyDirectionalShadows }; 9 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/apply-point-shadows.mjs: -------------------------------------------------------------------------------- 1 | const applyPointShadows = ( 2 | /* wgsl */ 3 | ` 4 | directLight.color *= pointShadows[i]; 5 | ` 6 | ); 7 | 8 | export { applyPointShadows }; 9 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/apply-spot-shadows.mjs: -------------------------------------------------------------------------------- 1 | const applySpotShadows = ( 2 | /* wgsl */ 3 | ` 4 | directLight.color *= spotShadows[i]; 5 | ` 6 | ); 7 | 8 | export { applySpotShadows }; 9 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/apply-tone-mapping.mjs: -------------------------------------------------------------------------------- 1 | const applyToneMapping = ({ toneMapping = "Khronos" } = {}) => { 2 | let toneMappingOutput = ( 3 | /* wgsl */ 4 | ` 5 | let exposure: f32 = 1.0; // TODO 6 | outputColor *= exposure; 7 | ` 8 | ); 9 | toneMappingOutput += (() => { 10 | switch (toneMapping) { 11 | case "Khronos": 12 | return ( 13 | /* wgsl */ 14 | ` 15 | outputColor = vec4(KhronosToneMapping(outputColor.rgb), outputColor.a); 16 | ` 17 | ); 18 | case "Reinhard": 19 | return ` 20 | outputColor = vec4(ReinhardToneMapping(outputColor.rgb), outputColor.a); 21 | `; 22 | case "Cineon": 23 | return ` 24 | outputColor = vec4(CineonToneMapping(outputColor.rgb), outputColor.a); 25 | `; 26 | case false: 27 | default: 28 | return ` 29 | outputColor = saturate(outputColor); 30 | `; 31 | } 32 | })(); 33 | toneMappingOutput += /* wgsl */ 34 | ` 35 | outputColor = linearTosRGB_4(outputColor); 36 | `; 37 | return toneMappingOutput; 38 | }; 39 | 40 | export { applyToneMapping }; 41 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/get-IBL-GGX-Fresnel.mjs: -------------------------------------------------------------------------------- 1 | const getIBLGGXFresnel = ({ 2 | environmentMap = null 3 | }) => { 4 | let iblIGGXFresnel = ( 5 | /* wgsl */ 6 | ` 7 | var iBLGGXFresnel: IBLGGXFresnel;` 8 | ); 9 | if (environmentMap && environmentMap.lutTexture) { 10 | iblIGGXFresnel += /* wgsl */ 11 | ` 12 | iBLGGXFresnel = getIBLGGXFresnel( 13 | normal, 14 | viewDirection, 15 | roughness, 16 | specularColor, 17 | specularIntensity, 18 | ${environmentMap.sampler.name}, 19 | ${environmentMap.lutTexture.options.name}, 20 | );`; 21 | } else { 22 | iblIGGXFresnel += /* wgsl */ 23 | ` 24 | computeMultiscattering( 25 | normal, 26 | viewDirection, 27 | specularColor, 28 | specularIntensity, 29 | roughness, 30 | &iBLGGXFresnel 31 | );`; 32 | } 33 | return iblIGGXFresnel; 34 | }; 35 | 36 | export { getIBLGGXFresnel }; 37 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/get-IBL-indirect-irradiance.mjs: -------------------------------------------------------------------------------- 1 | const getIBLIndirectIrradiance = ({ 2 | environmentMap = null 3 | }) => { 4 | let iblIndirectDiffuse = ""; 5 | if (environmentMap) { 6 | iblIndirectDiffuse += /* wgs */ 7 | ` 8 | iblIrradiance += getIBLIndirectIrradiance( 9 | normal, 10 | baseDiffuseColor.rgb, 11 | ${environmentMap.sampler.name}, 12 | ${environmentMap.diffuseTexture.options.name}, 13 | envRotation, 14 | envDiffuseIntensity, 15 | );`; 16 | } 17 | return iblIndirectDiffuse; 18 | }; 19 | 20 | export { getIBLIndirectIrradiance }; 21 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/get-IBL-indirect-radiance.mjs: -------------------------------------------------------------------------------- 1 | const getIBLIndirectRadiance = ({ 2 | environmentMap = null 3 | }) => { 4 | let iblIndirectSpecular = ""; 5 | if (environmentMap) { 6 | iblIndirectSpecular += /* wgs */ 7 | ` 8 | radiance += getIBLIndirectRadiance( 9 | normal, 10 | viewDirection, 11 | roughness, 12 | specularColor, 13 | specularIntensity, 14 | iBLGGXFresnel, 15 | ${environmentMap.sampler.name}, 16 | ${environmentMap.specularTexture.options.name}, 17 | envRotation, 18 | envSpecularIntensity, 19 | );`; 20 | } 21 | return iblIndirectSpecular; 22 | }; 23 | 24 | export { getIBLIndirectRadiance }; 25 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/get-IBL-volume-refraction.mjs: -------------------------------------------------------------------------------- 1 | const getIBLVolumeRefraction = ({ 2 | transmissionBackgroundTexture = null, 3 | extensionsUsed = [] 4 | }) => { 5 | const hasDispersion = extensionsUsed.includes("KHR_materials_dispersion"); 6 | const iblVolumeRefractionFunction = hasDispersion ? "getIBLVolumeRefractionWithDispersion" : "getIBLVolumeRefraction"; 7 | return transmissionBackgroundTexture ? ( 8 | /* wgsl */ 9 | ` 10 | var transmissionAlpha: f32 = 1.0; 11 | 12 | var transmitted: vec4f = ${iblVolumeRefractionFunction}( 13 | normal, 14 | normalize(viewDirection), 15 | roughness, 16 | baseDiffuseColor, 17 | specularColor, 18 | specularF90, 19 | worldPosition, 20 | modelScale, 21 | camera.view, 22 | camera.projection, 23 | dispersion, 24 | ior, 25 | thickness, 26 | attenuationColor, 27 | attenuationDistance, 28 | ${transmissionBackgroundTexture.texture.options.name}, 29 | ${transmissionBackgroundTexture.sampler.name}, 30 | ); 31 | 32 | transmissionAlpha = mix( transmissionAlpha, transmitted.a, transmission ); 33 | 34 | totalDiffuse = mix(totalDiffuse, transmitted.rgb, transmission); 35 | outputColor.a *= transmissionAlpha;` 36 | ) : ""; 37 | }; 38 | 39 | export { getIBLVolumeRefraction }; 40 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/get-PCF-shadows.mjs: -------------------------------------------------------------------------------- 1 | const getPCFShadows = ( 2 | /* wgsl */ 3 | ` 4 | let pointShadows = getPCFPointShadows(worldPosition); 5 | let directionalShadows = getPCFDirectionalShadows(worldPosition); 6 | let spotShadows = getPCFSpotShadows(worldPosition); 7 | ` 8 | ); 9 | 10 | export { getPCFShadows }; 11 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/body/get-metallic-roughness.mjs: -------------------------------------------------------------------------------- 1 | const getMetallicRoughness = ({ 2 | metallicRoughnessTexture = null 3 | } = {}) => { 4 | let metallicRoughness = ""; 5 | if (metallicRoughnessTexture) { 6 | metallicRoughness += /* wgsl */ 7 | ` 8 | var metallicRoughnessUV: vec2f = ${metallicRoughnessTexture.texCoordAttributeName ?? "uv"};`; 9 | if ("useTransform" in metallicRoughnessTexture.texture.options && metallicRoughnessTexture.texture.options.useTransform) { 10 | metallicRoughness += /* wgsl */ 11 | ` 12 | metallicRoughnessUV = (${metallicRoughnessTexture.texture.options.name}Matrix * vec3(metallicRoughnessUV, 1.0)).xy;`; 13 | } 14 | metallicRoughness += /* wgsl */ 15 | ` 16 | let metallicRoughness = textureSample(${metallicRoughnessTexture.texture.options.name}, ${metallicRoughnessTexture.sampler?.name ?? "defaultSampler"}, metallicRoughnessUV); 17 | 18 | metallic = metallic * metallicRoughness.b; 19 | roughness = roughness * metallicRoughness.g; 20 | `; 21 | } 22 | metallicRoughness += /* wgsl */ 23 | ` 24 | metallic = saturate(metallic); 25 | roughness = clamp(roughness, 0.0525, 1.0); 26 | `; 27 | return metallicRoughness; 28 | }; 29 | 30 | export { getMetallicRoughness }; 31 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/RE-indirect-diffuse.mjs: -------------------------------------------------------------------------------- 1 | const REIndirectDiffuse = ( 2 | /* wgsl */ 3 | ` 4 | fn getIndirectDiffuse(irradiance: vec3f, diffuseColor: vec3f, ptr_reflectedLight: ptr) { 5 | (*ptr_reflectedLight).indirectDiffuse += irradiance * BRDF_Lambert( diffuseColor ); 6 | } 7 | 8 | // Indirect Diffuse RenderEquations 9 | fn RE_IndirectDiffuse(irradiance: vec3f, diffuseColor: vec3f, ptr_reflectedLight: ptr) { 10 | var totalAmbientIrradiance: vec3f = irradiance; 11 | 12 | for(var i: i32 = 0; i < ambientLights.count; i++) { 13 | totalAmbientIrradiance += ambientLights.color[i]; 14 | } 15 | 16 | getIndirectDiffuse(totalAmbientIrradiance, diffuseColor, ptr_reflectedLight); 17 | } 18 | ` 19 | ); 20 | 21 | export { REIndirectDiffuse }; 22 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/RE-indirect-specular.mjs: -------------------------------------------------------------------------------- 1 | const REIndirectSpecular = ( 2 | /* wgsl */ 3 | ` 4 | // Indirect Specular RenderEquations 5 | fn RE_IndirectSpecular( 6 | radiance: vec3f, 7 | irradiance: vec3f, 8 | normal: vec3f, 9 | diffuseColor: vec3f, 10 | specularFactor: f32, 11 | specularColorFactor: vec3f, 12 | viewDirection: vec3f, 13 | metallic: f32, 14 | roughness: f32, 15 | iBLGGXFresnel: IBLGGXFresnel, 16 | ptr_reflectedLight: ptr 17 | ) { 18 | let k_D: vec3f = diffuseColor * (1.0 - iBLGGXFresnel.FssEss + iBLGGXFresnel.FmsEms); 19 | 20 | // we just add radiance and irradiance to the indirect contributions using iBLGGXFresnel 21 | // we might need to adjust when implementing clearcoat, sheen or iridescence 22 | 23 | // we remove RECIPROCAL_PI multiplication since the LUT already ensures energy conservation 24 | let cosineWeightedIrradiance: vec3f = irradiance; 25 | // let cosineWeightedIrradiance: vec3f = irradiance * RECIPROCAL_PI; 26 | 27 | (*ptr_reflectedLight).indirectSpecular += iBLGGXFresnel.FssEss * radiance; 28 | (*ptr_reflectedLight).indirectSpecular += iBLGGXFresnel.FmsEms * cosineWeightedIrradiance; 29 | 30 | (*ptr_reflectedLight).indirectDiffuse += k_D * cosineWeightedIrradiance; 31 | } 32 | ` 33 | ); 34 | 35 | export { REIndirectSpecular }; 36 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-IBL-indirect-irradiance.mjs: -------------------------------------------------------------------------------- 1 | const getIBLIndirectIrradiance = ( 2 | /* wgsl */ 3 | ` 4 | fn getIBLIndirectIrradiance( 5 | normal: vec3f, 6 | diffuseColor: vec3f, 7 | clampSampler: sampler, 8 | envDiffuseTexture: texture_cube, 9 | envRotation: mat3x3f, 10 | envDiffuseIntensity: f32, 11 | ) -> vec3f { 12 | // IBL diffuse (irradiance) 13 | let diffuseLight: vec4f = textureSample( 14 | envDiffuseTexture, 15 | clampSampler, 16 | normal * envRotation 17 | ); 18 | 19 | return diffuseLight.rgb * envDiffuseIntensity; 20 | } 21 | ` 22 | ); 23 | 24 | export { getIBLIndirectIrradiance }; 25 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-IBL-indirect-radiance.mjs: -------------------------------------------------------------------------------- 1 | const getIBLIndirectRadiance = ( 2 | /* wgsl */ 3 | ` 4 | fn getIBLIndirectRadiance( 5 | normal: vec3f, 6 | viewDirection: vec3f, 7 | roughness: f32, 8 | specularColor: vec3f, 9 | specularFactor: f32, 10 | iBLGGXFresnel: IBLGGXFresnel, 11 | clampSampler: sampler, 12 | envSpecularTexture: texture_cube, 13 | envRotation: mat3x3f, 14 | envSpecularIntensity: f32, 15 | )-> vec3f { 16 | let N: vec3f = normal; 17 | let V: vec3f = viewDirection; 18 | let NdotV: f32 = saturate(dot(N, V)); 19 | 20 | let reflection: vec3f = normalize(reflect(-V, N)); 21 | 22 | let lod: f32 = roughness * f32(textureNumLevels(envSpecularTexture) - 1); 23 | 24 | let specularLight: vec4f = textureSampleLevel( 25 | envSpecularTexture, 26 | clampSampler, 27 | reflection * envRotation, 28 | lod 29 | ); 30 | 31 | return specularLight.rgb * envSpecularIntensity; 32 | } 33 | ` 34 | ); 35 | 36 | export { getIBLIndirectRadiance }; 37 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-PCF-directional-shadow-contribution.mjs: -------------------------------------------------------------------------------- 1 | const getPCFDirectionalShadowContribution = ( 2 | /* wgsl */ 3 | ` 4 | fn getPCFDirectionalShadowContribution(index: i32, worldPosition: vec3f, depthTexture: texture_depth_2d) -> f32 { 5 | let directionalShadow: DirectionalShadowsElement = directionalShadows.directionalShadowsElements[index]; 6 | 7 | // get shadow coords 8 | let projectedShadowCoords: vec4f = directionalShadow.projectionMatrix * directionalShadow.viewMatrix * vec4(worldPosition, 1.0); 9 | var shadowCoords: vec3f = projectedShadowCoords.xyz / projectedShadowCoords.w; 10 | 11 | // Convert XY to (0, 1) 12 | // Y is flipped because texture coords are Y-down. 13 | shadowCoords = vec3( 14 | shadowCoords.xy * vec2(0.5, -0.5) + vec2(0.5), 15 | shadowCoords.z 16 | ); 17 | 18 | return getPCFBaseShadowContribution( 19 | shadowCoords, 20 | directionalShadow.pcfSamples, 21 | directionalShadow.bias, 22 | directionalShadow.intensity, 23 | depthTexture 24 | ); 25 | } 26 | ` 27 | ); 28 | 29 | export { getPCFDirectionalShadowContribution }; 30 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-PCF-directional-shadows.mjs: -------------------------------------------------------------------------------- 1 | const getPCFDirectionalShadows = (renderer) => { 2 | const directionalLights = renderer.shadowCastingLights.filter( 3 | (light) => light.type === "directionalLights" 4 | ); 5 | const minDirectionalLights = Math.max(renderer.lightsBindingParams.directionalLights.max, 1); 6 | return ( 7 | /* wgsl */ 8 | ` 9 | fn getPCFDirectionalShadows(worldPosition: vec3f) -> array { 10 | var directionalShadowContribution: array; 11 | 12 | var lightDirection: vec3f; 13 | 14 | ${directionalLights.map((light, index) => { 15 | return `lightDirection = worldPosition - directionalLights.elements[${index}].direction; 16 | 17 | ${light.shadow.isActive ? ` 18 | if(directionalShadows.directionalShadowsElements[${index}].isActive > 0) { 19 | directionalShadowContribution[${index}] = getPCFDirectionalShadowContribution( 20 | ${index}, 21 | worldPosition, 22 | directionalShadowDepthTexture${index} 23 | ); 24 | } else { 25 | directionalShadowContribution[${index}] = 1.0; 26 | } 27 | ` : `directionalShadowContribution[${index}] = 1.0;`}`; 28 | }).join("\n")} 29 | 30 | return directionalShadowContribution; 31 | } 32 | ` 33 | ); 34 | }; 35 | 36 | export { getPCFDirectionalShadows }; 37 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-PCF-spot-shadow-contribution.mjs: -------------------------------------------------------------------------------- 1 | const getPCFSpotShadowContribution = ( 2 | /* wgsl */ 3 | ` 4 | fn getPCFSpotShadowContribution(index: i32, worldPosition: vec3f, depthTexture: texture_depth_2d) -> f32 { 5 | let spotShadow: SpotShadowsElement = spotShadows.spotShadowsElements[index]; 6 | 7 | // get shadow coords 8 | let projectedShadowCoords: vec4f = spotShadow.projectionMatrix * spotShadow.viewMatrix * vec4(worldPosition, 1.0); 9 | var shadowCoords: vec3f = projectedShadowCoords.xyz / projectedShadowCoords.w; 10 | 11 | // Convert XY to (0, 1) 12 | // Y is flipped because texture coords are Y-down. 13 | shadowCoords = vec3( 14 | shadowCoords.xy * vec2(0.5, -0.5) + vec2(0.5), 15 | shadowCoords.z 16 | ); 17 | 18 | return getPCFBaseShadowContribution( 19 | shadowCoords, 20 | spotShadow.pcfSamples, 21 | spotShadow.bias, 22 | spotShadow.intensity, 23 | depthTexture 24 | ); 25 | } 26 | ` 27 | ); 28 | 29 | export { getPCFSpotShadowContribution }; 30 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-PCF-spot-shadows.mjs: -------------------------------------------------------------------------------- 1 | const getPCFSpotShadows = (renderer) => { 2 | const spotLights = renderer.shadowCastingLights.filter((light) => light.type === "spotLights"); 3 | const minSpotLights = Math.max(renderer.lightsBindingParams.spotLights.max, 1); 4 | return ( 5 | /* wgsl */ 6 | ` 7 | fn getPCFSpotShadows(worldPosition: vec3f) -> array { 8 | var spotShadowContribution: array; 9 | 10 | var lightDirection: vec3f; 11 | 12 | ${spotLights.map((light, index) => { 13 | return `lightDirection = worldPosition - spotLights.elements[${index}].direction; 14 | 15 | ${light.shadow.isActive ? ` 16 | if(spotShadows.spotShadowsElements[${index}].isActive > 0) { 17 | spotShadowContribution[${index}] = getPCFSpotShadowContribution( 18 | ${index}, 19 | worldPosition, 20 | spotShadowDepthTexture${index} 21 | ); 22 | } else { 23 | spotShadowContribution[${index}] = 1.0; 24 | } 25 | ` : `spotShadowContribution[${index}] = 1.0;`}`; 26 | }).join("\n")} 27 | 28 | return spotShadowContribution; 29 | } 30 | ` 31 | ); 32 | }; 33 | 34 | export { getPCFSpotShadows }; 35 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-fragment-input-struct.mjs: -------------------------------------------------------------------------------- 1 | import { getVertexOutputStructContent } from '../../vertex/head/get-vertex-output-struct-content.mjs'; 2 | 3 | const getFragmentInputStruct = ({ 4 | geometry, 5 | additionalVaryings = [] 6 | }) => { 7 | return ( 8 | /* wgsl */ 9 | ` 10 | struct FSInput { 11 | @builtin(front_facing) frontFacing: bool, 12 | ${getVertexOutputStructContent({ geometry, additionalVaryings })} 13 | };` 14 | ); 15 | }; 16 | 17 | export { getFragmentInputStruct }; 18 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-lambert-direct.mjs: -------------------------------------------------------------------------------- 1 | const getLambertDirect = ( 2 | /* wgsl */ 3 | ` 4 | fn getLambertDirect( 5 | normal: vec3f, 6 | diffuseColor: vec3f, 7 | directLight: DirectLight, 8 | ptr_reflectedLight: ptr 9 | ) { 10 | let NdotL = saturate(dot(normal, directLight.direction)); 11 | 12 | let irradiance: vec3f = NdotL * directLight.color; 13 | (*ptr_reflectedLight).directDiffuse += irradiance * BRDF_Lambert( diffuseColor ); 14 | } 15 | ` 16 | ); 17 | 18 | export { getLambertDirect }; 19 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-uv-cover-helper.mjs: -------------------------------------------------------------------------------- 1 | const getUVCover = ( 2 | /* wgsl */ 3 | ` 4 | fn getUVCover(uv: vec2f, textureMatrix: mat3x3f) -> vec2f { 5 | return (textureMatrix * vec3f(uv, 1.0)).xy; 6 | }` 7 | ); 8 | 9 | export { getUVCover }; 10 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/fragment/head/get-vertex-to-UV-coords-helpers.mjs: -------------------------------------------------------------------------------- 1 | const getVertexToUVCoords = ( 2 | /* wgsl */ 3 | ` 4 | fn getVertex2DToUVCoords(vertex: vec2f) -> vec2f { 5 | return vec2( 6 | vertex.x * 0.5 + 0.5, 7 | 0.5 - vertex.y * 0.5 8 | ); 9 | } 10 | 11 | fn getVertex3DToUVCoords(vertex: vec3f) -> vec2f { 12 | return getVertex2DToUVCoords( vec2(vertex.x, vertex.y) ); 13 | } 14 | ` 15 | ); 16 | 17 | export { getVertexToUVCoords }; 18 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/shading/phong-shading.mjs: -------------------------------------------------------------------------------- 1 | import { lambertUtils } from './lambert-shading.mjs'; 2 | import { getPhongDirect } from '../fragment/head/get-phong-direct.mjs'; 3 | import { getPhongShading } from '../fragment/body/get-phong-shading.mjs'; 4 | import { applyToneMapping } from '../fragment/body/apply-tone-mapping.mjs'; 5 | 6 | const getPhong = ({ addUtils = true, receiveShadows = false, toneMapping, useOcclusion = false } = {}) => ( 7 | /* wgsl */ 8 | ` 9 | ${addUtils ? lambertUtils : ""} 10 | ${getPhongDirect} 11 | 12 | fn getPhong( 13 | normal: vec3f, 14 | worldPosition: vec3f, 15 | color: vec4f, 16 | viewDirection: vec3f, 17 | specularIntensity: f32, 18 | specularColor: vec3f, 19 | shininess: f32, 20 | ${useOcclusion ? "occlusion: f32," : ""} 21 | ) -> vec4f { 22 | ${!useOcclusion ? "let occlusion: f32 = 1.0;" : ""} 23 | 24 | var outputColor: vec4f = color; 25 | 26 | ${getPhongShading({ receiveShadows })} 27 | 28 | outputColor = vec4(outgoingLight, outputColor.a); 29 | 30 | ${applyToneMapping({ toneMapping })} 31 | 32 | return outputColor; 33 | } 34 | ` 35 | ); 36 | 37 | export { getPhong }; 38 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/utils/BRDF_GGX.mjs: -------------------------------------------------------------------------------- 1 | const BRDF_GGX = ( 2 | /* wgsl */ 3 | ` 4 | fn DistributionGGX(NdotH: f32, roughness: f32) -> f32 { 5 | let a: f32 = pow2( roughness ); 6 | let a2: f32 = pow2( a ); 7 | 8 | let denom: f32 = (pow2( NdotH ) * (a2 - 1.0) + 1.0); 9 | 10 | return RECIPROCAL_PI * a2 / ( pow2( denom ) ); 11 | } 12 | 13 | fn GeometrySmith(NdotL: f32, NdotV: f32, roughness: f32) -> f32 { 14 | let a: f32 = pow2( roughness ); 15 | let a2: f32 = pow2( a ); 16 | 17 | let gv: f32 = NdotL * sqrt( a2 + ( 1.0 - a2 ) * pow2( NdotV ) ); 18 | let gl: f32 = NdotV * sqrt( a2 + ( 1.0 - a2 ) * pow2( NdotL ) ); 19 | 20 | return 0.5 / max( gv + gl, EPSILON ); 21 | } 22 | 23 | fn BRDF_GGX( 24 | NdotV: f32, 25 | NdotL: f32, 26 | NdotH: f32, 27 | VdotH: f32, 28 | roughness: f32, 29 | specularFactor: f32, 30 | specularColor: vec3f 31 | ) -> vec3f { 32 | // cook-torrance brdf 33 | let G: f32 = GeometrySmith(NdotL, NdotV, roughness); 34 | let D: f32 = DistributionGGX(NdotH, roughness); 35 | let F: vec3f = F_Schlick(specularColor, specularFactor, VdotH); 36 | 37 | return G * D * F; 38 | } 39 | ` 40 | ); 41 | 42 | export { BRDF_GGX }; 43 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/utils/common.mjs: -------------------------------------------------------------------------------- 1 | const common = ( 2 | /* wgsl */ 3 | ` 4 | fn lessThan3(a: vec3f, b: vec3f) -> vec3f { 5 | return vec3f(vec3(a.x < b.x, a.y < b.y, a.z < b.z)); 6 | } 7 | 8 | fn pow2( x: f32 ) -> f32 { 9 | return x * x; 10 | } 11 | 12 | fn pow3( x: f32 ) -> f32 { 13 | return x * x * x; 14 | } 15 | 16 | fn pow4( x: f32 ) -> f32 { 17 | return pow2(x) * pow2(x); 18 | } 19 | 20 | fn isinf(value: f32) -> bool { 21 | return value > 1.0e38 || value < -1.0e38; 22 | } 23 | 24 | fn BRDF_Lambert(diffuseColor: vec3f) -> vec3f { 25 | return RECIPROCAL_PI * diffuseColor; 26 | } 27 | 28 | fn F_Schlick(f0: vec3f, f90: f32, VdotH: f32) -> vec3f { 29 | let fresnel: f32 = exp2( ( - 5.55473 * VdotH - 6.98316 ) * VdotH ); 30 | return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel ); 31 | } 32 | ` 33 | ); 34 | 35 | export { common }; 36 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/utils/constants.mjs: -------------------------------------------------------------------------------- 1 | const constants = ( 2 | /* wgsl */ 3 | ` 4 | const PI = ${Math.PI}; 5 | const RECIPROCAL_PI = ${1 / Math.PI}; 6 | const RECIPROCAL_PI2 = ${0.5 / Math.PI}; 7 | const EPSILON = 1e-6;` 8 | ); 9 | 10 | export { constants }; 11 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/utils/generate-TBN.mjs: -------------------------------------------------------------------------------- 1 | const generateTBN = ( 2 | /* wgsl */ 3 | ` 4 | // TBN generates a tangent bitangent normal coordinate frame from the normal 5 | // (the normal must be normalized) 6 | fn generateTBN(normal: vec3f) -> mat3x3f { 7 | var bitangent: vec3f = vec3(0.0, 1.0, 0.0); 8 | 9 | let NdotUp: f32 = dot(normal, vec3(0.0, 1.0, 0.0)); 10 | 11 | if (1.0 - abs(NdotUp) <= EPSILON) { 12 | // Sampling +Y or -Y, so we need a more robust bitangent. 13 | if (NdotUp > 0.0) { 14 | bitangent = vec3(0.0, 0.0, 1.0); 15 | } 16 | else { 17 | bitangent = vec3(0.0, 0.0, -1.0); 18 | } 19 | } 20 | 21 | let tangent: vec3f = normalize(cross(bitangent, normal)); 22 | bitangent = cross(normal, tangent); 23 | 24 | return mat3x3f(tangent, bitangent, normal); 25 | } 26 | ` 27 | ); 28 | 29 | export { generateTBN }; 30 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/utils/hammersley-2D.mjs: -------------------------------------------------------------------------------- 1 | const hammersley2D = ( 2 | /* wgsl */ 3 | ` 4 | fn radicalInverse_VdC(inputBits: u32) -> f32 { 5 | var bits: u32 = inputBits; 6 | bits = (bits << 16u) | (bits >> 16u); 7 | bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); 8 | bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); 9 | bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); 10 | bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); 11 | return f32(bits) * 2.3283064365386963e-10; // / 0x100000000 12 | } 13 | 14 | // hammersley2d describes a sequence of points in the 2d unit square [0,1)^2 15 | // that can be used for quasi Monte Carlo integration 16 | fn hammersley2d(i: u32, N: u32) -> vec2f { 17 | return vec2(f32(i) / f32(N), radicalInverse_VdC(i)); 18 | } 19 | ` 20 | ); 21 | 22 | export { hammersley2D }; 23 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/vertex/body/declare-attributes-vars.mjs: -------------------------------------------------------------------------------- 1 | const declareAttributesVars = ({ geometry }) => { 2 | let attributeVars = geometry.vertexBuffers.map( 3 | (vertexBuffer) => vertexBuffer.attributes.map((attribute) => { 4 | return ( 5 | /* wgsl */ 6 | ` 7 | var ${attribute.name}: ${attribute.type} = attributes.${attribute.name};` 8 | ); 9 | }).join("") 10 | ).join("\n"); 11 | attributeVars += /* wgsl */ 12 | ` 13 | var instanceIndex: u32 = attributes.instanceIndex; 14 | `; 15 | return attributeVars; 16 | }; 17 | 18 | export { declareAttributesVars }; 19 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/vertex/body/get-vertex-output.mjs: -------------------------------------------------------------------------------- 1 | const getVertexOutput = ({ geometry }) => { 2 | let output = ( 3 | /* wgsl */ 4 | ` 5 | vsOutput.position = camera.projection * camera.view * worldPosition; 6 | vsOutput.normal = normal; 7 | vsOutput.worldPosition = worldPosition.xyz / worldPosition.w; 8 | vsOutput.viewDirection = camera.position - vsOutput.worldPosition; 9 | vsOutput.modelScale = vec3( 10 | length(modelMatrix[0].xyz), 11 | length(modelMatrix[1].xyz), 12 | length(modelMatrix[2].xyz) 13 | ); 14 | ` 15 | ); 16 | const tangentAttribute = geometry.getAttributeByName("tangent"); 17 | if (tangentAttribute) { 18 | output += /* wgsl */ 19 | ` 20 | vsOutput.tangent = normalize(modelMatrix * tangent); 21 | vsOutput.bitangent = cross(vsOutput.normal, vsOutput.tangent.xyz) * vsOutput.tangent.w; 22 | `; 23 | } 24 | output += geometry.vertexBuffers.map( 25 | (vertexBuffer) => vertexBuffer.attributes.filter((attr) => attr.name !== "normal" && attr.name !== "position" && attr.name !== "tangent").map((attribute) => { 26 | return ( 27 | /* wgsl */ 28 | ` 29 | vsOutput.${attribute.name} = ${attribute.name};` 30 | ); 31 | }).join("") 32 | ).join("\n"); 33 | return output; 34 | }; 35 | 36 | export { getVertexOutput }; 37 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/vertex/body/get-vertex-transformed-position-normal.mjs: -------------------------------------------------------------------------------- 1 | import { getMorphTargets } from './get-morph-targets.mjs'; 2 | import { getVertexSkinnedPositionNormal } from './get-vertex-skinned-position-normal.mjs'; 3 | 4 | const getVertexTransformedPositionNormal = ({ 5 | bindings = [], 6 | geometry 7 | }) => { 8 | let output = ""; 9 | output += getMorphTargets({ bindings, geometry }); 10 | output += /* wgsl */ 11 | ` 12 | var worldPosition: vec4f = vec4(position, 1.0); 13 | `; 14 | output += getVertexSkinnedPositionNormal({ bindings, geometry }); 15 | return output; 16 | }; 17 | 18 | export { getVertexTransformedPositionNormal }; 19 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/vertex/head/get-normal-helpers.mjs: -------------------------------------------------------------------------------- 1 | const getNormalHelpers = ( 2 | /* wgsl */ 3 | ` 4 | fn getWorldNormal(normal: vec3f) -> vec3f { 5 | return normalize(matrices.normal * normal); 6 | } 7 | 8 | fn getViewNormal(normal: vec3f) -> vec3f { 9 | return normalize((camera.view * vec4(matrices.normal * normal, 0.0)).xyz); 10 | }` 11 | ); 12 | 13 | export { getNormalHelpers }; 14 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/vertex/head/get-position-helpers.mjs: -------------------------------------------------------------------------------- 1 | const getPositionHelpers = ( 2 | /* wgsl */ 3 | ` 4 | fn getWorldPosition(position: vec3f) -> vec4f { 5 | return matrices.model * vec4f(position, 1.0); 6 | } 7 | 8 | fn getOutputPosition(position: vec3f) -> vec4f { 9 | return camera.projection * camera.view * matrices.model * vec4f(position, 1.0); 10 | }` 11 | ); 12 | 13 | export { getPositionHelpers }; 14 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/chunks/vertex/head/get-vertex-output-struct.mjs: -------------------------------------------------------------------------------- 1 | import { getVertexOutputStructContent } from './get-vertex-output-struct-content.mjs'; 2 | 3 | const getVertexOutputStruct = ({ 4 | geometry, 5 | additionalVaryings = [] 6 | }) => { 7 | return ( 8 | /* wgsl */ 9 | ` 10 | struct VSOutput { 11 | ${getVertexOutputStructContent({ geometry, additionalVaryings })} 12 | };` 13 | ); 14 | }; 15 | 16 | export { getVertexOutputStruct }; 17 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/default-material-helpers.mjs: -------------------------------------------------------------------------------- 1 | const patchAdditionalChunks = (chunks = null) => { 2 | if (!chunks) { 3 | chunks = { 4 | additionalHead: "", 5 | preliminaryContribution: "", 6 | additionalContribution: "" 7 | }; 8 | } else { 9 | if (!chunks.additionalHead) { 10 | chunks.additionalHead = ""; 11 | } 12 | if (!chunks.preliminaryContribution) { 13 | chunks.preliminaryContribution = ""; 14 | } 15 | if (!chunks.additionalContribution) { 16 | chunks.additionalContribution = ""; 17 | } 18 | } 19 | return chunks; 20 | }; 21 | 22 | export { patchAdditionalChunks }; 23 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/full/fragment/get-default-fragment-code.mjs: -------------------------------------------------------------------------------- 1 | const getDefaultFragmentCode = ( 2 | /* wgsl */ 3 | ` 4 | @fragment fn main() -> @location(0) vec4f { 5 | return vec4(0.0, 0.0, 0.0, 1.0); 6 | }` 7 | ); 8 | 9 | export { getDefaultFragmentCode }; 10 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/full/fragment/get-default-normal-fragment-code.mjs: -------------------------------------------------------------------------------- 1 | const getDefaultNormalFragmentCode = ( 2 | /* wgsl */ 3 | ` 4 | struct VSOutput { 5 | @builtin(position) position: vec4f, 6 | @location(0) uv: vec2f, 7 | @location(1) normal: vec3f, 8 | }; 9 | 10 | @fragment fn main(fsInput: VSOutput) -> @location(0) vec4f { 11 | // normals 12 | return vec4(normalize(fsInput.normal) * 0.5 + 0.5, 1.0); 13 | }` 14 | ); 15 | 16 | export { getDefaultNormalFragmentCode }; 17 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/full/fragment/get-default-point-shadow-depth-fragment-code.mjs: -------------------------------------------------------------------------------- 1 | const getDefaultPointShadowDepthFs = (lightIndex = 0) => ( 2 | /* wgsl */ 3 | ` 4 | struct PointShadowVSOutput { 5 | @builtin(position) position: vec4f, 6 | @location(0) worldPosition: vec3f, 7 | } 8 | 9 | @fragment fn main(fsInput: PointShadowVSOutput) -> @builtin(frag_depth) f32 { 10 | let pointShadow: PointShadowsElement = pointShadows.pointShadowsElements[${lightIndex}]; 11 | 12 | // get distance between fragment and light source 13 | var lightDistance: f32 = length(fsInput.worldPosition - pointShadow.position); 14 | 15 | // map to [0, 1] range by dividing by far plane - near plane 16 | lightDistance = (lightDistance - pointShadow.cameraNear) / (pointShadow.cameraFar - pointShadow.cameraNear); 17 | 18 | // write this as modified depth 19 | return saturate(lightDistance); 20 | }` 21 | ); 22 | 23 | export { getDefaultPointShadowDepthFs }; 24 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/full/fragment/get-default-shader-pass-fragment-code.mjs: -------------------------------------------------------------------------------- 1 | const getDefaultShaderPassFragmentCode = ( 2 | /* wgsl */ 3 | ` 4 | struct VSOutput { 5 | @builtin(position) position: vec4f, 6 | @location(0) uv: vec2f, 7 | }; 8 | 9 | @fragment fn main(fsInput: VSOutput) -> @location(0) vec4f { 10 | return textureSample(renderTexture, defaultSampler, fsInput.uv); 11 | }` 12 | ); 13 | 14 | export { getDefaultShaderPassFragmentCode }; 15 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/full/vertex/get-default-projected-vertex-shader-code.mjs: -------------------------------------------------------------------------------- 1 | const getDefaultProjectedVertexShaderCode = ( 2 | /* wgsl */ 3 | ` 4 | struct VSOutput { 5 | @builtin(position) position: vec4f, 6 | @location(0) uv: vec2f, 7 | @location(1) normal: vec3f, 8 | @location(2) worldPosition: vec3f, 9 | @location(3) viewDirection: vec3f, 10 | }; 11 | 12 | @vertex fn main( 13 | attributes: Attributes, 14 | ) -> VSOutput { 15 | var vsOutput: VSOutput; 16 | 17 | vsOutput.position = getOutputPosition(attributes.position); 18 | vsOutput.uv = attributes.uv; 19 | vsOutput.normal = getWorldNormal(attributes.normal); 20 | let worldPosition: vec4f = getWorldPosition(attributes.position); 21 | vsOutput.worldPosition = worldPosition.xyz / worldPosition.w; 22 | vsOutput.viewDirection = camera.position - vsOutput.worldPosition; 23 | 24 | return vsOutput; 25 | }` 26 | ); 27 | 28 | export { getDefaultProjectedVertexShaderCode }; 29 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/full/vertex/get-default-vertex-shader-code.mjs: -------------------------------------------------------------------------------- 1 | const getDefaultVertexShaderCode = ( 2 | /* wgsl */ 3 | ` 4 | struct VSOutput { 5 | @builtin(position) position: vec4f, 6 | @location(0) uv: vec2f, 7 | }; 8 | 9 | @vertex fn main( 10 | attributes: Attributes, 11 | ) -> VSOutput { 12 | var vsOutput: VSOutput; 13 | 14 | vsOutput.position = vec4f(attributes.position, 1.0); 15 | vsOutput.uv = attributes.uv; 16 | 17 | return vsOutput; 18 | }` 19 | ); 20 | 21 | export { getDefaultVertexShaderCode }; 22 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/full/vertex/get-vertex-shader-code.mjs: -------------------------------------------------------------------------------- 1 | import { getVertexOutputStruct } from '../../chunks/vertex/head/get-vertex-output-struct.mjs'; 2 | import { getVertexOutput } from '../../chunks/vertex/body/get-vertex-output.mjs'; 3 | import { getVertexTransformedPositionNormal } from '../../chunks/vertex/body/get-vertex-transformed-position-normal.mjs'; 4 | import { declareAttributesVars } from '../../chunks/vertex/body/declare-attributes-vars.mjs'; 5 | import { patchAdditionalChunks } from '../../default-material-helpers.mjs'; 6 | 7 | const getVertexShaderCode = ({ 8 | bindings = [], 9 | geometry, 10 | chunks = null, 11 | additionalVaryings = [] 12 | }) => { 13 | chunks = patchAdditionalChunks(chunks); 14 | return ( 15 | /* wgsl */ 16 | ` 17 | ${chunks.additionalHead} 18 | 19 | ${getVertexOutputStruct({ geometry, additionalVaryings })} 20 | 21 | @vertex fn main( 22 | attributes: Attributes, 23 | ) -> VSOutput { 24 | var vsOutput: VSOutput; 25 | 26 | ${declareAttributesVars({ geometry })} 27 | 28 | // user defined preliminary contribution 29 | ${chunks.preliminaryContribution} 30 | 31 | ${getVertexTransformedPositionNormal({ bindings, geometry })} 32 | 33 | ${getVertexOutput({ geometry })} 34 | 35 | // user defined additional contribution 36 | ${chunks.additionalContribution} 37 | 38 | return vsOutput; 39 | }` 40 | ); 41 | }; 42 | 43 | export { getVertexShaderCode }; 44 | -------------------------------------------------------------------------------- /dist/esm/core/shaders/shader-chunks.mjs: -------------------------------------------------------------------------------- 1 | import { getPositionHelpers } from './chunks/vertex/head/get-position-helpers.mjs'; 2 | import { getNormalHelpers } from './chunks/vertex/head/get-normal-helpers.mjs'; 3 | import { getUVCover } from './chunks/fragment/head/get-uv-cover-helper.mjs'; 4 | import { getVertexToUVCoords } from './chunks/fragment/head/get-vertex-to-UV-coords-helpers.mjs'; 5 | 6 | const shaderChunks = { 7 | /** WGSL code chunks added to the vertex shader */ 8 | vertex: { 9 | /** Applies given texture matrix (`mat4x4f`) to given uv coordinates (`vec2f`). */ 10 | getUVCover 11 | }, 12 | /** WGSL code chunks added to the fragment shader */ 13 | fragment: { 14 | /** Applies given texture matrix (`mat4x4f`) to given uv coordinates (`vec2f`). */ 15 | getUVCover, 16 | /** Convert vertex position as `vec2f` or `vec3f` to uv coordinates `vec2f`. */ 17 | getVertexToUVCoords 18 | } 19 | }; 20 | const ProjectedShaderChunks = { 21 | /** WGSL code chunks added to the vertex shader */ 22 | vertex: { 23 | /** Get output `position` (`vec4f`) vector by applying model view projection matrix to the attribute `position` (`vec3f`) vector. */ 24 | getPositionHelpers, 25 | /** Get `normal` (`vec3f`) in world or view space. */ 26 | getNormalHelpers 27 | }, 28 | /** WGSL code chunks added to the fragment shader */ 29 | fragment: {} 30 | }; 31 | 32 | export { ProjectedShaderChunks, shaderChunks }; 33 | -------------------------------------------------------------------------------- /dist/esm/core/textures/utils.mjs: -------------------------------------------------------------------------------- 1 | import { WebGPUTextureUsageConstants } from '../../utils/webgpu-constants.mjs'; 2 | 3 | const textureUsages = /* @__PURE__ */ new Map([ 4 | ["copySrc", WebGPUTextureUsageConstants.COPY_SRC], 5 | ["copyDst", WebGPUTextureUsageConstants.COPY_DST], 6 | ["renderAttachment", WebGPUTextureUsageConstants.RENDER_ATTACHMENT], 7 | ["storageBinding", WebGPUTextureUsageConstants.STORAGE_BINDING], 8 | ["textureBinding", WebGPUTextureUsageConstants.TEXTURE_BINDING] 9 | ]); 10 | const getTextureUsages = (usages = []) => { 11 | return usages.reduce((acc, v) => { 12 | return acc | textureUsages.get(v); 13 | }, 0); 14 | }; 15 | const getDefaultTextureUsage = (usages = [], textureType) => { 16 | if (usages.length) { 17 | return getTextureUsages(usages); 18 | } 19 | return textureType !== "storage" ? GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT : GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST; 20 | }; 21 | const getDefaultMediaTextureUsage = (usages = []) => { 22 | return getDefaultTextureUsage(usages, "texture"); 23 | }; 24 | const getNumMipLevels = (...sizes) => { 25 | const maxSize = Math.max(...sizes); 26 | return 1 + Math.log2(maxSize) | 0; 27 | }; 28 | 29 | export { getDefaultMediaTextureUsage, getDefaultTextureUsage, getNumMipLevels, getTextureUsages }; 30 | -------------------------------------------------------------------------------- /dist/esm/math/color-utils.mjs: -------------------------------------------------------------------------------- 1 | import { Vec3 } from './Vec3.mjs'; 2 | 3 | function sRGBToLinearFloat(c) { 4 | return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4); 5 | } 6 | function linearTosRGBFloat(c) { 7 | return c < 31308e-7 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055; 8 | } 9 | function sRGBToLinear(vector = new Vec3()) { 10 | vector.x = sRGBToLinearFloat(vector.x); 11 | vector.y = sRGBToLinearFloat(vector.y); 12 | vector.z = sRGBToLinearFloat(vector.z); 13 | return vector; 14 | } 15 | function linearTosRGB(vector = new Vec3()) { 16 | vector.x = linearTosRGBFloat(vector.x); 17 | vector.y = linearTosRGBFloat(vector.y); 18 | vector.z = linearTosRGBFloat(vector.z); 19 | return vector; 20 | } 21 | 22 | export { linearTosRGB, linearTosRGBFloat, sRGBToLinear, sRGBToLinearFloat }; 23 | -------------------------------------------------------------------------------- /dist/esm/utils/utils.mjs: -------------------------------------------------------------------------------- 1 | const generateUUID = () => { 2 | return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { 3 | const r = Math.random() * 16 | 0, v = c === "x" ? r : r & 3 | 8; 4 | return v.toString(16).toUpperCase(); 5 | }); 6 | }; 7 | const toCamelCase = (string) => { 8 | return string.replace(/(?:^\w|[A-Z]|\b\w)/g, (ltr, idx) => idx === 0 ? ltr.toLowerCase() : ltr.toUpperCase()).replace(/\s+/g, ""); 9 | }; 10 | const toKebabCase = (string) => { 11 | const camelCase = toCamelCase(string); 12 | return camelCase.charAt(0).toUpperCase() + camelCase.slice(1); 13 | }; 14 | let warningThrown = 0; 15 | const throwWarning = (warning) => { 16 | if (warningThrown > 100) { 17 | return; 18 | } else if (warningThrown === 100) { 19 | console.warn("GPUCurtains: too many warnings thrown, stop logging."); 20 | } else { 21 | console.warn(warning); 22 | } 23 | warningThrown++; 24 | }; 25 | const throwError = (error) => { 26 | throw new Error(error); 27 | }; 28 | 29 | export { generateUUID, throwError, throwWarning, toCamelCase, toKebabCase }; 30 | -------------------------------------------------------------------------------- /dist/esm/utils/webgpu-constants.mjs: -------------------------------------------------------------------------------- 1 | const WebGPUShaderStageConstants = typeof GPUShaderStage !== "undefined" ? GPUShaderStage : { 2 | VERTEX: 1, 3 | FRAGMENT: 2, 4 | COMPUTE: 4 5 | }; 6 | const WebGPUBufferUsageConstants = typeof GPUBufferUsage !== "undefined" ? GPUBufferUsage : { 7 | MAP_READ: 1, 8 | MAP_WRITE: 2, 9 | COPY_SRC: 4, 10 | COPY_DST: 8, 11 | INDEX: 16, 12 | VERTEX: 32, 13 | UNIFORM: 64, 14 | STORAGE: 128, 15 | INDIRECT: 256, 16 | QUERY_RESOLVE: 512 17 | }; 18 | const WebGPUTextureUsageConstants = typeof GPUTextureUsage !== "undefined" ? GPUTextureUsage : { 19 | COPY_SRC: 1, 20 | COPY_DST: 2, 21 | TEXTURE_BINDING: 4, 22 | STORAGE_BINDING: 8, 23 | RENDER_ATTACHMENT: 16 24 | }; 25 | 26 | export { WebGPUBufferUsageConstants, WebGPUShaderStageConstants, WebGPUTextureUsageConstants }; 27 | -------------------------------------------------------------------------------- /dist/types/core/buffers/utils.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { BufferBindingType } from '../bindings/Binding'; 3 | /** Defines all kinds of allowed buffer usages as camel case strings. */ 4 | export type BufferUsageKeys = 'copySrc' | 'copyDst' | 'index' | 'indirect' | 'mapRead' | 'mapWrite' | 'queryResolve' | 'vertex' | BufferBindingType; 5 | /** 6 | * Get the corresponding {@link !GPUBuffer.usage | GPUBufferUsageFlags} based on an array of {@link BufferUsageKeys | buffer usage names}. 7 | * @param usages - array of {@link BufferUsageKeys | buffer usage names}. 8 | * @returns - corresponding {@link !GPUBuffer.usage | GPUBufferUsageFlags}. 9 | */ 10 | export declare const getBufferUsages: (usages?: BufferUsageKeys[]) => GPUBufferUsageFlags; 11 | -------------------------------------------------------------------------------- /dist/types/core/lights/AmbientLight.d.ts: -------------------------------------------------------------------------------- 1 | import { Light, LightBaseParams } from './Light'; 2 | import { CameraRenderer } from '../renderers/utils'; 3 | import { GPUCurtains } from '../../curtains/GPUCurtains'; 4 | /** 5 | * Create an ambient light that equally illuminates all objects in the scene. 6 | * 7 | * This light cannot cast shadows. 8 | * 9 | * @example 10 | * ```javascript 11 | * // assuming 'renderer' is a valid Camera renderer 12 | * const ambientLight = new AmbientLight(renderer, { 13 | * color: new Vec3(1), 14 | * intensity: 0.1, 15 | * }) 16 | * ``` 17 | */ 18 | export declare class AmbientLight extends Light { 19 | /** 20 | * AmbientLight constructor 21 | * @param renderer - {@link CameraRenderer} or {@link GPUCurtains} used to create this {@link AmbientLight}. 22 | * @param parameters - {@link LightBaseParams} used to create this {@link AmbientLight}. 23 | */ 24 | constructor(renderer: CameraRenderer | GPUCurtains, { label, color, intensity }?: LightBaseParams); 25 | /** @ignore */ 26 | applyPosition(): void; 27 | } 28 | -------------------------------------------------------------------------------- /dist/types/core/materials/utils.d.ts: -------------------------------------------------------------------------------- 1 | import { RenderMaterialRenderingOptions } from '../../types/Materials'; 2 | /** 3 | * Compare two sets of {@link RenderMaterialRenderingOptions | rendering options} and returns an array of different options keys if any. 4 | * @param newOptions - Rendering new options to compare. 5 | * @param baseOptions - Rendering options to compare with. 6 | * @returns - An array with the options keys that differ, if any. 7 | */ 8 | export declare const compareRenderingOptions: (newOptions?: Partial, baseOptions?: Partial) => Array; 9 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/apply-directional-shadows.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to apply a given {@link core/lights/DirectionalLight.DirectionalLight | DirectionalLight} shadow to its light contribution. */ 2 | export declare const applyDirectionalShadows: string; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/apply-point-shadows.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to apply a given {@link core/lights/PointLight.PointLight | PointLight} shadow to its light contribution. */ 2 | export declare const applyPointShadows: string; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/apply-spot-shadows.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to apply a given {@link core/lights/SpotLight.SpotLight | SpotLight} shadow to its light contribution. */ 2 | export declare const applySpotShadows: string; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/apply-tone-mapping.d.ts: -------------------------------------------------------------------------------- 1 | import { ToneMappings } from '../../../../../extras/meshes/LitMesh'; 2 | /** 3 | * Apply the corresponding tone mapping to our `outputColor` (`vec4f`). 4 | * @param parameters - Parameters to use for applying tone mapping. 5 | * @param parameters.toneMapping - {@link ToneMappings} to apply if any. Default to `'Khronos'`. 6 | */ 7 | export declare const applyToneMapping: ({ toneMapping }?: { 8 | toneMapping?: ToneMappings; 9 | }) => string; 10 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/declare-attributes-vars.d.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry'; 2 | import { VertexShaderInputParams } from '../../../full/vertex/get-vertex-shader-code'; 3 | /** 4 | * Declare all the parameters coming from the fragment shader input struct. Used to declare mandatories `fragmentPosition` (`vec4f`), `frontFacing` (`bool`), `normal` (`vec3f`), `worldPosition` (`vec3f`), `viewDirection` (`vec3f`) and `modelScale` (`vec3f`) passed by the vertex shader, as well as optionals `tangent` (`vec3f`), `bitangent` (`vec3f`) and UV coordinates (`vec2f`). Eventual vertex colors will be handled by the `get-base-color` chunk. 5 | * @param parameters - Parameters used to declare the attributes variables. 6 | * @param parameters.geometry - {@link Geometry} used to declare the attributes variables. 7 | * @param parameters.additionalVaryings - Optional additional {@link VertexShaderInputParams.additionalVaryings | varyings} passed from the vertex shader to the fragment shader to declare. 8 | * @returns - A string with all the attributes variables declared. 9 | */ 10 | export declare const declareAttributesVars: ({ geometry, additionalVaryings, }: { 11 | geometry?: Geometry; 12 | additionalVaryings?: VertexShaderInputParams['additionalVaryings']; 13 | }) => string; 14 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-IBL-GGX-Fresnel.d.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from '../../../full/fragment/get-fragment-shader-code'; 2 | /** 3 | * Get the environment map IBL GGX Fresnel from the environment map LUT Texture, used for multi-scattering. 4 | * @param parameters - Parameters to use to apply PBR shading. 5 | * @param parameters.environmentMap - {@link extras/environmentMap/EnvironmentMap.EnvironmentMap | EnvironmentMap} to use for IBL GGX Fresnel any. 6 | * @returns - String with IBL GGX Fresnel applied to `iBLGGXFresnel` (`IBLGGXFresnel`). 7 | */ 8 | export declare const getIBLGGXFresnel: ({ environmentMap, }: { 9 | environmentMap?: PBRFragmentShaderInputParams['environmentMap']; 10 | }) => string; 11 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-IBL-indirect-irradiance.d.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from '../../../full/fragment/get-fragment-shader-code'; 2 | /** 3 | * Get the environment map indirect irradiance (diffuse). 4 | * @param parameters - Parameters to use to apply PBR shading. 5 | * @param parameters.environmentMap - {@link extras/environmentMap/EnvironmentMap.EnvironmentMap | EnvironmentMap} to use for indirect irradiance if any. 6 | * @returns - String with environment map indirect irradiance applied to `iblIrradiance` (`vec3f`). 7 | */ 8 | export declare const getIBLIndirectIrradiance: ({ environmentMap, }: { 9 | environmentMap?: PBRFragmentShaderInputParams['environmentMap']; 10 | }) => string; 11 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-IBL-indirect-radiance.d.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from '../../../full/fragment/get-fragment-shader-code'; 2 | /** 3 | * Get the environment map indirect radiance (specular). 4 | * @param parameters - Parameters to use to apply PBR shading. 5 | * @param parameters.environmentMap - {@link extras/environmentMap/EnvironmentMap.EnvironmentMap | EnvironmentMap} to use for indirect radiance if any. 6 | * @returns - String with environment map indirect radiance applied to `radiance` (`vec3f`). 7 | */ 8 | export declare const getIBLIndirectRadiance: ({ environmentMap, }: { 9 | environmentMap?: PBRFragmentShaderInputParams['environmentMap']; 10 | }) => string; 11 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-IBL-volume-refraction.d.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from '../../../full/fragment/get-fragment-shader-code'; 2 | import { ShaderTextureDescriptor } from '../../../../../extras/meshes/LitMesh'; 3 | /** 4 | * Apply transmission volume refraction to `totalDiffuse` light component if applicable. 5 | * @param parameters - Parameters to use to apply transmission volume refraction. 6 | * @param parameters.transmissionBackgroundTexture - {@link ShaderTextureDescriptor | Transmission background texture descriptor} to use for transmission if any. 7 | * @param parameters.extensionsUsed - {@link types/gltf/GLTFExtensions.GLTFExtensionsUsed | glTF extensions used} by the material for specifing shading if any. 8 | * @returns - A string with transmission volume refraction applied to `totalDiffuse` light component. 9 | */ 10 | export declare const getIBLVolumeRefraction: ({ transmissionBackgroundTexture, extensionsUsed, }: { 11 | transmissionBackgroundTexture?: ShaderTextureDescriptor; 12 | extensionsUsed?: PBRFragmentShaderInputParams['extensionsUsed']; 13 | }) => string; 14 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-PBR-shading.d.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from '../../../full/fragment/get-fragment-shader-code'; 2 | import { ShaderTextureDescriptor } from '../../../../../extras/meshes/LitMesh'; 3 | /** 4 | * Set the `outgoingLight` (`vec3f`) using PBR shading. 5 | * @param parameters - Parameters to use to apply PBR shading. 6 | * @param parameters.receiveShadows - Whether the shading function should account for current shadows. Default to `false`. 7 | * @param parameters.environmentMap - {@link extras/environmentMap/EnvironmentMap.EnvironmentMap | EnvironmentMap} to use for IBL shading if any. 8 | * @param parameters.transmissionBackgroundTexture - {@link ShaderTextureDescriptor | Transmission background texture descriptor} to use for transmission if any. 9 | * @param parameters.extensionsUsed - {@link types/gltf/GLTFExtensions.GLTFExtensionsUsed | glTF extensions used} by the material for specifing shading if any. 10 | * @returns - A string with PBR shading applied to `outgoingLight`. 11 | */ 12 | export declare const getPBRShading: ({ receiveShadows, environmentMap, transmissionBackgroundTexture, extensionsUsed, }?: { 13 | receiveShadows?: boolean; 14 | environmentMap?: PBRFragmentShaderInputParams['environmentMap']; 15 | transmissionBackgroundTexture?: ShaderTextureDescriptor; 16 | extensionsUsed?: PBRFragmentShaderInputParams['extensionsUsed']; 17 | }) => string; 18 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-PCF-shadows.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to get the PCF soft shadow generated by all the {@link core/lights/DirectionalLight.DirectionalLight | DirectionalLight}, {@link core/lights/PointLight.PointLight | PointLight} and {@link core/lights/SpotLight.SpotLight | SpotLight}. */ 2 | export declare const getPCFShadows: string; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-base-color.d.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry'; 2 | import { ShaderTextureDescriptor } from '../../../../../extras/meshes/LitMesh'; 3 | /** 4 | * Get the base color from the `material` binding `baseColorFactor` value, {@link Geometry} colors attributes if any and `baseColorTexture` if any, and apply it to our `outputColor`. Can also discard fragments based on `material` binding `alphaCutoff` value. 5 | * {@link https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-material-pbrmetallicroughness | See glTF PBR metallic roughness} definition and default values. 6 | * @param parameters - Parameters to use to set the base color. 7 | * @param parameters.geometry - {@link Geometry} to use to check for colors attributes. 8 | * @param parameters.baseColorTexture - {@link ShaderTextureDescriptor | Base color texture descriptor} to use if any. 9 | * @returns - A string with base color applied to `outputColor`. 10 | */ 11 | export declare const getBaseColor: ({ geometry, baseColorTexture, }?: { 12 | geometry?: Geometry; 13 | baseColorTexture?: ShaderTextureDescriptor; 14 | }) => string; 15 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-emissive-occlusion.d.ts: -------------------------------------------------------------------------------- 1 | import { ShaderTextureDescriptor } from '../../../../../extras/meshes/LitMesh'; 2 | /** 3 | * Set the `emissive` (`vec3f`) and `occlusion` (`f32`) values to use in our shader. 4 | * @param parameters - Parameters to use to set the emissive and occlusion values. 5 | * @param parameters.emissiveTexture - {@link ShaderTextureDescriptor | Emissive texture descriptor} to use if any. 6 | * @param parameters.occlusionTexture - {@link ShaderTextureDescriptor | Occlusion texture descriptor} to use if any. 7 | * @returns - A string with `emissive` (`vec3f`) and `occlusion` (`f32`) values set. 8 | */ 9 | export declare const getEmissiveOcclusion: ({ emissiveTexture, occlusionTexture, }?: { 10 | emissiveTexture?: ShaderTextureDescriptor; 11 | occlusionTexture?: ShaderTextureDescriptor; 12 | }) => string; 13 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-lambert-shading.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Set the `outgoingLight` (`vec3f`) using Lambert shading. 3 | * @param parameters - Parameters to use to apply Lambert shading. 4 | * @param parameters.receiveShadows - Whether the shading function should account for current shadows. Default to `false`. 5 | * @returns - A string with Lambert shading applied to `outgoingLight`. 6 | */ 7 | export declare const getLambertShading: ({ receiveShadows }?: { 8 | receiveShadows?: boolean; 9 | }) => string; 10 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-metallic-roughness.d.ts: -------------------------------------------------------------------------------- 1 | import { ShaderTextureDescriptor } from '../../../../../extras/meshes/LitMesh'; 2 | /** 3 | * Set the `metallic` (`f32`) and `roughness` (`f32`) values using the `material` binding `metallicFactor`, `roughnessFactor` values and the metallic roughness texture if any. 4 | * @param parameters - Parameters used to create the chunk. 5 | * @param parameters.metallicRoughnessTexture - {@link ShaderTextureDescriptor | Metallic roughness texture descriptor} to use if any. 6 | * @returns - A string with the `metallic` (`f32`) and `roughness` (`f32`) values set. 7 | */ 8 | export declare const getMetallicRoughness: ({ metallicRoughnessTexture, }?: { 9 | metallicRoughnessTexture?: ShaderTextureDescriptor; 10 | }) => string; 11 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-normal-tangent-bitangent.d.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry'; 2 | import { ShaderTextureDescriptor } from '../../../../../extras/meshes/LitMesh'; 3 | /** 4 | * Set the `normal` (`vec3f`), `geometryNormal` (`vec3f`), and eventually `tangent` (`vec3f`) and `bitangent` (`vec3f`) values if a normal texture is set. 5 | * 6 | * Tangent and bitangent are calculated using derivatives if the {@link Geometry} `tangent` and `bitangent` attributes are missing. 7 | * @param parameters - Parameters used to create the shader chunk. 8 | * @param parameters.geometry - {@link Geometry} to use to check for `tangent` and `bitangent` attributes. 9 | * @param parameters.normalTexture - {@link ShaderTextureDescriptor | Normal texture descriptor} to use if any. 10 | * @returns - A string with the `normal` (`vec3f`), `geometryNormal` (`vec3f`), `tangent` (`vec3f`) and `bitangent` (`vec3f`) values set. 11 | */ 12 | export declare const getNormalTangentBitangent: ({ geometry, normalTexture, }?: { 13 | geometry?: Geometry; 14 | normalTexture?: ShaderTextureDescriptor; 15 | }) => string; 16 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-pbr-shading.d.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from '../../../full/fragment/get-fragment-shader-code'; 2 | import { ShaderTextureDescriptor } from '../../../../../extras/meshes/LitMesh'; 3 | /** 4 | * Set the `outgoingLight` (`vec3f`) using PBR shading. 5 | * @param parameters - Parameters to use to apply PBR shading. 6 | * @param parameters.receiveShadows - Whether the shading function should account for current shadows. Default to `false`. 7 | * @param parameters.environmentMap - {@link extras/environmentMap/EnvironmentMap.EnvironmentMap | EnvironmentMap} to use for IBL shading if any. 8 | * @param parameters.transmissionBackgroundTexture - {@link ShaderTextureDescriptor | Transmission background texture descriptor} to use for transmission if any. 9 | * @param parameters.extensionsUsed - {@link types/gltf/GLTFExtensions.GLTFExtensionsUsed | glTF extensions used} by the material for specifing shading if any. 10 | * @returns - A string with PBR shading applied to `outgoingLight`. 11 | */ 12 | export declare const getPBRShading: ({ receiveShadows, environmentMap, transmissionBackgroundTexture, extensionsUsed, }?: { 13 | receiveShadows?: boolean; 14 | environmentMap?: PBRFragmentShaderInputParams['environmentMap']; 15 | transmissionBackgroundTexture?: ShaderTextureDescriptor; 16 | extensionsUsed?: PBRFragmentShaderInputParams['extensionsUsed']; 17 | }) => string; 18 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-phong-shading.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Set the `outgoingLight` (`vec3f`) using Phong shading. 3 | * @param parameters - Parameters to use to apply Phong shading. 4 | * @param parameters.receiveShadows - Whether the shading function should account for current shadows. Default to `false`. 5 | * @returns - A string with Phong shading applied to `outgoingLight`. 6 | */ 7 | export declare const getPhongShading: ({ receiveShadows }?: { 8 | receiveShadows?: boolean; 9 | }) => string; 10 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-specular.d.ts: -------------------------------------------------------------------------------- 1 | import { ShaderTextureDescriptor } from '../../../../../extras/meshes/LitMesh'; 2 | /** 3 | * Set the `specularFactor` (`f32`) and `specularColorFactor` (`vec3f`) values from the material specular variables and eventual specular textures. 4 | * @param parameters - Parameters used to set the `specularFactor` (`f32`) and `specularColorFactor` (`vec3f`) values. 5 | * @param parameters.specularTexture - {@link ShaderTextureDescriptor | Specular texture descriptor} (mixing both specular color in the `RGB` channels and specular intensity in the `A` channel) to use if any. 6 | * @param parameters.specularFactorTexture - {@link ShaderTextureDescriptor | Specular intensity texture descriptor} (using the `A` channel) to use if any. 7 | * @param parameters.specularColorTexture - {@link ShaderTextureDescriptor | Specular color texture descriptor} (using the `RGB` channels) to use if any. 8 | * @returns - String with the `specularFactor` (`f32`) and `specularColorFactor` (`vec3f`) values set. 9 | */ 10 | export declare const getSpecular: ({ specularTexture, specularFactorTexture, specularColorTexture, }?: { 11 | specularTexture?: ShaderTextureDescriptor; 12 | specularFactorTexture?: ShaderTextureDescriptor; 13 | specularColorTexture?: ShaderTextureDescriptor; 14 | }) => string; 15 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/body/get-transmission-thickness.d.ts: -------------------------------------------------------------------------------- 1 | import { ShaderTextureDescriptor } from '../../../../../extras/meshes/LitMesh'; 2 | /** 3 | * Set the `transmission` (`f32`) and `thickness` (`f32`) values from the material variables and eventual textures. 4 | * @param parameters - Parameters used to set the `transmission` (`f32`) and `thickness` (`f32`) values 5 | * @param parameters.transmissionTexture - {@link ShaderTextureDescriptor | Transmission texture descriptor} to use if any. 6 | * @param parameters.thicknessTexture - {@link ShaderTextureDescriptor | Thickness texture descriptor} to use if any. 7 | * @returns - String with the `transmission` (`f32`) and `thickness` (`f32`) values set. 8 | */ 9 | export declare const getTransmissionThickness: ({ transmissionTexture, thicknessTexture, }?: { 10 | transmissionTexture?: ShaderTextureDescriptor; 11 | thicknessTexture?: ShaderTextureDescriptor; 12 | }) => string; 13 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/RE-indirect-diffuse.d.ts: -------------------------------------------------------------------------------- 1 | /** WGSL functions to calculate the indirect diffuse contribution of lights. */ 2 | export declare const REIndirectDiffuse = "\nfn getIndirectDiffuse(irradiance: vec3f, diffuseColor: vec3f, ptr_reflectedLight: ptr) {\n (*ptr_reflectedLight).indirectDiffuse += irradiance * BRDF_Lambert( diffuseColor );\n}\n\n// Indirect Diffuse RenderEquations\nfn RE_IndirectDiffuse(irradiance: vec3f, diffuseColor: vec3f, ptr_reflectedLight: ptr) {\n var totalAmbientIrradiance: vec3f = irradiance;\n \n for(var i: i32 = 0; i < ambientLights.count; i++) {\n totalAmbientIrradiance += ambientLights.color[i];\n }\n \n getIndirectDiffuse(totalAmbientIrradiance, diffuseColor, ptr_reflectedLight);\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/RE-indirect-specular.d.ts: -------------------------------------------------------------------------------- 1 | /** WGSL functions to calculate the indirect specular and diffuse contributions of lights using multi-scattering. */ 2 | export declare const REIndirectSpecular = "\n// Indirect Specular RenderEquations\nfn RE_IndirectSpecular(\n radiance: vec3f,\n irradiance: vec3f,\n normal: vec3f,\n diffuseColor: vec3f,\n specularFactor: f32,\n specularColorFactor: vec3f,\n viewDirection: vec3f,\n metallic: f32,\n roughness: f32,\n iBLGGXFresnel: IBLGGXFresnel,\n ptr_reflectedLight: ptr\n) {\n let k_D: vec3f = diffuseColor * (1.0 - iBLGGXFresnel.FssEss + iBLGGXFresnel.FmsEms);\n\n // we just add radiance and irradiance to the indirect contributions using iBLGGXFresnel\n // we might need to adjust when implementing clearcoat, sheen or iridescence\n\n // we remove RECIPROCAL_PI multiplication since the LUT already ensures energy conservation\n let cosineWeightedIrradiance: vec3f = irradiance;\n // let cosineWeightedIrradiance: vec3f = irradiance * RECIPROCAL_PI; \n\n (*ptr_reflectedLight).indirectSpecular += iBLGGXFresnel.FssEss * radiance;\n (*ptr_reflectedLight).indirectSpecular += iBLGGXFresnel.FmsEms * cosineWeightedIrradiance;\n \n (*ptr_reflectedLight).indirectDiffuse += k_D * cosineWeightedIrradiance;\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-IBL-indirect-irradiance.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper function chunk appended internally and used to compute the indirect irradiance based on environment diffuse map. */ 2 | export declare const getIBLIndirectIrradiance = "\nfn getIBLIndirectIrradiance(\n normal: vec3f,\n diffuseColor: vec3f,\n clampSampler: sampler,\n envDiffuseTexture: texture_cube,\n envRotation: mat3x3f,\n envDiffuseIntensity: f32,\n) -> vec3f {\n // IBL diffuse (irradiance)\n let diffuseLight: vec4f = textureSample(\n envDiffuseTexture,\n clampSampler,\n normal * envRotation\n );\n\n return diffuseLight.rgb * envDiffuseIntensity;\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-IBL-indirect-radiance.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper function chunk appended internally and used to compute IBL indirect radiance, based on environment specular map. */ 2 | export declare const getIBLIndirectRadiance = "\nfn getIBLIndirectRadiance(\n normal: vec3f,\n viewDirection: vec3f,\n roughness: f32,\n specularColor: vec3f,\n specularFactor: f32,\n iBLGGXFresnel: IBLGGXFresnel,\n clampSampler: sampler,\n envSpecularTexture: texture_cube,\n envRotation: mat3x3f,\n envSpecularIntensity: f32,\n)-> vec3f {\n let N: vec3f = normal;\n let V: vec3f = viewDirection;\n let NdotV: f32 = saturate(dot(N, V));\n\n let reflection: vec3f = normalize(reflect(-V, N));\n\n let lod: f32 = roughness * f32(textureNumLevels(envSpecularTexture) - 1);\n\n let specularLight: vec4f = textureSampleLevel(\n envSpecularTexture,\n clampSampler,\n reflection * envRotation,\n lod\n );\n\n return specularLight.rgb * envSpecularIntensity;\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-PBR-direct.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper function chunk appended internally and used to compute PBR direct light contributions. */ 2 | export declare const getPBRDirect: string; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-PCF-directional-shadow-contribution.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to get the PCF soft shadow generated by a given {@link core/lights/DirectionalLight.DirectionalLight | DirectionalLight}. */ 2 | export declare const getPCFDirectionalShadowContribution: string; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-PCF-directional-shadows.d.ts: -------------------------------------------------------------------------------- 1 | import { CameraRenderer } from '../../../../renderers/utils'; 2 | /** 3 | * Get the global PCF soft shadows contributions from all the current {@link CameraRenderer} {@link DirectionalLight}. 4 | * @param renderer - {@link CameraRenderer} used by the {@link DirectionalLight}. 5 | */ 6 | export declare const getPCFDirectionalShadows: (renderer: CameraRenderer) => string; 7 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-PCF-point-shadow-contribution.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to get the PCF soft shadow generated by a given {@link core/lights/PointLight.PointLight | PointLight}. */ 2 | export declare const getPCFPointShadowContribution: string; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-PCF-point-shadows.d.ts: -------------------------------------------------------------------------------- 1 | import { CameraRenderer } from '../../../../renderers/utils'; 2 | /** 3 | * Get the global PCF soft shadows contributions from all the current {@link CameraRenderer} {@link PointLight}. 4 | * @param renderer - {@link CameraRenderer} used by the {@link PointLight}. 5 | */ 6 | export declare const getPCFPointShadows: (renderer: CameraRenderer) => string; 7 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-PCF-spot-shadow-contribution.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to get the PCF soft shadow generated by a given {@link core/lights/SpotLight.SpotLight | SpotLight}. */ 2 | export declare const getPCFSpotShadowContribution: string; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-PCF-spot-shadows.d.ts: -------------------------------------------------------------------------------- 1 | import { CameraRenderer } from '../../../../renderers/utils'; 2 | /** 3 | * Get the global PCF soft shadows contributions from all the current {@link CameraRenderer} {@link SpotLight}. 4 | * @param renderer - {@link CameraRenderer} used by the {@link SpotLight}. 5 | */ 6 | export declare const getPCFSpotShadows: (renderer: CameraRenderer) => string; 7 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-fragment-input-struct.d.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry'; 2 | import { VertexShaderInputParams } from '../../../full/vertex/get-vertex-shader-code'; 3 | /** 4 | * Get the fragment shader WGSL input struct using {@link getVertexOutputStructContent}. 5 | * @param parameters - Parameters used to generate the fragment shader WGSL input struct. 6 | * @param parameters.geometry - {@link Geometry} used to generate the struct from its attributes. 7 | * @param parameters.additionalVaryings - Optional additional {@link VertexShaderInputParams.additionalVaryings | varyings} passed from the vertex shader to the fragment shader. 8 | * @returns - String with the fragment shader WGSL input struct. 9 | */ 10 | export declare const getFragmentInputStruct: ({ geometry, additionalVaryings, }: { 11 | geometry: Geometry; 12 | additionalVaryings?: VertexShaderInputParams['additionalVaryings']; 13 | }) => string; 14 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-lambert-direct.d.ts: -------------------------------------------------------------------------------- 1 | /** Helper function chunk appended internally and used to compute Lambert direct light contributions. */ 2 | export declare const getLambertDirect = "\nfn getLambertDirect(\n normal: vec3f,\n diffuseColor: vec3f,\n directLight: DirectLight,\n ptr_reflectedLight: ptr\n) {\n let NdotL = saturate(dot(normal, directLight.direction));\n \n let irradiance: vec3f = NdotL * directLight.color;\n (*ptr_reflectedLight).directDiffuse += irradiance * BRDF_Lambert( diffuseColor );\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-uv-cover-helper.d.ts: -------------------------------------------------------------------------------- 1 | /** Applies given texture matrix (`mat4x4f`) to given uv coordinates (`vec2f`). */ 2 | export declare const getUVCover = "\nfn getUVCover(uv: vec2f, textureMatrix: mat3x3f) -> vec2f {\n return (textureMatrix * vec3f(uv, 1.0)).xy;\n}"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/fragment/head/get-vertex-to-UV-coords-helpers.d.ts: -------------------------------------------------------------------------------- 1 | /** Convert vertex position as `vec2f` or `vec3f` to uv coordinates `vec2f`. */ 2 | export declare const getVertexToUVCoords = "\nfn getVertex2DToUVCoords(vertex: vec2f) -> vec2f {\n return vec2(\n vertex.x * 0.5 + 0.5,\n 0.5 - vertex.y * 0.5\n );\n}\n\nfn getVertex3DToUVCoords(vertex: vec3f) -> vec2f {\n return getVertex2DToUVCoords( vec2(vertex.x, vertex.y) );\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/shading/phong-shading.d.ts: -------------------------------------------------------------------------------- 1 | import { GetShadingParams } from './lambert-shading'; 2 | /** 3 | * Shader chunk to add to the head of a fragment shader to be able to use Phong shading. 4 | * @param parameters - {@link GetShadingParams | parameters} used to append the right chunks and calculate the Phong shading. 5 | * 6 | * @example 7 | * ```wgsl 8 | * var color: vec4f = vec3(1.0); 9 | * let specularColor: vec3f = vec3(1.0); 10 | * let specularIntensity: f32 = 1.0; 11 | * let shininess: f32 = 30.0; 12 | * 13 | * color = getPhong(normal, worldPosition, color, viewDirection, specularIntensity, specularColor, shininess); 14 | * ``` 15 | */ 16 | export declare const getPhong: ({ addUtils, receiveShadows, toneMapping, useOcclusion }?: GetShadingParams) => string; 17 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/utils/BRDF_GGX.d.ts: -------------------------------------------------------------------------------- 1 | /** WGSL BRDF GGX functions. Need the `constants` and `common` chunks. */ 2 | export declare const BRDF_GGX = "\nfn DistributionGGX(NdotH: f32, roughness: f32) -> f32 {\n let a: f32 = pow2( roughness );\n let a2: f32 = pow2( a );\n\n let denom: f32 = (pow2( NdotH ) * (a2 - 1.0) + 1.0);\n\n return RECIPROCAL_PI * a2 / ( pow2( denom ) );\n}\n\nfn GeometrySmith(NdotL: f32, NdotV: f32, roughness: f32) -> f32 {\n let a: f32 = pow2( roughness );\n let a2: f32 = pow2( a );\n \n let gv: f32 = NdotL * sqrt( a2 + ( 1.0 - a2 ) * pow2( NdotV ) );\n let gl: f32 = NdotV * sqrt( a2 + ( 1.0 - a2 ) * pow2( NdotL ) );\n\n return 0.5 / max( gv + gl, EPSILON );\n}\n\nfn BRDF_GGX(\n NdotV: f32,\n NdotL: f32,\n NdotH: f32,\n VdotH: f32,\n roughness: f32,\n specularFactor: f32,\n specularColor: vec3f\n) -> vec3f {\n // cook-torrance brdf\n let G: f32 = GeometrySmith(NdotL, NdotV, roughness);\n let D: f32 = DistributionGGX(NdotH, roughness);\n let F: vec3f = F_Schlick(specularColor, specularFactor, VdotH);\n \n return G * D * F;\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/utils/common.d.ts: -------------------------------------------------------------------------------- 1 | /** Common WGSL functions and struct declarations to use for light shading. */ 2 | export declare const common = "\nfn lessThan3(a: vec3f, b: vec3f) -> vec3f {\n return vec3f(vec3(a.x < b.x, a.y < b.y, a.z < b.z));\n}\n\nfn pow2( x: f32 ) -> f32 {\n return x * x;\n}\n\nfn pow3( x: f32 ) -> f32 {\n return x * x * x;\n}\n\nfn pow4( x: f32 ) -> f32 {\n return pow2(x) * pow2(x);\n}\n\nfn isinf(value: f32) -> bool {\n return value > 1.0e38 || value < -1.0e38;\n}\n\nfn BRDF_Lambert(diffuseColor: vec3f) -> vec3f {\n return RECIPROCAL_PI * diffuseColor;\n}\n\nfn F_Schlick(f0: vec3f, f90: f32, VdotH: f32) -> vec3f {\n let fresnel: f32 = exp2( ( - 5.55473 * VdotH - 6.98316 ) * VdotH );\n return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/utils/constants.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants to use in shadings. 3 | */ 4 | export declare const constants: string; 5 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/utils/generate-TBN.d.ts: -------------------------------------------------------------------------------- 1 | /** WGSL function to generate a tangent bitangent normal coordinate frame from the normal. */ 2 | export declare const generateTBN = "\n// TBN generates a tangent bitangent normal coordinate frame from the normal\n// (the normal must be normalized)\nfn generateTBN(normal: vec3f) -> mat3x3f {\n var bitangent: vec3f = vec3(0.0, 1.0, 0.0);\n\n let NdotUp: f32 = dot(normal, vec3(0.0, 1.0, 0.0));\n \n if (1.0 - abs(NdotUp) <= EPSILON) {\n // Sampling +Y or -Y, so we need a more robust bitangent.\n if (NdotUp > 0.0) {\n bitangent = vec3(0.0, 0.0, 1.0);\n }\n else {\n bitangent = vec3(0.0, 0.0, -1.0);\n }\n }\n\n let tangent: vec3f = normalize(cross(bitangent, normal));\n bitangent = cross(normal, tangent);\n\n return mat3x3f(tangent, bitangent, normal);\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/utils/hammersley-2D.d.ts: -------------------------------------------------------------------------------- 1 | /** Hammersley 2D WGSL function. */ 2 | export declare const hammersley2D = "\nfn radicalInverse_VdC(inputBits: u32) -> f32 {\n var bits: u32 = inputBits;\n bits = (bits << 16u) | (bits >> 16u);\n bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);\n bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);\n bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);\n bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);\n return f32(bits) * 2.3283064365386963e-10; // / 0x100000000\n}\n\n// hammersley2d describes a sequence of points in the 2d unit square [0,1)^2\n// that can be used for quasi Monte Carlo integration\nfn hammersley2d(i: u32, N: u32) -> vec2f {\n return vec2(f32(i) / f32(N), radicalInverse_VdC(i));\n}\n"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/vertex/body/declare-attributes-vars.d.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry'; 2 | /** 3 | * Declare all the provided {@link Geometry} attributes as variables. 4 | * @param parameters - Parameters used to declare the attributes variables. 5 | * @param parameters.geometry - {@link Geometry} used to declare the attributes variables. 6 | * @returns - A string with all the attributes variables declared. 7 | */ 8 | export declare const declareAttributesVars: ({ geometry }: { 9 | geometry: Geometry; 10 | }) => string; 11 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/vertex/body/get-morph-targets.d.ts: -------------------------------------------------------------------------------- 1 | import { VertexShaderInputBaseParams } from '../../../full/vertex/get-vertex-shader-code'; 2 | /** 3 | * Compute the morphed targets transformations using the provided {@link core/geometries/Geometry.Geometry | Geometry} and {@link core/bindings/BufferBinding.BufferBinding | BufferBinding} array parameters if any. 4 | * @param parameters - {@link VertexShaderInputBaseParams} used to compute the morphed `worldPosition` and `normal` vectors if any morph target is defined in the {@link core/geometries/Geometry.Geometry | Geometry} attributes. 5 | * @returns - The part of the vertex shader where the moprhed target is applied. 6 | */ 7 | export declare const getMorphTargets: ({ bindings, geometry }: VertexShaderInputBaseParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/vertex/body/get-vertex-output.d.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry'; 2 | /** 3 | * Assign all the necessaries' vertex shader output variables. 4 | * @param parameters - Parameters used to assign the vertex shader output variables. 5 | * @param parameters.geometry - {@link Geometry} used to assign the vertex shader output variables. 6 | * @returns - A string with all the vertex shader output variables assigned. 7 | */ 8 | export declare const getVertexOutput: ({ geometry }: { 9 | geometry: Geometry; 10 | }) => string; 11 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/vertex/body/get-vertex-skinned-position-normal.d.ts: -------------------------------------------------------------------------------- 1 | import { VertexShaderInputBaseParams } from '../../../full/vertex/get-vertex-shader-code'; 2 | /** 3 | * Compute the skinning transformations using the provided {@link core/geometries/Geometry.Geometry | Geometry} and {@link core/bindings/BufferBinding.BufferBinding | BufferBinding} array parameters if any. 4 | * @param parameters - {@link VertexShaderInputBaseParams} used to compute the skinned `worldPosition` and `normal` vectors if any skinning is defined in the {@link core/geometries/Geometry.Geometry | Geometry} attributes. 5 | * @returns - The part of the vertex shader where the skinning is applied. 6 | */ 7 | export declare const getVertexSkinnedPositionNormal: ({ bindings, geometry }: VertexShaderInputBaseParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/vertex/body/get-vertex-transformed-position-normal.d.ts: -------------------------------------------------------------------------------- 1 | import { VertexShaderInputBaseParams } from '../../../full/vertex/get-vertex-shader-code'; 2 | /** 3 | * Generate the part of the vertex shader dedicated to compute the output transformed `worldPosition` and `normal` vectors. Account for instancing (using a {@link BufferBinding} with `instances` name if any), morph targets and skinning using the provided {@link core/geometries/Geometry.Geometry | Geometry} and {@link BufferBinding} array parameters. 4 | * 5 | * Used internally by the various {@link core/shadows/Shadow.Shadow | Shadow} classes and the {@link extras/gltf/GLTFScenesManager | GLTFScenesManager} class. 6 | * 7 | * @param parameters - {@link VertexShaderInputBaseParams} used to compute the output transformed `worldPosition` and `normal` vectors. 8 | * @returns - The part of the vertex shader dedicated to computing the output transformed `worldPosition` and `normal` vectors. 9 | */ 10 | export declare const getVertexTransformedPositionNormal: ({ bindings, geometry, }: VertexShaderInputBaseParams) => string; 11 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/vertex/head/get-normal-helpers.d.ts: -------------------------------------------------------------------------------- 1 | /** Get `normal` (`vec3f`) in world or view space. */ 2 | export declare const getNormalHelpers = "\nfn getWorldNormal(normal: vec3f) -> vec3f {\n return normalize(matrices.normal * normal);\n}\n\nfn getViewNormal(normal: vec3f) -> vec3f {\n return normalize((camera.view * vec4(matrices.normal * normal, 0.0)).xyz);\n}"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/vertex/head/get-position-helpers.d.ts: -------------------------------------------------------------------------------- 1 | /** Get output `position` (`vec4f`) vector by applying model view projection matrix to the attribute `position` (`vec3f`) vector. */ 2 | export declare const getPositionHelpers = "\nfn getWorldPosition(position: vec3f) -> vec4f {\n return matrices.model * vec4f(position, 1.0);\n}\n\nfn getOutputPosition(position: vec3f) -> vec4f {\n return camera.projection * camera.view * matrices.model * vec4f(position, 1.0);\n}"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/vertex/head/get-vertex-output-struct-content.d.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry'; 2 | import { VertexShaderInputParams } from '../../../full/vertex/get-vertex-shader-code'; 3 | /** 4 | * Get the vertex shader WGSL output struct content from the given {@link Geometry}. Pass all {@link Geometry} attributes, plus eventual `bitangent` (`vec3f`) if `tangent` attribute is defined, and `viewDirection` (`vec3f`), `worldPosition` (`vec3f`) and `modelScale` (`vec3f`). 5 | * @param parameters - Parameters used to generate the vertex shader WGSL output struct content. 6 | * @param parameters.geometry - {@link Geometry} used to generate the struct content from its attributes. 7 | * @param parameters.additionalVaryings - Optional additional {@link VertexShaderInputParams.additionalVaryings | varyings} to pass from the vertex shader to the fragment shader. 8 | * @returns - String with the vertex shader WGSL output struct content. 9 | */ 10 | export declare const getVertexOutputStructContent: ({ geometry, additionalVaryings, }: { 11 | geometry: Geometry; 12 | additionalVaryings?: VertexShaderInputParams['additionalVaryings']; 13 | }) => string; 14 | -------------------------------------------------------------------------------- /dist/types/core/shaders/chunks/vertex/head/get-vertex-output-struct.d.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry'; 2 | import { VertexShaderInputParams } from '../../../full/vertex/get-vertex-shader-code'; 3 | /** 4 | * Get the vertex shader WGSL output struct using {@link getVertexOutputStructContent}. 5 | * @param parameters - Parameters used to generate the vertex shader WGSL output struct. 6 | * @param parameters.geometry - {@link Geometry} used to generate the struct from its attributes. 7 | * @param parameters.additionalVaryings - Optional additional {@link VertexShaderInputParams.additionalVaryings | varyings} to pass from the vertex shader to the fragment shader. 8 | * @returns - String with the vertex shader WGSL output struct. 9 | */ 10 | export declare const getVertexOutputStruct: ({ geometry, additionalVaryings, }: { 11 | geometry: Geometry; 12 | additionalVaryings?: VertexShaderInputParams['additionalVaryings']; 13 | }) => string; 14 | -------------------------------------------------------------------------------- /dist/types/core/shaders/default-material-helpers.d.ts: -------------------------------------------------------------------------------- 1 | /** Additional WGSL chunks to add to the shaders. */ 2 | export interface AdditionalChunks { 3 | /** Additional WGSL chunk to add to the shader head. Useful for additional WGSL functions. */ 4 | additionalHead?: string; 5 | /** Preliminary modification to apply to the shader. 6 | * 7 | * For the vertex shader, it is called after the attributes variables declarations and before applying any morph, skinning or matrices calculations. 8 | * 9 | * For the fragment shader, it is called after the material and attributes variables declarations and before applying any lighting calculations. */ 10 | preliminaryContribution?: string; 11 | /** Additional modification to apply to the shader. 12 | * 13 | * For the vertex shader, it is called after having declared the outputted result and can therefore be used to update the outputted result. 14 | * 15 | * For the fragment shader, it is called after having applied the lighting calculations and before applying tone mapping if any. */ 16 | additionalContribution?: string; 17 | } 18 | /** 19 | * Patch {@link AdditionalChunks} in case they are missing. 20 | * @param chunks - Chunks to patch. 21 | */ 22 | export declare const patchAdditionalChunks: (chunks?: AdditionalChunks) => AdditionalChunks; 23 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/compute/compute-BRDF-LUT.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Compute a BRDF LUT (look up table) texture. 3 | */ 4 | export declare const computeBRDFLUT: string; 5 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/compute/compute-diffuse-from-specular-cubemap.d.ts: -------------------------------------------------------------------------------- 1 | import { Texture } from '../../../textures/Texture'; 2 | /** 3 | * Compute a diffuse cube map texture from a specular cube map {@link Texture}. 4 | * @param specularTexture - Specular cube map {@link Texture} to use. 5 | */ 6 | export declare const computeDiffuseFromSpecularCubemap: (specularTexture: Texture) => string; 7 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/compute/compute-specular-cubemap-from-HDR.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Compute a specular cube map texture from HDR image data. 3 | */ 4 | export declare const computeSpecularCubemapFromHDR: string; 5 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/fragment/get-PBR-fragment-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from './get-fragment-shader-code'; 2 | /** 3 | * Build a PBR fragment shader using the provided options. 4 | * @param parameters - {@link PBRFragmentShaderInputParams} used to build the PBR fragment shader. 5 | * @returns - The PBR fragment shader generated based on the provided parameters. 6 | */ 7 | export declare const getPBRFragmentShaderCode: ({ chunks, toneMapping, geometry, additionalVaryings, materialUniform, materialUniformName, extensionsUsed, receiveShadows, baseColorTexture, normalTexture, emissiveTexture, occlusionTexture, metallicRoughnessTexture, specularTexture, specularFactorTexture, specularColorTexture, transmissionTexture, thicknessTexture, transmissionBackgroundTexture, environmentMap, }: PBRFragmentShaderInputParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/fragment/get-default-fragment-code.d.ts: -------------------------------------------------------------------------------- 1 | /** Default fragment shader code that outputs only black pixels. */ 2 | export declare const getDefaultFragmentCode = "\n@fragment fn main() -> @location(0) vec4f {\n return vec4(0.0, 0.0, 0.0, 1.0);\n}"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/fragment/get-default-normal-fragment-code.d.ts: -------------------------------------------------------------------------------- 1 | /** Default fragment shader code that outputs mesh's normal. */ 2 | export declare const getDefaultNormalFragmentCode = "\nstruct VSOutput {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n @location(1) normal: vec3f,\n};\n\n@fragment fn main(fsInput: VSOutput) -> @location(0) vec4f {\n // normals\n return vec4(normalize(fsInput.normal) * 0.5 + 0.5, 1.0);\n}"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/fragment/get-default-point-shadow-depth-fragment-code.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Get {@link core/lights/PointLight.PointLight | PointLight} shadow map pass fragment shader. 3 | * @param lightIndex - Index of the {@link core/lights/PointLight.PointLight | PointLight} for which to render the depth pass. 4 | */ 5 | export declare const getDefaultPointShadowDepthFs: (lightIndex?: number) => string; 6 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/fragment/get-default-shader-pass-fragment-code.d.ts: -------------------------------------------------------------------------------- 1 | /** Default fragment shader code to use with {@link core/renderPasses/ShaderPass.ShaderPass | ShaderPass} that outputs the content of the pass `renderTexture` as is. */ 2 | export declare const getDefaultShaderPassFragmentCode = "\nstruct VSOutput {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n};\n\n@fragment fn main(fsInput: VSOutput) -> @location(0) vec4f {\n return textureSample(renderTexture, defaultSampler, fsInput.uv);\n}"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/fragment/get-lambert-fragment-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | import { LambertFragmentShaderInputParams } from './get-fragment-shader-code'; 2 | /** 3 | * Build a Lambert fragment shader using the provided options. 4 | * @param parameters - {@link LambertFragmentShaderInputParams} used to build the Lambert fragment shader. 5 | * @returns - The Lambert fragment shader generated based on the provided parameters. 6 | */ 7 | export declare const getLambertFragmentShaderCode: ({ chunks, toneMapping, geometry, additionalVaryings, materialUniform, materialUniformName, receiveShadows, baseColorTexture, normalTexture, emissiveTexture, occlusionTexture, }: LambertFragmentShaderInputParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/fragment/get-pbr-fragment-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from './get-fragment-shader-code'; 2 | /** 3 | * Build a PBR fragment shader using the provided options. 4 | * @param parameters - {@link PBRFragmentShaderInputParams} used to build the PBR fragment shader. 5 | * @returns - The PBR fragment shader generated based on the provided parameters. 6 | */ 7 | export declare const getPBRFragmentShaderCode: ({ chunks, toneMapping, geometry, additionalVaryings, materialUniform, materialUniformName, extensionsUsed, receiveShadows, baseColorTexture, normalTexture, emissiveTexture, occlusionTexture, metallicRoughnessTexture, specularTexture, specularFactorTexture, specularColorTexture, transmissionTexture, thicknessTexture, transmissionBackgroundTexture, environmentMap, }: PBRFragmentShaderInputParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/fragment/get-phong-fragment-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | import { PhongFragmentShaderInputParams } from './get-fragment-shader-code'; 2 | /** 3 | * Build a Phong fragment shader using the provided options. 4 | * @param parameters - {@link PhongFragmentShaderInputParams} used to build the Phong fragment shader. 5 | * @returns - The Phong fragment shader generated based on the provided parameters. 6 | */ 7 | export declare const getPhongFragmentShaderCode: ({ chunks, toneMapping, geometry, additionalVaryings, materialUniform, materialUniformName, receiveShadows, baseColorTexture, normalTexture, emissiveTexture, occlusionTexture, metallicRoughnessTexture, specularTexture, specularFactorTexture, specularColorTexture, }: PhongFragmentShaderInputParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/fragment/get-unlit-fragment-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | import { UnlitFragmentShaderInputParams } from './get-fragment-shader-code'; 2 | /** 3 | * Build an unlit fragment shader using the provided options. 4 | * @param parameters - {@link UnlitFragmentShaderInputParams} used to build the unlit fragment shader. 5 | * @returns - The unlit fragment shader generated based on the provided parameters. 6 | */ 7 | export declare const getUnlitFragmentShaderCode: ({ chunks, toneMapping, geometry, additionalVaryings, materialUniform, materialUniformName, baseColorTexture, }: UnlitFragmentShaderInputParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/vertex/get-default-directional-shadow-depth-vertex-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | import { VertexShaderInputBaseParams } from './get-vertex-shader-code'; 2 | /** 3 | * Get default ({@link core/lights/DirectionalLight.DirectionalLight | DirectionalLight}) shadow map pass vertex shader. 4 | * @param lightIndex - Index of the {@link core/lights/DirectionalLight.DirectionalLight | DirectionalLight} for which to render the depth pass. 5 | * @param parameters - {@link VertexShaderInputBaseParams} used to compute the output `worldPosition` and `normal` vectors. 6 | */ 7 | export declare const getDefaultDirectionalShadowDepthVs: (lightIndex: number, { bindings, geometry }: VertexShaderInputBaseParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/vertex/get-default-point-shadow-depth-vertex-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | import { VertexShaderInputParams } from './get-vertex-shader-code'; 2 | /** 3 | * Get {@link core/lights/PointLight.PointLight | PointLight} shadow map pass vertex shader. 4 | * @param lightIndex - Index of the {@link core/lights/PointLight.PointLight | PointLight} for which to render the depth pass. 5 | * @param parameters - {@link VertexShaderInputParams} used to compute the output `worldPosition` and `normal` vectors. 6 | */ 7 | export declare const getDefaultPointShadowDepthVs: (lightIndex: number, { bindings, geometry }: VertexShaderInputParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/vertex/get-default-projected-vertex-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | /** Default vertex shader code for projected meshes. */ 2 | export declare const getDefaultProjectedVertexShaderCode = "\nstruct VSOutput {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n @location(1) normal: vec3f,\n @location(2) worldPosition: vec3f,\n @location(3) viewDirection: vec3f,\n};\n\n@vertex fn main(\n attributes: Attributes,\n) -> VSOutput {\n var vsOutput: VSOutput;\n\n vsOutput.position = getOutputPosition(attributes.position);\n vsOutput.uv = attributes.uv;\n vsOutput.normal = getWorldNormal(attributes.normal);\n let worldPosition: vec4f = getWorldPosition(attributes.position);\n vsOutput.worldPosition = worldPosition.xyz / worldPosition.w;\n vsOutput.viewDirection = camera.position - vsOutput.worldPosition;\n \n return vsOutput;\n}"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/vertex/get-default-spot-shadow-depth-vertex-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | import { VertexShaderInputBaseParams } from './get-vertex-shader-code'; 2 | /** 3 | * Get default ({@link core/lights/SpotLight.SpotLight | SpotLight}) shadow map pass vertex shader. 4 | * @param lightIndex - Index of the {@link core/lights/SpotLight.SpotLight | SpotLight} for which to render the depth pass. 5 | * @param parameters - {@link VertexShaderInputBaseParams} used to compute the output `worldPosition` and `normal` vectors. 6 | */ 7 | export declare const getDefaultSpotShadowDepthVs: (lightIndex: number, { bindings, geometry }: VertexShaderInputBaseParams) => string; 8 | -------------------------------------------------------------------------------- /dist/types/core/shaders/full/vertex/get-default-vertex-shader-code.d.ts: -------------------------------------------------------------------------------- 1 | /** Default vertex shader code for unprojected meshes (such as {@link core/meshes/FullscreenPlane.FullscreenPlane | FullscreenPlane} or {@link core/renderPasses/ShaderPass.ShaderPass | ShaderPass}). */ 2 | export declare const getDefaultVertexShaderCode = "\nstruct VSOutput {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n};\n\n@vertex fn main(\n attributes: Attributes,\n) -> VSOutput {\n var vsOutput: VSOutput;\n\n vsOutput.position = vec4f(attributes.position, 1.0);\n vsOutput.uv = attributes.uv;\n \n return vsOutput;\n}"; 3 | -------------------------------------------------------------------------------- /dist/types/core/shaders/shader-chunks.d.ts: -------------------------------------------------------------------------------- 1 | import { RenderMaterialShadersType } from '../../types/Materials'; 2 | /** Defines {@link ShaderChunks} object structure */ 3 | export type ShaderChunks = Record>; 4 | /** Defines {@link ProjectedShaderChunks} object structure */ 5 | export type ProjectedShaderChunks = Record>; 6 | /** 7 | * Useful WGSL code chunks added to the vertex and/or fragment shaders 8 | */ 9 | export declare const shaderChunks: ShaderChunks; 10 | /** 11 | * Useful WGSL code chunks added to the projected Meshes vertex and/or fragment shaders 12 | */ 13 | export declare const ProjectedShaderChunks: ProjectedShaderChunks; 14 | -------------------------------------------------------------------------------- /dist/types/extras/geometries/BoxGeometry.d.ts: -------------------------------------------------------------------------------- 1 | import { IndexedGeometry } from '../../core/geometries/IndexedGeometry'; 2 | import { GeometryBaseParams } from '../../types/Geometries'; 3 | /** 4 | * Parameters used to create a {@link BoxGeometry} 5 | */ 6 | export interface BoxGeometryParams extends GeometryBaseParams { 7 | /** Number of segments along the X axis */ 8 | widthSegments?: number; 9 | /** Number of segments along the Y axis */ 10 | heightSegments?: number; 11 | /** Number of segments along the Z axis */ 12 | depthSegments?: number; 13 | } 14 | /** 15 | * Helper to easily create 3D box indexed geometries. 16 | * 17 | * @example 18 | * ```javascript 19 | * const boxGeometry = new BoxGeometry() 20 | * ``` 21 | */ 22 | export declare class BoxGeometry extends IndexedGeometry { 23 | constructor({ instancesCount, vertexBuffers, topology, mapBuffersAtCreation, widthSegments, heightSegments, depthSegments, }?: BoxGeometryParams); 24 | } 25 | -------------------------------------------------------------------------------- /dist/types/extras/geometries/SphereGeometry.d.ts: -------------------------------------------------------------------------------- 1 | import { IndexedGeometry } from '../../core/geometries/IndexedGeometry'; 2 | import { GeometryBaseParams } from '../../types/Geometries'; 3 | /** 4 | * Parameters used to create a {@link SphereGeometry} 5 | */ 6 | export interface SphereGeometryParams extends GeometryBaseParams { 7 | /** Number of horizontal segments */ 8 | widthSegments?: number; 9 | /** Number of vertical segments */ 10 | heightSegments?: number; 11 | /** Horizontal starting angle */ 12 | phiStart?: number; 13 | /** Horizontal sweep angle size */ 14 | phiLength?: number; 15 | /** Vertical starting angle */ 16 | thetaStart?: number; 17 | /** Vertical sweep angle size */ 18 | thetaLength?: number; 19 | } 20 | /** 21 | * Helper to easily create 3D sphere indexed geometries. 22 | * 23 | * @example 24 | * ```javascript 25 | * const sphereGeometry = new SphereGeometry() 26 | * ``` 27 | */ 28 | export declare class SphereGeometry extends IndexedGeometry { 29 | constructor({ topology, instancesCount, vertexBuffers, mapBuffersAtCreation, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength, }?: SphereGeometryParams); 30 | } 31 | -------------------------------------------------------------------------------- /dist/types/math/color-utils.d.ts: -------------------------------------------------------------------------------- 1 | import { Vec3 } from './Vec3'; 2 | /** 3 | * Convert a color float component from sRGB to linear space. 4 | * @param c - color float component to convert. 5 | * @returns - converted color float component. 6 | */ 7 | export declare function sRGBToLinearFloat(c: number): number; 8 | /** 9 | * Convert a color float component from linear to sRGB space. 10 | * @param c - color float component to convert. 11 | * @returns - converted color float component. 12 | */ 13 | export declare function linearTosRGBFloat(c: number): number; 14 | /** 15 | * Convert a color {@link Vec3} from sRGB to linear space. 16 | * @param vector - color {@link Vec3} to convert. 17 | * @returns - converted color {@link Vec3}. 18 | */ 19 | export declare function sRGBToLinear(vector?: Vec3): Vec3; 20 | /** 21 | * Convert a color {@link Vec3} from linear to sRGB space. 22 | * @param vector - color {@link Vec3} to convert. 23 | * @returns - converted color {@link Vec3}. 24 | */ 25 | export declare function linearTosRGB(vector?: Vec3): Vec3; 26 | -------------------------------------------------------------------------------- /dist/types/types/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './gltf/GLTF'; 2 | export * from './gltf/GLTFExtensions'; 3 | export * from './gltf/GLTFScenesManager'; 4 | export * from './BindGroups'; 5 | export * from './Geometries'; 6 | export * from './Materials'; 7 | export * from './PipelineEntries'; 8 | export * from './BindGroups'; 9 | export * from './Textures'; 10 | -------------------------------------------------------------------------------- /dist/types/utils/utils.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Generate a unique universal id 3 | * @returns - unique universal id generated 4 | */ 5 | export declare const generateUUID: () => string; 6 | /** 7 | * Turns a string into a camel case string 8 | * @param string - string to transform 9 | * @returns - camel case string created 10 | */ 11 | export declare const toCamelCase: (string: string) => string; 12 | /** 13 | * Turns a string into a kebab case string 14 | * @param string - string to transform 15 | * @returns - kebab case string created 16 | */ 17 | export declare const toKebabCase: (string: string) => string; 18 | /** 19 | * Throw a console warning with the passed arguments 20 | * @param warning - warning to be thrown 21 | */ 22 | export declare const throwWarning: (warning: string) => void; 23 | /** 24 | * Throw a javascript error with the passed arguments 25 | * @param error - error to be thrown 26 | */ 27 | export declare const throwError: (error: string) => never; 28 | -------------------------------------------------------------------------------- /dist/types/utils/webgpu-constants.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GPUShaderStage constants with fallbacks. 3 | */ 4 | export declare const WebGPUShaderStageConstants: Record; 5 | /** 6 | * GPUBufferUsage constants with fallbacks. 7 | */ 8 | export declare const WebGPUBufferUsageConstants: Record; 9 | /** 10 | * GPUTextureUsage constants with fallbacks. 11 | */ 12 | export declare const WebGPUTextureUsageConstants: Record; 13 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/docs/assets/favicon.png -------------------------------------------------------------------------------- /examples/canvas-text/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #page { 3 | display: flex; 4 | justify-content: center; 5 | align-items: center; 6 | } 7 | 8 | .plane { 9 | display: block; 10 | transition: all 0.5s; 11 | } 12 | 13 | .plane.canvas-texture-ready { 14 | /*opacity: 0;*/ 15 | -webkit-text-fill-color: transparent; 16 | } 17 | 18 | .plane h1 { 19 | margin: 0; 20 | padding: 0 0.5em; 21 | font-size: 5vw; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/cloth-simulation/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #page { 3 | display: flex; 4 | align-items: center; 5 | justify-content: center; 6 | } 7 | 8 | #cloth { 9 | position: relative; 10 | overflow: hidden; 11 | width: 90%; 12 | height: 90vh; 13 | /* prettier-ignore */ 14 | height: 90svh; 15 | } 16 | 17 | .no-curtains #cloth { 18 | background: linear-gradient(to right, var(--primary-color), var(--secondary-color)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/compute-blur/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #page { 3 | padding: 2.25rem 0; 4 | } 5 | 6 | .plane { 7 | position: relative; 8 | overflow: hidden; 9 | width: 80%; 10 | height: 80vh; 11 | margin: 10vh auto; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/compute-boids/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #page { 3 | display: flex; 4 | justify-content: center; 5 | align-items: center; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/compute-particles/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #page { 3 | display: flex; 4 | justify-content: center; 5 | align-items: center; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/cubemap/assets/negx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/examples/cubemap/assets/negx.jpg -------------------------------------------------------------------------------- /examples/cubemap/assets/negy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/examples/cubemap/assets/negy.jpg -------------------------------------------------------------------------------- /examples/cubemap/assets/negz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/examples/cubemap/assets/negz.jpg -------------------------------------------------------------------------------- /examples/cubemap/assets/posx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/examples/cubemap/assets/posx.jpg -------------------------------------------------------------------------------- /examples/cubemap/assets/posy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/examples/cubemap/assets/posy.jpg -------------------------------------------------------------------------------- /examples/cubemap/assets/posz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/examples/cubemap/assets/posz.jpg -------------------------------------------------------------------------------- /examples/cubemap/assets/readme.txt: -------------------------------------------------------------------------------- 1 | Author 2 | ====== 3 | 4 | This is the work of Emil Persson, aka Humus. 5 | http://www.humus.name 6 | humus@comhem.se 7 | 8 | 9 | 10 | Legal stuff 11 | =========== 12 | 13 | This work is free and may be used by anyone for any purpose 14 | and may be distributed freely to anyone using any distribution 15 | media or distribution method as long as this file is included. 16 | Distribution without this file is allowed if it's distributed 17 | with free non-commercial software; however, fair credit of the 18 | original author is expected. 19 | Any commercial distribution of this software requires the written 20 | approval of Emil Persson. 21 | -------------------------------------------------------------------------------- /examples/cubemap/styles.css: -------------------------------------------------------------------------------- 1 | #credits { 2 | position: absolute; 3 | left: 1rem; 4 | bottom: 1rem; 5 | font-size: 0.75rem; 6 | } 7 | -------------------------------------------------------------------------------- /examples/custom-geometry/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | /*** content ***/ 3 | #page { 4 | max-width: 1440px; 5 | margin: 0 auto; 6 | padding: 2.25rem 0; 7 | } 8 | 9 | #planes { 10 | } 11 | 12 | .plane { 13 | width: 75%; 14 | aspect-ratio: 20 / 10; 15 | margin: 7rem 0; 16 | } 17 | 18 | .plane:nth-child(odd) { 19 | margin-left: 25%; 20 | } 21 | } 22 | 23 | @media screen and (orientation: portrait) { 24 | .plane { 25 | width: 100%; 26 | } 27 | 28 | .plane:nth-child(odd) { 29 | margin-left: 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/custom-scroll-and-transformations/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | /*** content ***/ 3 | #page { 4 | max-width: 1680px; 5 | margin: 0 auto; 6 | padding: 2.25rem 20px; 7 | } 8 | 9 | #planes { 10 | --nb-planes-per-row: 4; 11 | display: grid; 12 | grid-template-columns: repeat(var(--nb-planes-per-row), [col-start] 1fr); 13 | gap: 2rem; 14 | padding: 0 0 calc(50vh - (0.5 * 100vw / var(--nb-planes-per-row))) 0; 15 | } 16 | 17 | .plane { 18 | grid-column: span 1; 19 | aspect-ratio: 1; 20 | margin: 0; 21 | } 22 | } 23 | 24 | @media screen and (min-width: 1720px) { 25 | #planes { 26 | padding: 0 0 calc(50vh - (0.5 * 1680px / var(--nb-planes-per-row))) 0; 27 | } 28 | } 29 | 30 | @media screen and (orientation: portrait) { 31 | #planes { 32 | --nb-planes-per-row: 2; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/deferred-rendering/styles.css: -------------------------------------------------------------------------------- 1 | #debug-view-button { 2 | position: absolute; 3 | z-index: 2; 4 | top: 1rem; 5 | left: 1rem; 6 | } 7 | -------------------------------------------------------------------------------- /examples/dom-meshes/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #mesh-container { 3 | position: relative; 4 | width: 100%; 5 | display: flex; 6 | justify-content: space-around; 7 | align-items: center; 8 | flex-wrap: wrap; 9 | } 10 | 11 | .dom-mesh { 12 | flex-basis: 25%; 13 | aspect-ratio: 1; 14 | margin: 10vh 5%; 15 | box-sizing: border-box; 16 | border: 2px solid var(--primary-color); 17 | position: relative; 18 | 19 | justify-content: center; 20 | align-items: center; 21 | align-content: center; 22 | } 23 | 24 | .dom-mesh h2 { 25 | position: absolute; 26 | top: 50%; 27 | right: 0; 28 | left: 0; 29 | transform: translate3d(0, -50%, 0); 30 | margin: 0; 31 | text-align: center; 32 | } 33 | 34 | #large-cube-mesh { 35 | flex-basis: 60%; 36 | aspect-ratio: 2.5 / 1; 37 | } 38 | 39 | .dom-mesh img { 40 | display: none; 41 | min-width: 100%; 42 | min-height: 100%; 43 | object-fit: cover; 44 | } 45 | 46 | .sphere-mesh { 47 | border-radius: 50%; 48 | } 49 | } 50 | 51 | @media screen and (orientation: portrait) { 52 | .dom-mesh { 53 | flex-basis: 75%; 54 | margin: 10vh 12.5%; 55 | } 56 | 57 | #large-cube-mesh { 58 | flex-basis: 90%; 59 | margin: 10vh 5%; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /examples/full-screen-plane-shader/styles.css: -------------------------------------------------------------------------------- 1 | #page { 2 | position: absolute; 3 | inset: 0; 4 | } 5 | 6 | .no-curtains #page:after { 7 | content: 'Oh, it looks like WebGPU is not yet supported by this browser or OS.'; 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | height: 100%; 12 | width: 100%; 13 | } 14 | -------------------------------------------------------------------------------- /examples/gltf-dom-meshes/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | h1 { 3 | margin-bottom: 0; 4 | } 5 | 6 | #content { 7 | overflow: hidden; 8 | } 9 | 10 | #gltf-content { 11 | position: relative; 12 | float: left; 13 | width: 25%; 14 | box-sizing: border-box; 15 | padding: 1rem; 16 | margin: 0 2rem 1rem 0; 17 | } 18 | 19 | #gltf { 20 | /* 21 | Start with the Boom Box (first example) aspect ratio 22 | taken from its glTF bounding box size x / y 23 | */ 24 | aspect-ratio: 1.0153 / 1; 25 | } 26 | } 27 | 28 | @media screen and (max-aspect-ratio: 10 / 8) { 29 | #gltf-content { 30 | width: 50%; 31 | } 32 | } 33 | 34 | @media screen and (orientation: portrait) { 35 | #gltf-content { 36 | width: 75%; 37 | margin: 0 auto 1rem auto; 38 | float: none; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/gltf-loader-ibl-shading/styles.css: -------------------------------------------------------------------------------- 1 | #canvas::after { 2 | content: 'Loading'; 3 | position: fixed; 4 | z-index: 1; 5 | top: 0; 6 | right: 0; 7 | bottom: 0; 8 | left: 0; 9 | pointer-events: none; 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | opacity: 0; 14 | transition: opacity 0.35s; 15 | } 16 | 17 | #canvas.loading::after { 18 | opacity: 1; 19 | } 20 | 21 | #credits { 22 | position: absolute; 23 | left: 1rem; 24 | bottom: 1rem; 25 | font-size: 0.75rem; 26 | } 27 | -------------------------------------------------------------------------------- /examples/gltf-loader-skins-animations-shadows/styles.css: -------------------------------------------------------------------------------- 1 | #canvas::after { 2 | content: 'Loading'; 3 | position: fixed; 4 | z-index: 1; 5 | top: 0; 6 | right: 0; 7 | bottom: 0; 8 | left: 0; 9 | pointer-events: none; 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | opacity: 0; 14 | transition: opacity 0.35s; 15 | } 16 | 17 | #canvas.loading::after { 18 | opacity: 1; 19 | } 20 | 21 | #credits { 22 | position: absolute; 23 | left: 1rem; 24 | bottom: 1rem; 25 | font-size: 0.75rem; 26 | } 27 | -------------------------------------------------------------------------------- /examples/gsap-instanced-kinetic-typography/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #page { 3 | display: flex; 4 | justify-content: center; 5 | align-items: center; 6 | height: 100vh; 7 | opacity: 0; 8 | } 9 | 10 | .no-curtains #page { 11 | opacity: 1; 12 | } 13 | 14 | h1 { 15 | text-align: center; 16 | position: relative; 17 | padding: 0; 18 | margin: 0; 19 | } 20 | 21 | .kinetic-plane { 22 | display: block; 23 | padding: 0 0.125em; 24 | font-size: 3rem; 25 | font-family: var(--text-font); 26 | font-weight: 700; 27 | position: absolute; 28 | top: 50%; 29 | left: 50%; 30 | transform: translate3d(-50%, -50%, 0); 31 | text-transform: uppercase; 32 | } 33 | 34 | .no-curtains .kinetic-plane { 35 | position: relative; 36 | top: auto; 37 | left: auto; 38 | transform: translate3d(0, 0, 0); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/instanced-planes/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | /*** content ***/ 3 | #page { 4 | padding: 2.25rem 0; 5 | } 6 | 7 | #planes { 8 | padding: 0; 9 | } 10 | 11 | .plane { 12 | width: 50%; 13 | aspect-ratio: 20 / 10; 14 | margin: 7rem 0 7rem 12.5%; 15 | } 16 | 17 | .plane:nth-child(odd) { 18 | margin-left: 37.5%; 19 | } 20 | } 21 | 22 | @media screen and (orientation: portrait) { 23 | .plane { 24 | width: 75%; 25 | margin: 7rem auto; 26 | } 27 | 28 | .plane:nth-child(odd) { 29 | margin-left: auto; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/instanced-shadowed-particles/shaders/chunks/additional-vertex-particle.wgsl.js: -------------------------------------------------------------------------------- 1 | export const additionalVertexParticle = /* wgsl */ ` 2 | let size: f32 = getParticleSize(attributes.particlePosition.w, attributes.particleVelocity.w); 3 | 4 | // billboarding 5 | worldPosition = matrices.model * vec4(attributes.particlePosition.xyz, 1.0); 6 | var mvPosition: vec4f = camera.view * worldPosition; 7 | mvPosition += vec4(attributes.position, 0.0) * size; 8 | vsOutput.position = camera.projection * mvPosition; 9 | 10 | vsOutput.worldPosition = (worldPosition.xyz / worldPosition.w) + attributes.position * size; 11 | vsOutput.viewDirection = camera.position - vsOutput.worldPosition; 12 | 13 | // normals in view space to follow billboarding 14 | vsOutput.normal = getViewNormal(attributes.normal); 15 | 16 | vsOutput.velocity = attributes.particleVelocity; 17 | ` 18 | -------------------------------------------------------------------------------- /examples/instanced-shadowed-particles/shaders/chunks/discard-particle-fragment.wgsl.js: -------------------------------------------------------------------------------- 1 | export const discardParticleFragment = /* wgsl */ ` 2 | if(distance(fsInput.uv, vec2(0.5)) > 0.5) { 3 | discard; 4 | } 5 | ` 6 | -------------------------------------------------------------------------------- /examples/instanced-shadowed-particles/shaders/chunks/get-particle-size.wgsl.js: -------------------------------------------------------------------------------- 1 | export const getParticleSize = /* wgsl */ ` 2 | fn getParticleSize(currentLife: f32, initialLife: f32) -> f32 { 3 | // scale from 0 -> 1 when life begins 4 | let startSize = smoothstep(0.0, 0.25, 1.0 - currentLife / initialLife); 5 | // scale from 1 -> 0 when life ends 6 | let endSize = smoothstep(0.0, 0.25, currentLife / initialLife); 7 | 8 | return startSize * endSize * params.size; 9 | } 10 | ` 11 | -------------------------------------------------------------------------------- /examples/instanced-shadowed-particles/shaders/chunks/preliminary-fragment-particle.wgsl.js: -------------------------------------------------------------------------------- 1 | import { discardParticleFragment } from './discard-particle-fragment.wgsl.js' 2 | 3 | export const preliminaryFragmentParticle = /* wgsl */ ` 4 | ${discardParticleFragment} 5 | 6 | // clamp velocity 7 | let velocityLength = saturate(length(velocity.xyz) * shading.velocityStrength); 8 | 9 | // use it to mix between our base (blue) color and our additional (pink) color 10 | outputColor = mix( 11 | outputColor, 12 | vec4(shading.pinkColor, 1.0), 13 | vec4(vec3(velocityLength), 1.0) 14 | ); 15 | ` 16 | -------------------------------------------------------------------------------- /examples/instanced-shadowed-particles/styles.css: -------------------------------------------------------------------------------- 1 | #credits { 2 | position: absolute; 3 | left: 1rem; 4 | bottom: 1rem; 5 | font-size: 0.75rem; 6 | max-width: 22.5rem; 7 | } 8 | -------------------------------------------------------------------------------- /examples/mixing-dom-synced-planes-transmissive-bubbles/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | /*** content ***/ 3 | 4 | #page { 5 | padding: 2.25rem 0; 6 | } 7 | 8 | h1 { 9 | margin-bottom: 0; 10 | } 11 | 12 | #planes { 13 | padding-top: 0; 14 | } 15 | 16 | #credits { 17 | margin-top: 1.5rem; 18 | } 19 | 20 | .plane { 21 | width: 75%; 22 | aspect-ratio: 20 / 10; 23 | margin: 7rem 0; 24 | } 25 | 26 | .plane:nth-child(odd) { 27 | margin-left: 25%; 28 | } 29 | } 30 | 31 | @media screen and (orientation: portrait) { 32 | .plane { 33 | width: 100%; 34 | margin: 7rem auto; 35 | } 36 | 37 | .plane:nth-child(odd) { 38 | margin-left: auto; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /examples/multiple-canvases-updating-renderer/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | /*** canvas ***/ 3 | #canvas-front { 4 | position: fixed; 5 | top: 0; 6 | left: 0; 7 | height: 100vh; 8 | /* prettier ignore */ 9 | height: 100lvh; 10 | width: 100vw; 11 | z-index: 3; 12 | pointer-events: none; 13 | } 14 | 15 | #canvas-back { 16 | position: fixed; 17 | top: 0; 18 | left: 0; 19 | height: 100vh; 20 | /* prettier ignore */ 21 | height: 100lvh; 22 | width: 100vw; 23 | z-index: 1; 24 | pointer-events: none; 25 | } 26 | 27 | /*** content ***/ 28 | #page { 29 | position: relative; 30 | z-index: 2; 31 | display: flex; 32 | justify-content: center; 33 | align-items: center; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/ping-pong-plane/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #ping-pong-plane { 3 | width: 100%; 4 | height: 100vh; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/post-processing-transform-origin/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #scrolling-wheel { 3 | position: relative; 4 | overflow: hidden; 5 | width: 100%; 6 | height: 100vh; 7 | } 8 | 9 | #scrolling-wheel h1 { 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | position: absolute; 14 | top: 0; 15 | right: 0; 16 | bottom: 0; 17 | left: 0; 18 | margin: 0; 19 | z-index: 1; 20 | } 21 | 22 | .plane { 23 | position: absolute; 24 | top: 30vh; 25 | right: 20vw; 26 | bottom: 30vh; 27 | left: 20vw; 28 | } 29 | } 30 | 31 | @media screen and (orientation: portrait) { 32 | .plane { 33 | position: absolute; 34 | top: 40vh; 35 | right: 10vw; 36 | bottom: 40vh; 37 | left: 10vw; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/render-bundle-indirect-drawing-gpu-culling/styles.css: -------------------------------------------------------------------------------- 1 | #debug-camera-button { 2 | position: absolute; 3 | z-index: 1; 4 | bottom: 1rem; 5 | left: 1rem; 6 | } 7 | 8 | .stats { 9 | transform-origin: 0 0; 10 | transform: scale3d(2, 2, 1); 11 | } 12 | -------------------------------------------------------------------------------- /examples/shadow-mapping/styles.css: -------------------------------------------------------------------------------- 1 | #debug-view-button { 2 | position: absolute; 3 | z-index: 2; 4 | top: 1rem; 5 | left: 1rem; 6 | } 7 | -------------------------------------------------------------------------------- /examples/slideshow/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #page { 3 | display: flex; 4 | align-items: center; 5 | justify-content: center; 6 | } 7 | 8 | #multi-textures-plane { 9 | position: relative; 10 | overflow: hidden; 11 | width: 100%; 12 | height: 100vh; 13 | } 14 | 15 | #multi-textures-plane button { 16 | border: 0; 17 | cursor: pointer; 18 | font: inherit; 19 | background: transparent; 20 | margin: 0; 21 | padding: 2rem; 22 | box-sizing: border-box; 23 | display: flex; 24 | justify-content: center; 25 | align-items: flex-end; 26 | position: absolute; 27 | width: 100%; 28 | top: 0; 29 | right: 0; 30 | bottom: 0; 31 | left: 0; 32 | font-size: 1.5rem; 33 | opacity: 0; 34 | transition: opacity 0.5s linear; 35 | } 36 | 37 | #multi-textures-plane button.show { 38 | opacity: 1; 39 | } 40 | 41 | body.is-waiting:not(.no-curtains) { 42 | cursor: wait; 43 | } 44 | 45 | body.is-waiting #multi-textures-plane button { 46 | pointer-events: none; 47 | opacity: 0.5; 48 | } 49 | } 50 | 51 | @media screen and (max-width: 1000px) { 52 | #multi-textures-plane button { 53 | font-size: 1.25rem; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /examples/video-planes/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #videos { 3 | display: flex; 4 | justify-content: space-around; 5 | align-items: center; 6 | flex-wrap: wrap; 7 | } 8 | 9 | .video-wrapper { 10 | flex-basis: 40%; 11 | margin: 0 5%; 12 | overflow: hidden; 13 | } 14 | 15 | .video-wrapper h2 { 16 | text-align: center; 17 | } 18 | 19 | .video-elements { 20 | justify-content: center; 21 | align-items: center; 22 | align-content: center; 23 | aspect-ratio: 15 / 10; 24 | } 25 | } 26 | 27 | @media screen and (max-width: 1000px) { 28 | .multi-textures { 29 | font-size: 2em; 30 | } 31 | 32 | .video-wrapper { 33 | flex-basis: 90%; 34 | } 35 | 36 | .video-elements { 37 | aspect-ratio: 10 / 15; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /guides/core-concepts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Core concepts 3 | group: Guides 4 | category: About 5 | children: 6 | - ./renderers-scene-rendering-and-camera.md 7 | - ./bindings-and-bind-groups.md 8 | --- 9 | 10 | # Core concepts 11 | 12 | A collection of resources to understand how gpu-curtains work under the hood and take full advantages of all its possibilities. 13 | 14 | - [The renderers, scene rendering and camera](./renderers-scene-rendering-and-camera.md) 15 | - [Bindings and bind groups](./bindings-and-bind-groups.md) -------------------------------------------------------------------------------- /guides/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting started 3 | group: Guides 4 | category: Tutorials 5 | children: 6 | - ./3d-engine-usage.md 7 | - ./dom-syncing-usage.md 8 | --- 9 | 10 | # Getting started 11 | 12 | A couple tutorial of basic tutorials to understand how to get started with gpu-curtains. 13 | 14 | - [Use gpu-curtains as a 3D engine](./3d-engine-usage.md) 15 | - [Use gpu-curtains for DOM syncing](./dom-syncing-usage.md) 16 | 17 | ## More examples 18 | 19 | Have a look at all the possibilities in the [example section](https://martinlaxenaire.github.io/gpu-curtains/examples/). -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import esbuild, { minify } from 'rollup-plugin-esbuild' 2 | 3 | export default [ 4 | { 5 | plugins: [esbuild()], 6 | input: 'src/index.ts', 7 | output: [ 8 | { 9 | dir: 'dist/esm', 10 | format: 'es', 11 | preserveModules: true, 12 | preserveModulesRoot: 'src', 13 | entryFileNames: '[name].mjs', 14 | }, 15 | { 16 | file: 'dist/gpu-curtains.umd.js', 17 | format: 'umd', 18 | name: 'window', 19 | extend: true, 20 | }, 21 | { 22 | file: 'dist/gpu-curtains.umd.min.js', 23 | format: 'umd', 24 | name: 'window', 25 | extend: true, 26 | plugins: [ 27 | minify({ 28 | keepNames: true, 29 | }), 30 | ], 31 | sourcemap: true, 32 | }, 33 | ], 34 | }, 35 | ] 36 | -------------------------------------------------------------------------------- /sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://martinlaxenaire.github.io/gpu-curtains/index.html 5 | 6 | 7 | https://martinlaxenaire.github.io/gpu-curtains/examples/sitemap.xml 8 | 9 | 10 | https://martinlaxenaire.github.io/gpu-curtains/docs/sitemap.xml 11 | 12 | -------------------------------------------------------------------------------- /src/core/lights/AmbientLight.ts: -------------------------------------------------------------------------------- 1 | import { Light, LightBaseParams, LightsType } from './Light' 2 | import { Vec3 } from '../../math/Vec3' 3 | import { CameraRenderer } from '../renderers/utils' 4 | import { GPUCurtains } from '../../curtains/GPUCurtains' 5 | 6 | /** 7 | * Create an ambient light that equally illuminates all objects in the scene. 8 | * 9 | * This light cannot cast shadows. 10 | * 11 | * @example 12 | * ```javascript 13 | * // assuming 'renderer' is a valid Camera renderer 14 | * const ambientLight = new AmbientLight(renderer, { 15 | * color: new Vec3(1), 16 | * intensity: 0.1, 17 | * }) 18 | * ``` 19 | */ 20 | export class AmbientLight extends Light { 21 | /** 22 | * AmbientLight constructor 23 | * @param renderer - {@link CameraRenderer} or {@link GPUCurtains} used to create this {@link AmbientLight}. 24 | * @param parameters - {@link LightBaseParams} used to create this {@link AmbientLight}. 25 | */ 26 | constructor( 27 | renderer: CameraRenderer | GPUCurtains, 28 | { label = 'AmbientLight', color = new Vec3(1), intensity = 0.1 } = {} as LightBaseParams 29 | ) { 30 | const type = 'ambientLights' 31 | super(renderer, { label, color, intensity, type }) 32 | } 33 | 34 | // explicitly disable position as well 35 | 36 | /** @ignore */ 37 | applyPosition() {} 38 | } 39 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/body/apply-directional-shadows.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to apply a given {@link core/lights/DirectionalLight.DirectionalLight | DirectionalLight} shadow to its light contribution. */ 2 | export const applyDirectionalShadows: string = /* wgsl */ ` 3 | directLight.color *= directionalShadows[i]; 4 | ` 5 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/body/apply-point-shadows.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to apply a given {@link core/lights/PointLight.PointLight | PointLight} shadow to its light contribution. */ 2 | export const applyPointShadows: string = /* wgsl */ ` 3 | directLight.color *= pointShadows[i]; 4 | ` 5 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/body/apply-spot-shadows.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to apply a given {@link core/lights/SpotLight.SpotLight | SpotLight} shadow to its light contribution. */ 2 | export const applySpotShadows: string = /* wgsl */ ` 3 | directLight.color *= spotShadows[i]; 4 | ` 5 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/body/get-IBL-indirect-irradiance.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from '../../../full/fragment/get-fragment-shader-code' 2 | 3 | /** 4 | * Get the environment map indirect irradiance (diffuse). 5 | * @param parameters - Parameters to use to apply PBR shading. 6 | * @param parameters.environmentMap - {@link extras/environmentMap/EnvironmentMap.EnvironmentMap | EnvironmentMap} to use for indirect irradiance if any. 7 | * @returns - String with environment map indirect irradiance applied to `iblIrradiance` (`vec3f`). 8 | */ 9 | export const getIBLIndirectIrradiance = ({ 10 | environmentMap = null, 11 | }: { 12 | environmentMap?: PBRFragmentShaderInputParams['environmentMap'] 13 | }): string => { 14 | let iblIndirectDiffuse = '' 15 | 16 | if (environmentMap) { 17 | iblIndirectDiffuse += /* wgs */ ` 18 | iblIrradiance += getIBLIndirectIrradiance( 19 | normal, 20 | baseDiffuseColor.rgb, 21 | ${environmentMap.sampler.name}, 22 | ${environmentMap.diffuseTexture.options.name}, 23 | envRotation, 24 | envDiffuseIntensity, 25 | );` 26 | } 27 | 28 | return iblIndirectDiffuse 29 | } 30 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/body/get-IBL-indirect-radiance.ts: -------------------------------------------------------------------------------- 1 | import { PBRFragmentShaderInputParams } from '../../../full/fragment/get-fragment-shader-code' 2 | 3 | /** 4 | * Get the environment map indirect radiance (specular). 5 | * @param parameters - Parameters to use to apply PBR shading. 6 | * @param parameters.environmentMap - {@link extras/environmentMap/EnvironmentMap.EnvironmentMap | EnvironmentMap} to use for indirect radiance if any. 7 | * @returns - String with environment map indirect radiance applied to `radiance` (`vec3f`). 8 | */ 9 | export const getIBLIndirectRadiance = ({ 10 | environmentMap = null, 11 | }: { 12 | environmentMap?: PBRFragmentShaderInputParams['environmentMap'] 13 | }): string => { 14 | let iblIndirectSpecular = '' 15 | 16 | if (environmentMap) { 17 | iblIndirectSpecular += /* wgs */ ` 18 | radiance += getIBLIndirectRadiance( 19 | normal, 20 | viewDirection, 21 | roughness, 22 | specularColor, 23 | specularIntensity, 24 | iBLGGXFresnel, 25 | ${environmentMap.sampler.name}, 26 | ${environmentMap.specularTexture.options.name}, 27 | envRotation, 28 | envSpecularIntensity, 29 | );` 30 | } 31 | 32 | return iblIndirectSpecular 33 | } 34 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/body/get-PCF-shadows.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to get the PCF soft shadow generated by all the {@link core/lights/DirectionalLight.DirectionalLight | DirectionalLight}, {@link core/lights/PointLight.PointLight | PointLight} and {@link core/lights/SpotLight.SpotLight | SpotLight}. */ 2 | export const getPCFShadows: string = /* wgsl */ ` 3 | let pointShadows = getPCFPointShadows(worldPosition); 4 | let directionalShadows = getPCFDirectionalShadows(worldPosition); 5 | let spotShadows = getPCFSpotShadows(worldPosition); 6 | ` 7 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/RE-indirect-diffuse.ts: -------------------------------------------------------------------------------- 1 | /** WGSL functions to calculate the indirect diffuse contribution of lights. */ 2 | export const REIndirectDiffuse = /* wgsl */ ` 3 | fn getIndirectDiffuse(irradiance: vec3f, diffuseColor: vec3f, ptr_reflectedLight: ptr) { 4 | (*ptr_reflectedLight).indirectDiffuse += irradiance * BRDF_Lambert( diffuseColor ); 5 | } 6 | 7 | // Indirect Diffuse RenderEquations 8 | fn RE_IndirectDiffuse(irradiance: vec3f, diffuseColor: vec3f, ptr_reflectedLight: ptr) { 9 | var totalAmbientIrradiance: vec3f = irradiance; 10 | 11 | for(var i: i32 = 0; i < ambientLights.count; i++) { 12 | totalAmbientIrradiance += ambientLights.color[i]; 13 | } 14 | 15 | getIndirectDiffuse(totalAmbientIrradiance, diffuseColor, ptr_reflectedLight); 16 | } 17 | ` 18 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/RE-indirect-specular.ts: -------------------------------------------------------------------------------- 1 | /** WGSL functions to calculate the indirect specular and diffuse contributions of lights using multi-scattering. */ 2 | export const REIndirectSpecular = /* wgsl */ ` 3 | // Indirect Specular RenderEquations 4 | fn RE_IndirectSpecular( 5 | radiance: vec3f, 6 | irradiance: vec3f, 7 | normal: vec3f, 8 | diffuseColor: vec3f, 9 | specularFactor: f32, 10 | specularColorFactor: vec3f, 11 | viewDirection: vec3f, 12 | metallic: f32, 13 | roughness: f32, 14 | iBLGGXFresnel: IBLGGXFresnel, 15 | ptr_reflectedLight: ptr 16 | ) { 17 | let k_D: vec3f = diffuseColor * (1.0 - iBLGGXFresnel.FssEss + iBLGGXFresnel.FmsEms); 18 | 19 | // we just add radiance and irradiance to the indirect contributions using iBLGGXFresnel 20 | // we might need to adjust when implementing clearcoat, sheen or iridescence 21 | 22 | // we remove RECIPROCAL_PI multiplication since the LUT already ensures energy conservation 23 | let cosineWeightedIrradiance: vec3f = irradiance; 24 | // let cosineWeightedIrradiance: vec3f = irradiance * RECIPROCAL_PI; 25 | 26 | (*ptr_reflectedLight).indirectSpecular += iBLGGXFresnel.FssEss * radiance; 27 | (*ptr_reflectedLight).indirectSpecular += iBLGGXFresnel.FmsEms * cosineWeightedIrradiance; 28 | 29 | (*ptr_reflectedLight).indirectDiffuse += k_D * cosineWeightedIrradiance; 30 | } 31 | ` 32 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/get-IBL-indirect-irradiance.ts: -------------------------------------------------------------------------------- 1 | /** Helper function chunk appended internally and used to compute the indirect irradiance based on environment diffuse map. */ 2 | export const getIBLIndirectIrradiance = /* wgsl */ ` 3 | fn getIBLIndirectIrradiance( 4 | normal: vec3f, 5 | diffuseColor: vec3f, 6 | clampSampler: sampler, 7 | envDiffuseTexture: texture_cube, 8 | envRotation: mat3x3f, 9 | envDiffuseIntensity: f32, 10 | ) -> vec3f { 11 | // IBL diffuse (irradiance) 12 | let diffuseLight: vec4f = textureSample( 13 | envDiffuseTexture, 14 | clampSampler, 15 | normal * envRotation 16 | ); 17 | 18 | return diffuseLight.rgb * envDiffuseIntensity; 19 | } 20 | ` 21 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/get-IBL-indirect-radiance.ts: -------------------------------------------------------------------------------- 1 | /** Helper function chunk appended internally and used to compute IBL indirect radiance, based on environment specular map. */ 2 | export const getIBLIndirectRadiance = /* wgsl */ ` 3 | fn getIBLIndirectRadiance( 4 | normal: vec3f, 5 | viewDirection: vec3f, 6 | roughness: f32, 7 | specularColor: vec3f, 8 | specularFactor: f32, 9 | iBLGGXFresnel: IBLGGXFresnel, 10 | clampSampler: sampler, 11 | envSpecularTexture: texture_cube, 12 | envRotation: mat3x3f, 13 | envSpecularIntensity: f32, 14 | )-> vec3f { 15 | let N: vec3f = normal; 16 | let V: vec3f = viewDirection; 17 | let NdotV: f32 = saturate(dot(N, V)); 18 | 19 | let reflection: vec3f = normalize(reflect(-V, N)); 20 | 21 | let lod: f32 = roughness * f32(textureNumLevels(envSpecularTexture) - 1); 22 | 23 | let specularLight: vec4f = textureSampleLevel( 24 | envSpecularTexture, 25 | clampSampler, 26 | reflection * envRotation, 27 | lod 28 | ); 29 | 30 | return specularLight.rgb * envSpecularIntensity; 31 | } 32 | ` 33 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/get-PCF-directional-shadow-contribution.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to get the PCF soft shadow generated by a given {@link core/lights/DirectionalLight.DirectionalLight | DirectionalLight}. */ 2 | export const getPCFDirectionalShadowContribution: string = /* wgsl */ ` 3 | fn getPCFDirectionalShadowContribution(index: i32, worldPosition: vec3f, depthTexture: texture_depth_2d) -> f32 { 4 | let directionalShadow: DirectionalShadowsElement = directionalShadows.directionalShadowsElements[index]; 5 | 6 | // get shadow coords 7 | let projectedShadowCoords: vec4f = directionalShadow.projectionMatrix * directionalShadow.viewMatrix * vec4(worldPosition, 1.0); 8 | var shadowCoords: vec3f = projectedShadowCoords.xyz / projectedShadowCoords.w; 9 | 10 | // Convert XY to (0, 1) 11 | // Y is flipped because texture coords are Y-down. 12 | shadowCoords = vec3( 13 | shadowCoords.xy * vec2(0.5, -0.5) + vec2(0.5), 14 | shadowCoords.z 15 | ); 16 | 17 | return getPCFBaseShadowContribution( 18 | shadowCoords, 19 | directionalShadow.pcfSamples, 20 | directionalShadow.bias, 21 | directionalShadow.intensity, 22 | depthTexture 23 | ); 24 | } 25 | ` 26 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/get-PCF-spot-shadow-contribution.ts: -------------------------------------------------------------------------------- 1 | /** Helper chunk to get the PCF soft shadow generated by a given {@link core/lights/SpotLight.SpotLight | SpotLight}. */ 2 | export const getPCFSpotShadowContribution: string = /* wgsl */ ` 3 | fn getPCFSpotShadowContribution(index: i32, worldPosition: vec3f, depthTexture: texture_depth_2d) -> f32 { 4 | let spotShadow: SpotShadowsElement = spotShadows.spotShadowsElements[index]; 5 | 6 | // get shadow coords 7 | let projectedShadowCoords: vec4f = spotShadow.projectionMatrix * spotShadow.viewMatrix * vec4(worldPosition, 1.0); 8 | var shadowCoords: vec3f = projectedShadowCoords.xyz / projectedShadowCoords.w; 9 | 10 | // Convert XY to (0, 1) 11 | // Y is flipped because texture coords are Y-down. 12 | shadowCoords = vec3( 13 | shadowCoords.xy * vec2(0.5, -0.5) + vec2(0.5), 14 | shadowCoords.z 15 | ); 16 | 17 | return getPCFBaseShadowContribution( 18 | shadowCoords, 19 | spotShadow.pcfSamples, 20 | spotShadow.bias, 21 | spotShadow.intensity, 22 | depthTexture 23 | ); 24 | } 25 | ` 26 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/get-fragment-input-struct.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry' 2 | import { getVertexOutputStructContent } from '../../vertex/head/get-vertex-output-struct-content' 3 | import { VertexShaderInputParams } from '../../../full/vertex/get-vertex-shader-code' 4 | 5 | /** 6 | * Get the fragment shader WGSL input struct using {@link getVertexOutputStructContent}. 7 | * @param parameters - Parameters used to generate the fragment shader WGSL input struct. 8 | * @param parameters.geometry - {@link Geometry} used to generate the struct from its attributes. 9 | * @param parameters.additionalVaryings - Optional additional {@link VertexShaderInputParams.additionalVaryings | varyings} passed from the vertex shader to the fragment shader. 10 | * @returns - String with the fragment shader WGSL input struct. 11 | */ 12 | export const getFragmentInputStruct = ({ 13 | geometry, 14 | additionalVaryings = [], 15 | }: { 16 | geometry: Geometry 17 | additionalVaryings?: VertexShaderInputParams['additionalVaryings'] 18 | }): string => { 19 | return /* wgsl */ ` 20 | struct FSInput { 21 | @builtin(front_facing) frontFacing: bool, 22 | ${getVertexOutputStructContent({ geometry, additionalVaryings })} 23 | };` 24 | } 25 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/get-lambert-direct.ts: -------------------------------------------------------------------------------- 1 | /** Helper function chunk appended internally and used to compute Lambert direct light contributions. */ 2 | export const getLambertDirect = /* wgsl */ ` 3 | fn getLambertDirect( 4 | normal: vec3f, 5 | diffuseColor: vec3f, 6 | directLight: DirectLight, 7 | ptr_reflectedLight: ptr 8 | ) { 9 | let NdotL = saturate(dot(normal, directLight.direction)); 10 | 11 | let irradiance: vec3f = NdotL * directLight.color; 12 | (*ptr_reflectedLight).directDiffuse += irradiance * BRDF_Lambert( diffuseColor ); 13 | } 14 | ` 15 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/get-uv-cover-helper.ts: -------------------------------------------------------------------------------- 1 | /** Applies given texture matrix (`mat4x4f`) to given uv coordinates (`vec2f`). */ 2 | export const getUVCover = /* wgsl */ ` 3 | fn getUVCover(uv: vec2f, textureMatrix: mat3x3f) -> vec2f { 4 | return (textureMatrix * vec3f(uv, 1.0)).xy; 5 | }` 6 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/fragment/head/get-vertex-to-UV-coords-helpers.ts: -------------------------------------------------------------------------------- 1 | /** Convert vertex position as `vec2f` or `vec3f` to uv coordinates `vec2f`. */ 2 | export const getVertexToUVCoords = /* wgsl */ ` 3 | fn getVertex2DToUVCoords(vertex: vec2f) -> vec2f { 4 | return vec2( 5 | vertex.x * 0.5 + 0.5, 6 | 0.5 - vertex.y * 0.5 7 | ); 8 | } 9 | 10 | fn getVertex3DToUVCoords(vertex: vec3f) -> vec2f { 11 | return getVertex2DToUVCoords( vec2(vertex.x, vertex.y) ); 12 | } 13 | ` 14 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/utils/BRDF_GGX.ts: -------------------------------------------------------------------------------- 1 | /** WGSL BRDF GGX functions. Need the `constants` and `common` chunks. */ 2 | export const BRDF_GGX = /* wgsl */ ` 3 | fn DistributionGGX(NdotH: f32, roughness: f32) -> f32 { 4 | let a: f32 = pow2( roughness ); 5 | let a2: f32 = pow2( a ); 6 | 7 | let denom: f32 = (pow2( NdotH ) * (a2 - 1.0) + 1.0); 8 | 9 | return RECIPROCAL_PI * a2 / ( pow2( denom ) ); 10 | } 11 | 12 | fn GeometrySmith(NdotL: f32, NdotV: f32, roughness: f32) -> f32 { 13 | let a: f32 = pow2( roughness ); 14 | let a2: f32 = pow2( a ); 15 | 16 | let gv: f32 = NdotL * sqrt( a2 + ( 1.0 - a2 ) * pow2( NdotV ) ); 17 | let gl: f32 = NdotV * sqrt( a2 + ( 1.0 - a2 ) * pow2( NdotL ) ); 18 | 19 | return 0.5 / max( gv + gl, EPSILON ); 20 | } 21 | 22 | fn BRDF_GGX( 23 | NdotV: f32, 24 | NdotL: f32, 25 | NdotH: f32, 26 | VdotH: f32, 27 | roughness: f32, 28 | specularFactor: f32, 29 | specularColor: vec3f 30 | ) -> vec3f { 31 | // cook-torrance brdf 32 | let G: f32 = GeometrySmith(NdotL, NdotV, roughness); 33 | let D: f32 = DistributionGGX(NdotH, roughness); 34 | let F: vec3f = F_Schlick(specularColor, specularFactor, VdotH); 35 | 36 | return G * D * F; 37 | } 38 | ` 39 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/utils/common.ts: -------------------------------------------------------------------------------- 1 | /** Common WGSL functions and struct declarations to use for light shading. */ 2 | export const common = /* wgsl */ ` 3 | fn lessThan3(a: vec3f, b: vec3f) -> vec3f { 4 | return vec3f(vec3(a.x < b.x, a.y < b.y, a.z < b.z)); 5 | } 6 | 7 | fn pow2( x: f32 ) -> f32 { 8 | return x * x; 9 | } 10 | 11 | fn pow3( x: f32 ) -> f32 { 12 | return x * x * x; 13 | } 14 | 15 | fn pow4( x: f32 ) -> f32 { 16 | return pow2(x) * pow2(x); 17 | } 18 | 19 | fn isinf(value: f32) -> bool { 20 | return value > 1.0e38 || value < -1.0e38; 21 | } 22 | 23 | fn BRDF_Lambert(diffuseColor: vec3f) -> vec3f { 24 | return RECIPROCAL_PI * diffuseColor; 25 | } 26 | 27 | fn F_Schlick(f0: vec3f, f90: f32, VdotH: f32) -> vec3f { 28 | let fresnel: f32 = exp2( ( - 5.55473 * VdotH - 6.98316 ) * VdotH ); 29 | return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel ); 30 | } 31 | ` 32 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/utils/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants to use in shadings. 3 | */ 4 | export const constants = /* wgsl */ ` 5 | const PI = ${Math.PI}; 6 | const RECIPROCAL_PI = ${1 / Math.PI}; 7 | const RECIPROCAL_PI2 = ${0.5 / Math.PI}; 8 | const EPSILON = 1e-6;` 9 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/utils/generate-TBN.ts: -------------------------------------------------------------------------------- 1 | /** WGSL function to generate a tangent bitangent normal coordinate frame from the normal. */ 2 | export const generateTBN = /* wgsl */ ` 3 | // TBN generates a tangent bitangent normal coordinate frame from the normal 4 | // (the normal must be normalized) 5 | fn generateTBN(normal: vec3f) -> mat3x3f { 6 | var bitangent: vec3f = vec3(0.0, 1.0, 0.0); 7 | 8 | let NdotUp: f32 = dot(normal, vec3(0.0, 1.0, 0.0)); 9 | 10 | if (1.0 - abs(NdotUp) <= EPSILON) { 11 | // Sampling +Y or -Y, so we need a more robust bitangent. 12 | if (NdotUp > 0.0) { 13 | bitangent = vec3(0.0, 0.0, 1.0); 14 | } 15 | else { 16 | bitangent = vec3(0.0, 0.0, -1.0); 17 | } 18 | } 19 | 20 | let tangent: vec3f = normalize(cross(bitangent, normal)); 21 | bitangent = cross(normal, tangent); 22 | 23 | return mat3x3f(tangent, bitangent, normal); 24 | } 25 | ` 26 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/utils/hammersley-2D.ts: -------------------------------------------------------------------------------- 1 | /** Hammersley 2D WGSL function. */ 2 | export const hammersley2D = /* wgsl */ ` 3 | fn radicalInverse_VdC(inputBits: u32) -> f32 { 4 | var bits: u32 = inputBits; 5 | bits = (bits << 16u) | (bits >> 16u); 6 | bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); 7 | bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); 8 | bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); 9 | bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); 10 | return f32(bits) * 2.3283064365386963e-10; // / 0x100000000 11 | } 12 | 13 | // hammersley2d describes a sequence of points in the 2d unit square [0,1)^2 14 | // that can be used for quasi Monte Carlo integration 15 | fn hammersley2d(i: u32, N: u32) -> vec2f { 16 | return vec2(f32(i) / f32(N), radicalInverse_VdC(i)); 17 | } 18 | ` 19 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/vertex/body/declare-attributes-vars.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry' 2 | 3 | /** 4 | * Declare all the provided {@link Geometry} attributes as variables. 5 | * @param parameters - Parameters used to declare the attributes variables. 6 | * @param parameters.geometry - {@link Geometry} used to declare the attributes variables. 7 | * @returns - A string with all the attributes variables declared. 8 | */ 9 | export const declareAttributesVars = ({ geometry }: { geometry: Geometry }): string => { 10 | let attributeVars = geometry.vertexBuffers 11 | .map((vertexBuffer) => 12 | vertexBuffer.attributes 13 | .map((attribute) => { 14 | return /* wgsl */ ` 15 | var ${attribute.name}: ${attribute.type} = attributes.${attribute.name};` 16 | }) 17 | .join('') 18 | ) 19 | .join('\n') 20 | 21 | attributeVars += /* wgsl */ ` 22 | var instanceIndex: u32 = attributes.instanceIndex; 23 | ` 24 | 25 | return attributeVars 26 | } 27 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/vertex/head/get-normal-helpers.ts: -------------------------------------------------------------------------------- 1 | /** Get `normal` (`vec3f`) in world or view space. */ 2 | export const getNormalHelpers = /* wgsl */ ` 3 | fn getWorldNormal(normal: vec3f) -> vec3f { 4 | return normalize(matrices.normal * normal); 5 | } 6 | 7 | fn getViewNormal(normal: vec3f) -> vec3f { 8 | return normalize((camera.view * vec4(matrices.normal * normal, 0.0)).xyz); 9 | }` 10 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/vertex/head/get-position-helpers.ts: -------------------------------------------------------------------------------- 1 | /** Get output `position` (`vec4f`) vector by applying model view projection matrix to the attribute `position` (`vec3f`) vector. */ 2 | export const getPositionHelpers = /* wgsl */ ` 3 | fn getWorldPosition(position: vec3f) -> vec4f { 4 | return matrices.model * vec4f(position, 1.0); 5 | } 6 | 7 | fn getOutputPosition(position: vec3f) -> vec4f { 8 | return camera.projection * camera.view * matrices.model * vec4f(position, 1.0); 9 | }` 10 | -------------------------------------------------------------------------------- /src/core/shaders/chunks/vertex/head/get-vertex-output-struct.ts: -------------------------------------------------------------------------------- 1 | import { Geometry } from '../../../../geometries/Geometry' 2 | import { getVertexOutputStructContent } from './get-vertex-output-struct-content' 3 | import { VertexShaderInputParams } from '../../../full/vertex/get-vertex-shader-code' 4 | 5 | /** 6 | * Get the vertex shader WGSL output struct using {@link getVertexOutputStructContent}. 7 | * @param parameters - Parameters used to generate the vertex shader WGSL output struct. 8 | * @param parameters.geometry - {@link Geometry} used to generate the struct from its attributes. 9 | * @param parameters.additionalVaryings - Optional additional {@link VertexShaderInputParams.additionalVaryings | varyings} to pass from the vertex shader to the fragment shader. 10 | * @returns - String with the vertex shader WGSL output struct. 11 | */ 12 | export const getVertexOutputStruct = ({ 13 | geometry, 14 | additionalVaryings = [], 15 | }: { 16 | geometry: Geometry 17 | additionalVaryings?: VertexShaderInputParams['additionalVaryings'] 18 | }): string => { 19 | return /* wgsl */ ` 20 | struct VSOutput { 21 | ${getVertexOutputStructContent({ geometry, additionalVaryings })} 22 | };` 23 | } 24 | -------------------------------------------------------------------------------- /src/core/shaders/full/fragment/get-default-fragment-code.ts: -------------------------------------------------------------------------------- 1 | /** Default fragment shader code that outputs only black pixels. */ 2 | export const getDefaultFragmentCode = /* wgsl */ ` 3 | @fragment fn main() -> @location(0) vec4f { 4 | return vec4(0.0, 0.0, 0.0, 1.0); 5 | }` 6 | -------------------------------------------------------------------------------- /src/core/shaders/full/fragment/get-default-normal-fragment-code.ts: -------------------------------------------------------------------------------- 1 | /** Default fragment shader code that outputs mesh's normal. */ 2 | export const getDefaultNormalFragmentCode = /* wgsl */ ` 3 | struct VSOutput { 4 | @builtin(position) position: vec4f, 5 | @location(0) uv: vec2f, 6 | @location(1) normal: vec3f, 7 | }; 8 | 9 | @fragment fn main(fsInput: VSOutput) -> @location(0) vec4f { 10 | // normals 11 | return vec4(normalize(fsInput.normal) * 0.5 + 0.5, 1.0); 12 | }` 13 | -------------------------------------------------------------------------------- /src/core/shaders/full/fragment/get-default-point-shadow-depth-fragment-code.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Get {@link core/lights/PointLight.PointLight | PointLight} shadow map pass fragment shader. 3 | * @param lightIndex - Index of the {@link core/lights/PointLight.PointLight | PointLight} for which to render the depth pass. 4 | */ 5 | export const getDefaultPointShadowDepthFs = (lightIndex = 0): string => /* wgsl */ ` 6 | struct PointShadowVSOutput { 7 | @builtin(position) position: vec4f, 8 | @location(0) worldPosition: vec3f, 9 | } 10 | 11 | @fragment fn main(fsInput: PointShadowVSOutput) -> @builtin(frag_depth) f32 { 12 | let pointShadow: PointShadowsElement = pointShadows.pointShadowsElements[${lightIndex}]; 13 | 14 | // get distance between fragment and light source 15 | var lightDistance: f32 = length(fsInput.worldPosition - pointShadow.position); 16 | 17 | // map to [0, 1] range by dividing by far plane - near plane 18 | lightDistance = (lightDistance - pointShadow.cameraNear) / (pointShadow.cameraFar - pointShadow.cameraNear); 19 | 20 | // write this as modified depth 21 | return saturate(lightDistance); 22 | }` 23 | -------------------------------------------------------------------------------- /src/core/shaders/full/fragment/get-default-shader-pass-fragment-code.ts: -------------------------------------------------------------------------------- 1 | /** Default fragment shader code to use with {@link core/renderPasses/ShaderPass.ShaderPass | ShaderPass} that outputs the content of the pass `renderTexture` as is. */ 2 | export const getDefaultShaderPassFragmentCode = /* wgsl */ ` 3 | struct VSOutput { 4 | @builtin(position) position: vec4f, 5 | @location(0) uv: vec2f, 6 | }; 7 | 8 | @fragment fn main(fsInput: VSOutput) -> @location(0) vec4f { 9 | return textureSample(renderTexture, defaultSampler, fsInput.uv); 10 | }` 11 | -------------------------------------------------------------------------------- /src/core/shaders/full/vertex/get-default-projected-vertex-shader-code.ts: -------------------------------------------------------------------------------- 1 | /** Default vertex shader code for projected meshes. */ 2 | export const getDefaultProjectedVertexShaderCode = /* wgsl */ ` 3 | struct VSOutput { 4 | @builtin(position) position: vec4f, 5 | @location(0) uv: vec2f, 6 | @location(1) normal: vec3f, 7 | @location(2) worldPosition: vec3f, 8 | @location(3) viewDirection: vec3f, 9 | }; 10 | 11 | @vertex fn main( 12 | attributes: Attributes, 13 | ) -> VSOutput { 14 | var vsOutput: VSOutput; 15 | 16 | vsOutput.position = getOutputPosition(attributes.position); 17 | vsOutput.uv = attributes.uv; 18 | vsOutput.normal = getWorldNormal(attributes.normal); 19 | let worldPosition: vec4f = getWorldPosition(attributes.position); 20 | vsOutput.worldPosition = worldPosition.xyz / worldPosition.w; 21 | vsOutput.viewDirection = camera.position - vsOutput.worldPosition; 22 | 23 | return vsOutput; 24 | }` 25 | -------------------------------------------------------------------------------- /src/core/shaders/full/vertex/get-default-vertex-shader-code.ts: -------------------------------------------------------------------------------- 1 | /** Default vertex shader code for unprojected meshes (such as {@link core/meshes/FullscreenPlane.FullscreenPlane | FullscreenPlane} or {@link core/renderPasses/ShaderPass.ShaderPass | ShaderPass}). */ 2 | export const getDefaultVertexShaderCode = /* wgsl */ ` 3 | struct VSOutput { 4 | @builtin(position) position: vec4f, 5 | @location(0) uv: vec2f, 6 | }; 7 | 8 | @vertex fn main( 9 | attributes: Attributes, 10 | ) -> VSOutput { 11 | var vsOutput: VSOutput; 12 | 13 | vsOutput.position = vec4f(attributes.position, 1.0); 14 | vsOutput.uv = attributes.uv; 15 | 16 | return vsOutput; 17 | }` 18 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | export * from './gltf/GLTF' 4 | export * from './gltf/GLTFExtensions' 5 | export * from './gltf/GLTFScenesManager' 6 | export * from './BindGroups' 7 | export * from './Geometries' 8 | export * from './Materials' 9 | export * from './PipelineEntries' 10 | export * from './BindGroups' 11 | export * from './Textures' 12 | -------------------------------------------------------------------------------- /src/utils/webgpu-constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GPUShaderStage constants with fallbacks. 3 | */ 4 | export const WebGPUShaderStageConstants: Record = 5 | typeof GPUShaderStage !== 'undefined' 6 | ? GPUShaderStage 7 | : { 8 | VERTEX: 1, 9 | FRAGMENT: 2, 10 | COMPUTE: 4, 11 | } 12 | 13 | /** 14 | * GPUBufferUsage constants with fallbacks. 15 | */ 16 | export const WebGPUBufferUsageConstants: Record = 17 | typeof GPUBufferUsage !== 'undefined' 18 | ? GPUBufferUsage 19 | : { 20 | MAP_READ: 1, 21 | MAP_WRITE: 2, 22 | COPY_SRC: 4, 23 | COPY_DST: 8, 24 | INDEX: 16, 25 | VERTEX: 32, 26 | UNIFORM: 64, 27 | STORAGE: 128, 28 | INDIRECT: 256, 29 | QUERY_RESOLVE: 512, 30 | } 31 | 32 | /** 33 | * GPUTextureUsage constants with fallbacks. 34 | */ 35 | export const WebGPUTextureUsageConstants: Record = 36 | typeof GPUTextureUsage !== 'undefined' 37 | ? GPUTextureUsage 38 | : { 39 | COPY_SRC: 1, 40 | COPY_DST: 2, 41 | TEXTURE_BINDING: 4, 42 | STORAGE_BINDING: 8, 43 | RENDER_ATTACHMENT: 16, 44 | } 45 | -------------------------------------------------------------------------------- /tests/basic-rotating-cube/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Basic rotating cube test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/basic-rotating-cube/main.js: -------------------------------------------------------------------------------- 1 | // Basic rotating cube for most simple tests 2 | window.addEventListener('load', async () => { 3 | const path = location.hostname === 'localhost' ? '../../src/index.ts' : '../../dist/esm/index.mjs' 4 | const { BoxGeometry, GPUCameraRenderer, GPUDeviceManager, Mesh } = await import(/* @vite-ignore */ path) 5 | 6 | // create a device manager 7 | const gpuDeviceManager = new GPUDeviceManager({ 8 | label: 'Custom device manager', 9 | adapterOptions: { 10 | featureLevel: 'compatibility', 11 | }, 12 | }) 13 | 14 | // wait for the device to be created 15 | await gpuDeviceManager.init() 16 | 17 | // create a camera renderer 18 | const gpuCameraRenderer = new GPUCameraRenderer({ 19 | deviceManager: gpuDeviceManager, 20 | container: document.querySelector('#canvas'), 21 | //pixelRatio: window.devicePixelRatio, 22 | }) 23 | 24 | const mesh = new Mesh(gpuCameraRenderer, { 25 | label: 'Cube', 26 | geometry: new BoxGeometry(), 27 | }) 28 | 29 | mesh.onBeforeRender(() => { 30 | mesh.rotation.y += 0.02 31 | }) 32 | 33 | console.log(mesh) 34 | }) 35 | -------------------------------------------------------------------------------- /tests/bindings-offsets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Buffer layout debug 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 | 22 |
23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/camera/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Camera debug & tests 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/camera/styles.css: -------------------------------------------------------------------------------- 1 | .mesh-bounding-box { 2 | position: fixed; 3 | box-sizing: border-box; 4 | border-width: 2px; 5 | border-style: solid; 6 | } 7 | -------------------------------------------------------------------------------- /tests/canvas-resizing/styles.css: -------------------------------------------------------------------------------- 1 | #page { 2 | position: relative; 3 | min-height: 0; 4 | z-index: 2; 5 | display: grid; 6 | grid-template-columns: repeat(2, minmax(0, 1fr)); 7 | grid-gap: 0.5rem; 8 | background: var(--light-color); 9 | } 10 | 11 | .canvas { 12 | width: 100%; 13 | height: 50vh; 14 | background: rgba(var(--dark-color-rgb), 0.5); 15 | position: relative; 16 | } 17 | 18 | .canvas[data-fixed-size] { 19 | height: auto; 20 | aspect-ratio: 1; 21 | } 22 | 23 | .canvas::before { 24 | content: 'Pixel ratio: ' attr(data-pixel-ratio) ', auto resize: ' attr(data-auto-resize) 25 | ', should use window resize: ' attr(data-should-resize); 26 | position: absolute; 27 | top: 0; 28 | left: 0; 29 | font-size: 0.75rem; 30 | padding: 0.25em 0.5em; 31 | background: var(--secondary-color); 32 | } 33 | 34 | .canvas[data-fixed-size]::before { 35 | content: 'Pixel ratio: ' attr(data-pixel-ratio) ', auto resize: ' attr(data-auto-resize) ', should resize: ' 36 | attr(data-should-resize) ', fixed size: ' attr(data-fixed-size); 37 | } 38 | 39 | .canvas canvas { 40 | background: var(--dark-color); 41 | } 42 | -------------------------------------------------------------------------------- /tests/compute-results/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Compute pass result test 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 | 22 |
23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/compute-results/styles.css: -------------------------------------------------------------------------------- 1 | #page { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | } 6 | -------------------------------------------------------------------------------- /tests/context-lost/styles.css: -------------------------------------------------------------------------------- 1 | #lose-context-button { 2 | position: relative; 3 | top: 1rem; 4 | left: 1rem; 5 | } 6 | 7 | .plane { 8 | position: absolute; 9 | top: 10vh; 10 | top: 10 svh; 11 | left: 10%; 12 | width: 80%; 13 | height: 80vh; 14 | height: 80 svh; 15 | } 16 | -------------------------------------------------------------------------------- /tests/cubemap-env/styles.css: -------------------------------------------------------------------------------- 1 | #credits { 2 | position: absolute; 3 | left: 1rem; 4 | bottom: 1rem; 5 | font-size: 0.75rem; 6 | } 7 | -------------------------------------------------------------------------------- /tests/dynamic-materials-geometries/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Dynamic materials and geometries tests 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/frustum-culling/styles.css: -------------------------------------------------------------------------------- 1 | #shuffle-button { 2 | position: absolute; 3 | bottom: 1rem; 4 | left: 1rem; 5 | font-size: 0.875rem; 6 | z-index: 1; 7 | } 8 | 9 | .bounding-box { 10 | position: fixed; 11 | box-sizing: border-box; 12 | font-size: 0.5rem; 13 | color: var(--color, white); 14 | border: 1px solid var(--color, white); 15 | } 16 | 17 | .bounding-box::after { 18 | position: absolute; 19 | top: 0.1em; 20 | left: 0.2em; 21 | } 22 | 23 | .sphere-bounding-box { 24 | --color: green; 25 | } 26 | 27 | .sphere-bounding-box::after { 28 | content: 'sphere'; 29 | } 30 | 31 | .obb-bounding-box { 32 | --color: red; 33 | } 34 | 35 | .obb-bounding-box::after { 36 | content: 'OBB'; 37 | } 38 | -------------------------------------------------------------------------------- /tests/gltf-loader/styles.css: -------------------------------------------------------------------------------- 1 | .stats { 2 | transform-origin: 0 0; 3 | transform: scale3d(2, 2, 1); 4 | } 5 | 6 | #canvas::after { 7 | content: 'Loading'; 8 | position: fixed; 9 | z-index: 1; 10 | top: 0; 11 | right: 0; 12 | bottom: 0; 13 | left: 0; 14 | pointer-events: none; 15 | display: flex; 16 | justify-content: center; 17 | align-items: center; 18 | opacity: 0; 19 | transition: opacity 0.35s; 20 | } 21 | 22 | #canvas.loading::after { 23 | opacity: 1; 24 | } 25 | 26 | #credits { 27 | position: absolute; 28 | left: 1rem; 29 | bottom: 1rem; 30 | font-size: 0.75rem; 31 | } 32 | -------------------------------------------------------------------------------- /tests/gltf-shadows/assets/cannon_1k.hdr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/tests/gltf-shadows/assets/cannon_1k.hdr -------------------------------------------------------------------------------- /tests/gltf-shadows/assets/lut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/tests/gltf-shadows/assets/lut.png -------------------------------------------------------------------------------- /tests/gltf-shadows/styles.css: -------------------------------------------------------------------------------- 1 | .stats { 2 | transform-origin: 0 0; 3 | transform: scale3d(2, 2, 1); 4 | } 5 | 6 | #canvas::after { 7 | content: 'Loading'; 8 | position: fixed; 9 | z-index: 1; 10 | top: 0; 11 | right: 0; 12 | bottom: 0; 13 | left: 0; 14 | pointer-events: none; 15 | display: flex; 16 | justify-content: center; 17 | align-items: center; 18 | opacity: 0; 19 | transition: opacity 0.35s; 20 | } 21 | 22 | #canvas.loading::after { 23 | opacity: 1; 24 | } 25 | 26 | #credits { 27 | position: absolute; 28 | text-align: right; 29 | right: 1rem; 30 | bottom: 1rem; 31 | font-size: 0.75rem; 32 | } 33 | -------------------------------------------------------------------------------- /tests/gltf-skins-shadows/styles.css: -------------------------------------------------------------------------------- 1 | #canvas::after { 2 | content: 'Loading'; 3 | position: fixed; 4 | z-index: 1; 5 | top: 0; 6 | right: 0; 7 | bottom: 0; 8 | left: 0; 9 | pointer-events: none; 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | opacity: 0; 14 | transition: opacity 0.35s; 15 | } 16 | 17 | #canvas.loading::after { 18 | opacity: 1; 19 | } 20 | 21 | #credits { 22 | position: absolute; 23 | left: 1rem; 24 | bottom: 1rem; 25 | font-size: 0.75rem; 26 | } 27 | -------------------------------------------------------------------------------- /tests/lights/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Lights test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/lit-meshes/styles.css: -------------------------------------------------------------------------------- 1 | .stats { 2 | transform-origin: 0 0; 3 | transform: scale3d(2, 2, 1); 4 | } 5 | 6 | #canvas::after { 7 | content: 'Loading'; 8 | position: fixed; 9 | z-index: 1; 10 | top: 0; 11 | right: 0; 12 | bottom: 0; 13 | left: 0; 14 | pointer-events: none; 15 | display: flex; 16 | justify-content: center; 17 | align-items: center; 18 | opacity: 0; 19 | transition: opacity 0.35s; 20 | } 21 | 22 | #canvas.loading::after { 23 | opacity: 1; 24 | } 25 | 26 | #credits { 27 | position: absolute; 28 | left: 1rem; 29 | bottom: 1rem; 30 | font-size: 0.75rem; 31 | } 32 | -------------------------------------------------------------------------------- /tests/multiple-canvases/styles.css: -------------------------------------------------------------------------------- 1 | #canvas-front { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | height: 100vh; 6 | /* prettier-ignore */ 7 | height: 100svh; 8 | width: 100vw; 9 | z-index: 3; 10 | pointer-events: none; 11 | } 12 | 13 | #canvas-back { 14 | position: fixed; 15 | top: 0; 16 | left: 0; 17 | height: 100vh; 18 | /* prettier-ignore */ 19 | height: 100svh; 20 | width: 100vw; 21 | z-index: 1; 22 | pointer-events: none; 23 | } 24 | 25 | #page { 26 | position: relative; 27 | z-index: 2; 28 | display: flex; 29 | justify-content: center; 30 | align-items: center; 31 | } 32 | 33 | #buttons { 34 | position: absolute; 35 | top: 0; 36 | right: 0; 37 | bottom: 0; 38 | left: 0; 39 | padding: 1rem; 40 | display: flex; 41 | flex-direction: column; 42 | justify-content: flex-start; 43 | align-items: flex-start; 44 | pointer-events: none; 45 | } 46 | 47 | #buttons button { 48 | pointer-events: auto; 49 | margin: 0 1rem 1rem 0; 50 | } 51 | 52 | #page h1 { 53 | margin: 0; 54 | padding: 0; 55 | font-size: 3rem; 56 | } 57 | -------------------------------------------------------------------------------- /tests/offscreen-canvas/init.js: -------------------------------------------------------------------------------- 1 | let renderer 2 | 3 | export const init = async ({ canvas, label, width, height, top = 0, left = 0, pixelRatio, isLocal = false }) => { 4 | const path = isLocal ? '../../src/index.ts' : '../../dist/esm/index.mjs' 5 | const { GPUDeviceManager, GPUCameraRenderer, BoxGeometry, Mesh } = await import(/* @vite-ignore */ path) 6 | 7 | const deviceManager = new GPUDeviceManager() 8 | 9 | await deviceManager.init() 10 | 11 | renderer = new GPUCameraRenderer({ 12 | deviceManager, 13 | label, 14 | container: canvas, 15 | pixelRatio, 16 | autoResize: false, 17 | }) 18 | 19 | if (width && height) { 20 | renderer.resize({ width, height, top, left }) 21 | } 22 | 23 | console.log(renderer) 24 | 25 | const mesh = new Mesh(renderer, { 26 | geometry: new BoxGeometry(), 27 | }) 28 | 29 | mesh.onBeforeRender(() => { 30 | mesh.rotation.y += 0.01 31 | mesh.rotation.z += 0.01 32 | }) 33 | } 34 | 35 | export const resize = ({ width, height, top = 0, left = 0 }) => { 36 | renderer?.resize({ width, height, top, left }) 37 | } 38 | -------------------------------------------------------------------------------- /tests/offscreen-canvas/styles.css: -------------------------------------------------------------------------------- 1 | #page { 2 | /* prettier-ignore */ 3 | height: 100svh; 4 | display: grid; 5 | grid-template-columns: repeat(2, minmax(0, 1fr)); 6 | grid-gap: 0.5rem; 7 | background: var(--light-color); 8 | } 9 | 10 | .canvas-container { 11 | display: flex; 12 | position: relative; 13 | } 14 | 15 | .canvas { 16 | display: block; 17 | position: absolute; 18 | top: 0; 19 | left: 0; 20 | width: 100%; 21 | height: 100%; 22 | background: var(--dark-color); 23 | } 24 | 25 | #jank-button { 26 | position: absolute; 27 | top: 1rem; 28 | left: 1rem; 29 | z-index: 1; 30 | } 31 | 32 | #jank-result { 33 | position: absolute; 34 | bottom: 0; 35 | left: 0; 36 | z-index: 1; 37 | padding: 0.25em 0.5em; 38 | background: var(--secondary-color); 39 | } 40 | -------------------------------------------------------------------------------- /tests/offscreen-canvas/worker.js: -------------------------------------------------------------------------------- 1 | import { init, resize } from './init.js' 2 | 3 | self.onmessage = function (message) { 4 | const { data } = message 5 | const { type } = data 6 | if (type === 'init') { 7 | const { canvas, label, width, height, top, left, pixelRatio, isLocal } = data 8 | init({ canvas, label, width, height, top, left, pixelRatio, isLocal }) 9 | } else if (type === 'resize') { 10 | const { width, height, top, left } = data 11 | resize({ width, height, top, left }) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/orbit-camera-depth-texture/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Orbit camera + depth textures basic test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/orbit-camera-selective-passes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Orbit camera basic test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/orbit-controls/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Orbit controls tests 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/order-independent-transparency/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Weighted, blended order-independent transparency proof of concept 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/plane-transformations/styles.css: -------------------------------------------------------------------------------- 1 | .plane { 2 | position: fixed; 3 | width: 50%; 4 | height: 50vh; 5 | top: 25vh; 6 | left: 25%; 7 | } 8 | 9 | .mesh-bounding-box { 10 | position: fixed; 11 | box-sizing: border-box; 12 | border-width: 2px; 13 | border-style: solid; 14 | } 15 | -------------------------------------------------------------------------------- /tests/post-processing-input-output/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Post-processing input/output test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/post-processing-passes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Post processing passes test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/raycaster/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Raycaster test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/reflections/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Reflections test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/render-bundles/styles.css: -------------------------------------------------------------------------------- 1 | #lose-context-button { 2 | position: relative; 3 | top: 1rem; 4 | left: 1rem; 5 | } 6 | -------------------------------------------------------------------------------- /tests/reset-plane/styles.css: -------------------------------------------------------------------------------- 1 | #page { 2 | display: flex; 3 | align-items: center; 4 | } 5 | 6 | #switch-plane { 7 | position: absolute; 8 | top: 1rem; 9 | left: 1rem; 10 | } 11 | 12 | #planes { 13 | display: grid; 14 | grid-template-columns: repeat(2, [col-start] 1fr); 15 | column-gap: 25vw; 16 | row-gap: 25vh; 17 | width: 100%; 18 | align-items: center; 19 | } 20 | 21 | #first-plane { 22 | aspect-ratio: 0.5; 23 | margin: 0 15%; 24 | } 25 | 26 | #second-plane { 27 | aspect-ratio: 1.5; 28 | } 29 | -------------------------------------------------------------------------------- /tests/scene-graph/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Scene graph debug & tests 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/scroll-resize/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | #mesh-container { 3 | position: relative; 4 | width: 100%; 5 | overflow: hidden; 6 | } 7 | 8 | .dom-mesh { 9 | width: 25%; 10 | aspect-ratio: 1; 11 | margin: 40vh auto; 12 | box-sizing: border-box; 13 | border: 2px solid var(--primary-color); 14 | position: relative; 15 | 16 | justify-content: center; 17 | align-items: center; 18 | align-content: center; 19 | } 20 | 21 | .dom-mesh h2 { 22 | position: absolute; 23 | top: 50%; 24 | right: 0; 25 | left: 0; 26 | transform: translate3d(0, -50%, 0); 27 | margin: 0; 28 | text-align: center; 29 | } 30 | 31 | #large-cube-mesh { 32 | width: 75%; 33 | aspect-ratio: 2.5 / 1; 34 | } 35 | 36 | .dom-mesh img { 37 | display: none; 38 | min-width: 100%; 39 | min-height: 100%; 40 | object-fit: cover; 41 | } 42 | } 43 | 44 | @media screen and (orientation: portrait) { 45 | .dom-mesh { 46 | width: 66%; 47 | } 48 | 49 | #large-cube-mesh { 50 | width: 90%; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/shadow-mapping/styles.css: -------------------------------------------------------------------------------- 1 | .stats { 2 | transform-origin: 0 0; 3 | transform: scale3d(2, 2, 1); 4 | } 5 | -------------------------------------------------------------------------------- /tests/stencil-test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Stencil tests 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/stress-test-instanced/styles.css: -------------------------------------------------------------------------------- 1 | .stats { 2 | transform-origin: 0 0; 3 | transform: scale3d(2, 2, 1); 4 | } 5 | -------------------------------------------------------------------------------- /tests/stress-test-render-bundle/styles.css: -------------------------------------------------------------------------------- 1 | .stats { 2 | transform-origin: 0 0; 3 | transform: scale3d(2, 2, 1); 4 | } 5 | -------------------------------------------------------------------------------- /tests/stress-test/styles.css: -------------------------------------------------------------------------------- 1 | .stats { 2 | transform-origin: 0 0; 3 | transform: scale3d(2, 2, 1); 4 | } 5 | -------------------------------------------------------------------------------- /tests/textures-dom-textures/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | .meshes-container { 3 | display: flex; 4 | flex-wrap: wrap; 5 | margin: 2.5rem 0; 6 | } 7 | 8 | .meshes-container .mesh-container { 9 | flex-basis: calc(100% / 3); 10 | padding: 0 7.5%; 11 | box-sizing: border-box; 12 | } 13 | 14 | .mesh { 15 | aspect-ratio: 1; 16 | } 17 | 18 | .mesh img, 19 | .mesh video, 20 | .mesh canvas { 21 | display: none; 22 | } 23 | 24 | #slideshow { 25 | width: 75%; 26 | margin: 0 auto; 27 | aspect-ratio: 2; 28 | } 29 | 30 | #slideshow.is-waiting { 31 | cursor: wait; 32 | } 33 | } 34 | 35 | @media screen and (orientation: portrait) { 36 | } 37 | -------------------------------------------------------------------------------- /tests/textures-external-textures/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | .meshes-container { 3 | display: flex; 4 | flex-wrap: wrap; 5 | margin: 2.5rem 0; 6 | } 7 | 8 | .meshes-container .mesh-container { 9 | flex-basis: calc(100% / 3); 10 | padding: 2rem; 11 | box-sizing: border-box; 12 | } 13 | 14 | .mesh { 15 | aspect-ratio: 1; 16 | } 17 | 18 | .mesh img, 19 | .mesh video, 20 | .mesh canvas { 21 | display: none; 22 | } 23 | } 24 | 25 | @media screen and (orientation: portrait) { 26 | } 27 | -------------------------------------------------------------------------------- /tests/textures-media-textures/styles.css: -------------------------------------------------------------------------------- 1 | @media screen { 2 | .meshes-container { 3 | display: flex; 4 | margin: 2.5rem 0; 5 | } 6 | 7 | .meshes-container .mesh-container { 8 | flex-basis: calc(100% / 3); 9 | margin: 0 7.5%; 10 | } 11 | 12 | .mesh { 13 | aspect-ratio: 1; 14 | } 15 | } 16 | 17 | @media screen and (orientation: portrait) { 18 | } 19 | -------------------------------------------------------------------------------- /tests/textures-transformations/styles.css: -------------------------------------------------------------------------------- 1 | #planes { 2 | display: grid; 3 | grid-template-columns: repeat(2, [col-start] 1fr); 4 | column-gap: 25vw; 5 | row-gap: 25vh; 6 | } 7 | 8 | .square-plane { 9 | aspect-ratio: 1; 10 | } 11 | 12 | .landscape-plane { 13 | aspect-ratio: 15 / 10; 14 | } 15 | 16 | .portrait-plane { 17 | aspect-ratio: 10 / 15; 18 | } 19 | -------------------------------------------------------------------------------- /tests/transparent-meshes-sorting/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Transparent meshes sorting test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/umd-test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | gpu-curtains | Basic rotating cube test 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/umd-test/main.js: -------------------------------------------------------------------------------- 1 | // Basic rotating cube for most simple tests 2 | window.addEventListener('load', async () => { 3 | // create a device manager 4 | const gpuDeviceManager = new GPUDeviceManager({ 5 | label: 'Custom device manager', 6 | }) 7 | 8 | // wait for the device to be created 9 | await gpuDeviceManager.init() 10 | 11 | // create a camera renderer 12 | const gpuCameraRenderer = new GPUCameraRenderer({ 13 | deviceManager: gpuDeviceManager, 14 | container: document.querySelector('#canvas'), 15 | //pixelRatio: window.devicePixelRatio, 16 | }) 17 | 18 | const mesh = new Mesh(gpuCameraRenderer, { 19 | label: 'Cube', 20 | geometry: new BoxGeometry(), 21 | }) 22 | 23 | mesh.onBeforeRender(() => { 24 | mesh.rotation.y += 0.02 25 | }) 26 | 27 | console.log(mesh) 28 | }) 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2020", 4 | "target": "es2021", 5 | "declaration": true, 6 | "emitDeclarationOnly": true, 7 | "outDir": "./dist/types", 8 | "typeRoots": [ "./node_modules/@webgpu/types", "./node_modules/@types"], 9 | "allowJs": true, 10 | "checkJs": true, 11 | "moduleResolution": "Bundler" 12 | }, 13 | "exclude": [ 14 | "node_modules" 15 | ], 16 | "include": [ 17 | "src/**/*.ts", 18 | "src/**/*.d.ts", 19 | ] 20 | } -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://typedoc.org/schema.json", 3 | "entryPoints": [ 4 | "src/**/*.ts" 5 | ], 6 | "exclude": ["src/index.ts"], 7 | "favicon": "./website/assets/favicon.png", 8 | "out": "docs", 9 | "hideGenerator": true, 10 | "highlightLanguages": [ 11 | "bash", 12 | "console", 13 | "css", 14 | "html", 15 | "javascript", 16 | "json", 17 | "jsonc", 18 | "json5", 19 | "tsx", 20 | "typescript", 21 | "wgsl" 22 | ], 23 | "titleLink": "https://martinlaxenaire.github.io/gpu-curtains/", 24 | "navigationLinks": { 25 | "Repository": "https://github.com/martinlaxenaire/gpu-curtains", 26 | "Docs": "https://martinlaxenaire.github.io/gpu-curtains/docs/", 27 | "Examples": "https://martinlaxenaire.github.io/gpu-curtains/examples/" 28 | }, 29 | "hostedBaseUrl": "https://martinlaxenaire.github.io/gpu-curtains/docs", 30 | "plugin": ["typedoc-plugin-mdn-links"], 31 | "defaultCategory": "API", 32 | "categoryOrder": ["Tutorials", "About", "API"], 33 | "projectDocuments": ["guides/getting-started.md", "guides/core-concepts.md"], 34 | "sort": ["source-order"], 35 | "sourceLinkExternal": true, 36 | "markdownLinkExternal": true, 37 | "validation": { 38 | "notExported": true, 39 | "invalidLink": true, 40 | "notDocumented": true 41 | } 42 | } -------------------------------------------------------------------------------- /website/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/favicon.png -------------------------------------------------------------------------------- /website/assets/gltf/Suzanne.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/gltf/Suzanne.bin -------------------------------------------------------------------------------- /website/assets/gltf/Suzanne_BaseColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/gltf/Suzanne_BaseColor.png -------------------------------------------------------------------------------- /website/assets/gltf/Suzanne_MetallicRoughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/gltf/Suzanne_MetallicRoughness.png -------------------------------------------------------------------------------- /website/assets/gpu-curtains-logo-1080-720.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/gpu-curtains-logo-1080-720.jpg -------------------------------------------------------------------------------- /website/assets/gpu-curtains-logo-1080-720.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/gpu-curtains-logo-1080-720.png -------------------------------------------------------------------------------- /website/assets/gpu-curtains-logo-1920-1280.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/gpu-curtains-logo-1920-1280.jpg -------------------------------------------------------------------------------- /website/assets/gpu-curtains-logo-1920-1280.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/gpu-curtains-logo-1920-1280.png -------------------------------------------------------------------------------- /website/assets/hdr/Colorful_Studio.hdr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/hdr/Colorful_Studio.hdr -------------------------------------------------------------------------------- /website/assets/hdr/cannon_1k.hdr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martinlaxenaire/gpu-curtains/abeb156210a8b22f70da393b332dab1dea9c4c02/website/assets/hdr/cannon_1k.hdr -------------------------------------------------------------------------------- /website/js/shaders/image-plane.wgsl.js: -------------------------------------------------------------------------------- 1 | export const imagePlaneVs = /* wgsl */ ` 2 | struct VSOutput { 3 | @builtin(position) position: vec4f, 4 | @location(0) uv: vec2f, 5 | }; 6 | 7 | @vertex fn main( 8 | attributes: Attributes, 9 | ) -> VSOutput { 10 | var vsOutput: VSOutput; 11 | 12 | var transformed: vec3f = vec3( 13 | attributes.position.x, 14 | attributes.position.y, 15 | attributes.position.z - cos(3.141595 * attributes.position.y * 0.5) * deformation.strength * 2.0 16 | ); 17 | 18 | vsOutput.position = getOutputPosition(transformed); 19 | vsOutput.uv = getUVCover(attributes.uv, texturesMatrices.planeTexture.matrix); 20 | 21 | return vsOutput; 22 | } 23 | ` 24 | 25 | export const imagePlaneFs = /* wgsl */ ` 26 | struct VSOutput { 27 | @builtin(position) position: vec4f, 28 | @location(0) uv: vec2f, 29 | }; 30 | 31 | @fragment fn main(fsInput: VSOutput) -> @location(0) vec4f { 32 | var color = textureSample(planeTexture, defaultSampler, fsInput.uv); 33 | return vec4(color.rgb, color.a * global.opacity); 34 | } 35 | ` 36 | -------------------------------------------------------------------------------- /website/js/shaders/normals-opacity-fs.wgsl.js: -------------------------------------------------------------------------------- 1 | export default /* wgsl */ ` 2 | struct VSOutput { 3 | @builtin(position) position: vec4f, 4 | @location(0) uv: vec2f, 5 | @location(1) normal: vec3f, 6 | }; 7 | 8 | @fragment fn main(fsInput: VSOutput) -> @location(0) vec4f { 9 | // normals 10 | var color: vec4f = vec4(normalize(fsInput.normal) * 0.5 + 0.5, global.opacity); 11 | 12 | return color; 13 | }` 14 | --------------------------------------------------------------------------------