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.

135 lines (132 loc) 4.31 kB
import { shadowStruct, Shadow } from './Shadow.mjs'; import { PerspectiveCamera } from '../cameras/PerspectiveCamera.mjs'; import { Texture } from '../textures/Texture.mjs'; import { getDefaultSpotShadowDepthVs } from '../shaders/full/vertex/get-default-spot-shadow-depth-vertex-shader-code.mjs'; import { Vec3 } from '../../math/Vec3.mjs'; const spotShadowStruct = { ...shadowStruct, position: { type: "vec3f", value: new Vec3() }, viewMatrix: { type: "mat4x4f", value: new Float32Array(16) }, projectionMatrix: { type: "mat4x4f", value: new Float32Array(16) } }; class SpotShadow extends Shadow { /** * SpotShadow constructor * @param renderer - {@link CameraRenderer} or {@link GPUCurtains} used to create this {@link SpotShadow}. * @param parameters - {@link SpotShadowParams} used to create this {@link SpotShadow}. */ constructor(renderer, { light, intensity, bias, normalBias, pcfSamples, depthTextureSize, depthTextureFormat, autoRender, useRenderBundle } = {}) { super(renderer, { light, intensity, bias, normalBias, pcfSamples, depthTextureSize, depthTextureFormat, autoRender, useRenderBundle }); this.focus = 1; this.camera = new PerspectiveCamera({ near: 0.1, far: this.light.range !== 0 ? this.light.range : 150, fov: 180 / Math.PI * 2 * this.light.angle * this.focus, width: this.options.depthTextureSize.x, height: this.options.depthTextureSize.y, onMatricesChanged: () => { this.onPropertyChanged("projectionMatrix", this.camera.projectionMatrix); this.onPropertyChanged("viewMatrix", this.camera.viewMatrix); } }); this.camera.position.set(0); this.camera.parent = this.light; } /** * Set or reset this {@link SpotShadow} {@link CameraRenderer} corresponding {@link core/bindings/BufferBinding.BufferBinding | BufferBinding}. */ setRendererBinding() { this.rendererBinding = this.renderer.bindings.spotShadows; } /** * Resend all properties to the {@link CameraRenderer} corresponding {@link core/bindings/BufferBinding.BufferBinding | BufferBinding}. Called when the maximum number of corresponding {@link SpotLight} 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.setPosition(); } /** * Copy the {@link SpotLight} actual position and update binding. */ setPosition() { this.onPropertyChanged("position", this.light.actualPosition); } /** * Set the {@link PerspectiveCamera#fov | camera fov} based on the {@link SpotLight#angle | SpotLight angle}. */ setCameraFov() { this.camera.fov = 180 / Math.PI * 2 * this.light.angle * this.focus; } /** * Reset the {@link depthTexture} when the {@link depthTextureSize} changes and update camera ratio. */ onDepthTextureSizeChanged() { super.setDepthTexture(); this.camera.setSize({ width: this.depthTextureSize.x, height: this.depthTextureSize.y }); } /** * Create the {@link depthTexture}. */ createDepthTexture() { this.depthTexture = new Texture(this.renderer, { label: `${this.light.options.label} (index: ${this.light.index}) shadow depth texture`, name: "spotShadowDepthTexture" + this.index, type: "depth", format: this.depthTextureFormat, sampleCount: this.sampleCount, fixedSize: { width: this.depthTextureSize.x, height: this.depthTextureSize.y }, autoDestroy: false // do not destroy when removing a mesh }); } /** * Get the default depth pass vertex shader for this {@link SpotShadow}. * parameters - {@link VertexShaderInputBaseParams} used to compute the output `worldPosition` and `normal` vectors. * @returns - Depth pass vertex shader. */ getDefaultShadowDepthVs({ bindings = [], geometry }) { return { /** Returned code. */ code: getDefaultSpotShadowDepthVs(this.index, { bindings, geometry }) }; } } export { SpotShadow, spotShadowStruct };