UNPKG

gpu-curtains

Version:

gpu-curtains is a 3D WebGPU rendering engine. It can be used as a standalone 3D engine, but also includes extra classes focused on mapping 3d objects to DOM elements; It allows users to synchronize values such as position, sizing, or scale between them.

158 lines (157 loc) 5.13 kB
import { Vec3 } from "../../math/Vec3.mjs"; import { Texture } from "../textures/Texture.mjs"; import { OrthographicCamera } from "../cameras/OrthographicCamera.mjs"; import { Shadow, shadowStruct } from "./Shadow.mjs"; import { getDefaultDirectionalShadowDepthVs } from "../shaders/full/vertex/get-default-directional-shadow-depth-vertex-shader-code.mjs"; //#region src/core/shadows/DirectionalShadow.ts /** @ignore */ const directionalShadowStruct = { ...shadowStruct, direction: { type: "vec3f", value: new Vec3() }, viewMatrix: { type: "mat4x4f", value: new Float32Array(16) }, projectionMatrix: { type: "mat4x4f", value: new Float32Array(16) } }; /** * Create a shadow map from a {@link DirectionalLight} by rendering to a depth texture using a {@link OrthographicCamera}. */ var DirectionalShadow = class extends Shadow { /** * Direction of the parent {@link DirectionalLight}. Duplicate to avoid adding the {@link DirectionalLight} binding to vertex shaders. * @private */ #direction; /** * DirectionalShadow constructor * @param renderer - {@link CameraRenderer} or {@link GPUCurtains} used to create this {@link DirectionalShadow}. * @param parameters - {@link DirectionalShadowParams} used to create this {@link DirectionalShadow}. */ constructor(renderer, { light, intensity, bias, normalBias, pcfSamples, radius, depthTextureSize, depthTextureFormat, autoRender, useRenderBundle, camera = { left: -10, right: 10, bottom: -10, top: 10, near: .1, far: 150 } } = {}) { super(renderer, { light, intensity, bias, normalBias, pcfSamples, radius, depthTextureSize, depthTextureFormat, autoRender, useRenderBundle }); this.options = { ...this.options, camera }; this.camera = new OrthographicCamera({ left: camera.left, right: camera.right, top: camera.top, bottom: camera.bottom, near: camera.near, far: camera.far, onMatricesChanged: () => { this.onPropertyChanged("projectionMatrix", this.camera.projectionMatrix); this.onPropertyChanged("viewMatrix", this.camera.viewMatrix); } }); this.camera.position.set(0); this.camera.parent = this.light; this.#direction = new Vec3(); } /** * Set or reset this {@link DirectionalShadow} {@link CameraRenderer} corresponding {@link core/bindings/BufferBinding.BufferBinding | BufferBinding}. */ setRendererBinding() { this.rendererBinding = this.renderer.bindings.directionalShadows; } /** * Set the parameters and start casting shadows by setting the {@link isActive} setter to `true`.<br> * Called internally by the associated {@link DirectionalLight} if any shadow parameters are specified when creating it. Can also be called directly. * @param parameters - parameters to use for this {@link DirectionalShadow}. */ cast({ intensity, bias, normalBias, pcfSamples, radius, depthTextureSize, depthTextureFormat, autoRender, useRenderBundle, camera } = {}) { if (camera) { this.camera.left = camera.left ?? -10; this.camera.right = camera.right ?? 10; this.camera.top = camera.top ?? 10; this.camera.bottom = camera.bottom ?? -10; this.camera.near = camera.near ?? .1; this.camera.far = camera.far ?? 150; } super.cast({ intensity, bias, normalBias, pcfSamples, radius, depthTextureSize, depthTextureFormat, autoRender, useRenderBundle }); } /** * Resend all properties to the {@link CameraRenderer} corresponding {@link core/bindings/BufferBinding.BufferBinding | BufferBinding}. Called when the maximum number of corresponding {@link DirectionalLight} has been overflowed or when the {@link renderer} has changed. */ reset() { this.setRendererBinding(); super.reset(); this.onPropertyChanged("projectionMatrix", this.camera.projectionMatrix); this.onPropertyChanged("viewMatrix", this.camera.viewMatrix); this.onPropertyChanged("direction", this.#direction); } /** * Copy the {@link DirectionalLight} direction and update binding. * @param direction - {@link DirectionalLight} direction to copy. */ setDirection(direction = new Vec3()) { this.#direction.copy(direction); this.onPropertyChanged("direction", this.#direction); } /** * Create the {@link depthTexture}. */ createDepthTexture() { this.depthTexture = new Texture(this.renderer, { label: `${this.light.options.label} (index: ${this.index}) shadow depth texture`, name: "directionalShadowDepthTexture" + this.index, type: "depth", format: this.depthTextureFormat, sampleCount: this.sampleCount, fixedSize: { width: this.depthTextureSize.x, height: this.depthTextureSize.y }, autoDestroy: false }); } /** * Get the default depth pass vertex shader for this {@link Shadow}. * parameters - {@link VertexShaderInputBaseParams} used to compute the output `worldPosition` and `normal` vectors. * @returns - Depth pass vertex shader. */ getDefaultShadowDepthVs({ bindings = [], geometry }) { return { code: getDefaultDirectionalShadowDepthVs(this.index, { bindings, geometry }) }; } }; //#endregion export { DirectionalShadow, directionalShadowStruct };