UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

696 lines (695 loc) 26.3 kB
import Base from "../core/Base.mjs"; import glenum from "../core/glenum.mjs"; import Vector3 from "../math/Vector3.mjs"; import BoundingBox from "../math/BoundingBox.mjs"; import Frustum from "../math/Frustum.mjs"; import Matrix4 from "../math/Matrix4.mjs"; import Renderer from "../Renderer.mjs"; import Shader from "../Shader.mjs"; import Material from "../Material.mjs"; import FrameBuffer from "../FrameBuffer.mjs"; import Texture from "../Texture.mjs"; import Texture2D from "../Texture2D.mjs"; import TextureCube from "../TextureCube.mjs"; import PerspectiveCamera from "../camera/Perspective.mjs"; import OrthoCamera from "../camera/Orthographic.mjs"; import Pass from "../compositor/Pass.mjs"; import TexturePool from "../compositor/TexturePool.mjs"; import mat4 from "../glmatrix/mat4.mjs"; import shadowmapEssl from "../shader/source/shadowmap.glsl.mjs"; var targets = ["px", "nx", "py", "ny", "pz", "nz"]; Shader["import"](shadowmapEssl); function getDepthMaterialUniform(renderable, depthMaterial, symbol) { if (symbol === "alphaMap") { return renderable.material.get("diffuseMap"); } else if (symbol === "alphaCutoff") { if (renderable.material.isDefined("fragment", "ALPHA_TEST") && renderable.material.get("diffuseMap")) { var alphaCutoff = renderable.material.get("alphaCutoff"); return alphaCutoff || 0; } return 0; } else if (symbol === "uvRepeat") { return renderable.material.get("uvRepeat"); } else if (symbol === "uvOffset") { return renderable.material.get("uvOffset"); } else { return depthMaterial.get(symbol); } } function isDepthMaterialChanged(renderable, prevRenderable) { var matA = renderable.material; var matB = prevRenderable.material; return matA.get("diffuseMap") !== matB.get("diffuseMap") || (matA.get("alphaCutoff") || 0) !== (matB.get("alphaCutoff") || 0); } var ShadowMapPass = Base.extend(function() { return { softShadow: ShadowMapPass.PCF, shadowBlur: 1, lightFrustumBias: "auto", kernelPCF: new Float32Array([ 1, 0, 1, 1, -1, 1, 0, 1, -1, 0, -1, -1, 1, -1, 0, -1 ]), precision: "highp", _lastRenderNotCastShadow: false, _frameBuffer: new FrameBuffer(), _textures: {}, _shadowMapNumber: { "POINT_LIGHT": 0, "DIRECTIONAL_LIGHT": 0, "SPOT_LIGHT": 0 }, _depthMaterials: {}, _distanceMaterials: {}, _receivers: [], _lightsCastShadow: [], _lightCameras: {}, _lightMaterials: {}, _texturePool: new TexturePool() }; }, function() { this._gaussianPassH = new Pass({ fragment: Shader.source("clay.compositor.gaussian_blur") }); this._gaussianPassV = new Pass({ fragment: Shader.source("clay.compositor.gaussian_blur") }); this._gaussianPassH.setUniform("blurSize", this.shadowBlur); this._gaussianPassH.setUniform("blurDir", 0); this._gaussianPassV.setUniform("blurSize", this.shadowBlur); this._gaussianPassV.setUniform("blurDir", 1); this._outputDepthPass = new Pass({ fragment: Shader.source("clay.sm.debug_depth") }); }, { render: function(renderer, scene, sceneCamera, notUpdateScene) { if (!sceneCamera) { sceneCamera = scene.getMainCamera(); } this.trigger("beforerender", this, renderer, scene, sceneCamera); this._renderShadowPass(renderer, scene, sceneCamera, notUpdateScene); this.trigger("afterrender", this, renderer, scene, sceneCamera); }, renderDebug: function(renderer, size) { renderer.saveClear(); var viewport = renderer.viewport; var x = 0, y = 0; var width = size || viewport.width / 4; var height = width; if (this.softShadow === ShadowMapPass.VSM) { this._outputDepthPass.material.define("fragment", "USE_VSM"); } else { this._outputDepthPass.material.undefine("fragment", "USE_VSM"); } for (var name in this._textures) { var texture = this._textures[name]; renderer.setViewport(x, y, width * texture.width / texture.height, height); this._outputDepthPass.setUniform("depthMap", texture); this._outputDepthPass.render(renderer); x += width * texture.width / texture.height; } renderer.setViewport(viewport); renderer.restoreClear(); }, _updateReceivers: function(renderer, mesh) { if (mesh.receiveShadow) { this._receivers.push(mesh); mesh.material.set("shadowEnabled", 1); mesh.material.set("pcfKernel", this.kernelPCF); } else { mesh.material.set("shadowEnabled", 0); } if (this.softShadow === ShadowMapPass.VSM) { mesh.material.define("fragment", "USE_VSM"); mesh.material.undefine("fragment", "PCF_KERNEL_SIZE"); } else { mesh.material.undefine("fragment", "USE_VSM"); var kernelPCF = this.kernelPCF; if (kernelPCF && kernelPCF.length) { mesh.material.define("fragment", "PCF_KERNEL_SIZE", kernelPCF.length / 2); } else { mesh.material.undefine("fragment", "PCF_KERNEL_SIZE"); } } }, _update: function(renderer, scene) { var self = this; scene.traverse(function(renderable) { if (renderable.isRenderable()) { self._updateReceivers(renderer, renderable); } }); for (var i = 0; i < scene.lights.length; i++) { var light = scene.lights[i]; if (light.castShadow && !light.invisible) { this._lightsCastShadow.push(light); } } }, _renderShadowPass: function(renderer, scene, sceneCamera, notUpdateScene) { for (var name in this._shadowMapNumber) { this._shadowMapNumber[name] = 0; } this._lightsCastShadow.length = 0; this._receivers.length = 0; var _gl = renderer.gl; if (!notUpdateScene) { scene.update(); } if (sceneCamera) { sceneCamera.update(); } scene.updateLights(); this._update(renderer, scene); if (!this._lightsCastShadow.length && this._lastRenderNotCastShadow) { return; } this._lastRenderNotCastShadow = this._lightsCastShadow === 0; _gl.enable(_gl.DEPTH_TEST); _gl.depthMask(true); _gl.disable(_gl.BLEND); _gl.clearColor(1, 1, 1, 1); var spotLightShadowMaps = []; var spotLightMatrices = []; var directionalLightShadowMaps = []; var directionalLightMatrices = []; var shadowCascadeClips = []; var pointLightShadowMaps = []; var dirLightHasCascade; for (var i = 0; i < this._lightsCastShadow.length; i++) { var light = this._lightsCastShadow[i]; if (light.type === "DIRECTIONAL_LIGHT") { if (dirLightHasCascade) { console.warn("Only one direectional light supported with shadow cascade"); continue; } if (light.shadowCascade > 4) { console.warn("Support at most 4 cascade"); continue; } if (light.shadowCascade > 1) { dirLightHasCascade = light; } this.renderDirectionalLightShadow( renderer, scene, sceneCamera, light, shadowCascadeClips, directionalLightMatrices, directionalLightShadowMaps ); } else if (light.type === "SPOT_LIGHT") { this.renderSpotLightShadow( renderer, scene, light, spotLightMatrices, spotLightShadowMaps ); } else if (light.type === "POINT_LIGHT") { this.renderPointLightShadow( renderer, scene, light, pointLightShadowMaps ); } this._shadowMapNumber[light.type]++; } for (var lightType in this._shadowMapNumber) { var number = this._shadowMapNumber[lightType]; var key = lightType + "_SHADOWMAP_COUNT"; for (var i = 0; i < this._receivers.length; i++) { var mesh = this._receivers[i]; var material = mesh.material; if (material.fragmentDefines[key] !== number) { if (number > 0) { material.define("fragment", key, number); } else if (material.isDefined("fragment", key)) { material.undefine("fragment", key); } } } } for (var i = 0; i < this._receivers.length; i++) { var mesh = this._receivers[i]; var material = mesh.material; if (dirLightHasCascade) { material.define("fragment", "SHADOW_CASCADE", dirLightHasCascade.shadowCascade); } else { material.undefine("fragment", "SHADOW_CASCADE"); } } var shadowUniforms = scene.shadowUniforms; function getSize(texture) { return texture.height; } if (directionalLightShadowMaps.length > 0) { var directionalLightShadowMapSizes = directionalLightShadowMaps.map(getSize); shadowUniforms.directionalLightShadowMaps = { value: directionalLightShadowMaps, type: "tv" }; shadowUniforms.directionalLightMatrices = { value: directionalLightMatrices, type: "m4v" }; shadowUniforms.directionalLightShadowMapSizes = { value: directionalLightShadowMapSizes, type: "1fv" }; if (dirLightHasCascade) { var shadowCascadeClipsNear = shadowCascadeClips.slice(); var shadowCascadeClipsFar = shadowCascadeClips.slice(); shadowCascadeClipsNear.pop(); shadowCascadeClipsFar.shift(); shadowCascadeClipsNear.reverse(); shadowCascadeClipsFar.reverse(); directionalLightMatrices.reverse(); shadowUniforms.shadowCascadeClipsNear = { value: shadowCascadeClipsNear, type: "1fv" }; shadowUniforms.shadowCascadeClipsFar = { value: shadowCascadeClipsFar, type: "1fv" }; } } if (spotLightShadowMaps.length > 0) { var spotLightShadowMapSizes = spotLightShadowMaps.map(getSize); var shadowUniforms = scene.shadowUniforms; shadowUniforms.spotLightShadowMaps = { value: spotLightShadowMaps, type: "tv" }; shadowUniforms.spotLightMatrices = { value: spotLightMatrices, type: "m4v" }; shadowUniforms.spotLightShadowMapSizes = { value: spotLightShadowMapSizes, type: "1fv" }; } if (pointLightShadowMaps.length > 0) { shadowUniforms.pointLightShadowMaps = { value: pointLightShadowMaps, type: "tv" }; } }, renderDirectionalLightShadow: function() { var splitFrustum = new Frustum(); var splitProjMatrix = new Matrix4(); var cropBBox = new BoundingBox(); var cropMatrix = new Matrix4(); var lightViewMatrix = new Matrix4(); var lightViewProjMatrix = new Matrix4(); var lightProjMatrix = new Matrix4(); return function(renderer, scene, sceneCamera, light, shadowCascadeClips, directionalLightMatrices, directionalLightShadowMaps) { var defaultShadowMaterial = this._getDepthMaterial(light); var passConfig = { getMaterial: function(renderable) { return renderable.shadowDepthMaterial || defaultShadowMaterial; }, isMaterialChanged: isDepthMaterialChanged, getUniform: getDepthMaterialUniform, ifRender: function(renderable) { return renderable.castShadow; }, sortCompare: Renderer.opaqueSortCompare }; if (!scene.viewBoundingBoxLastFrame.isFinite()) { var boundingBox = scene.getBoundingBox(); scene.viewBoundingBoxLastFrame.copy(boundingBox).applyTransform(sceneCamera.viewMatrix); } var clippedFar = Math.min(-scene.viewBoundingBoxLastFrame.min.z, sceneCamera.far); var clippedNear = Math.max(-scene.viewBoundingBoxLastFrame.max.z, sceneCamera.near); var lightCamera = this._getDirectionalLightCamera(light, scene, sceneCamera); var lvpMat4Arr = lightViewProjMatrix.array; lightProjMatrix.copy(lightCamera.projectionMatrix); mat4.invert(lightViewMatrix.array, lightCamera.worldTransform.array); mat4.multiply(lightViewMatrix.array, lightViewMatrix.array, sceneCamera.worldTransform.array); mat4.multiply(lvpMat4Arr, lightProjMatrix.array, lightViewMatrix.array); var clipPlanes = []; var isPerspective = sceneCamera instanceof PerspectiveCamera; var scaleZ = (sceneCamera.near + sceneCamera.far) / (sceneCamera.near - sceneCamera.far); var offsetZ = 2 * sceneCamera.near * sceneCamera.far / (sceneCamera.near - sceneCamera.far); for (var i = 0; i <= light.shadowCascade; i++) { var clog = clippedNear * Math.pow(clippedFar / clippedNear, i / light.shadowCascade); var cuni = clippedNear + (clippedFar - clippedNear) * i / light.shadowCascade; var c = clog * light.cascadeSplitLogFactor + cuni * (1 - light.cascadeSplitLogFactor); clipPlanes.push(c); shadowCascadeClips.push(-(-c * scaleZ + offsetZ) / -c); } var texture = this._getTexture(light, light.shadowCascade); directionalLightShadowMaps.push(texture); var viewport = renderer.viewport; var _gl = renderer.gl; this._frameBuffer.attach(texture); this._frameBuffer.bind(renderer); _gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT); for (var i = 0; i < light.shadowCascade; i++) { var nearPlane = clipPlanes[i]; var farPlane = clipPlanes[i + 1]; if (isPerspective) { mat4.perspective(splitProjMatrix.array, sceneCamera.fov / 180 * Math.PI, sceneCamera.aspect, nearPlane, farPlane); } else { mat4.ortho( splitProjMatrix.array, sceneCamera.left, sceneCamera.right, sceneCamera.bottom, sceneCamera.top, nearPlane, farPlane ); } splitFrustum.setFromProjection(splitProjMatrix); splitFrustum.getTransformedBoundingBox(cropBBox, lightViewMatrix); cropBBox.applyProjection(lightProjMatrix); var _min = cropBBox.min.array; var _max = cropBBox.max.array; _min[0] = Math.max(_min[0], -1); _min[1] = Math.max(_min[1], -1); _max[0] = Math.min(_max[0], 1); _max[1] = Math.min(_max[1], 1); cropMatrix.ortho(_min[0], _max[0], _min[1], _max[1], 1, -1); lightCamera.projectionMatrix.multiplyLeft(cropMatrix); var shadowSize = light.shadowResolution || 512; renderer.setViewport((light.shadowCascade - i - 1) * shadowSize, 0, shadowSize, shadowSize, 1); var renderList = scene.updateRenderList(lightCamera); renderer.renderPass(renderList.opaque, lightCamera, passConfig); if (this.softShadow === ShadowMapPass.VSM) { this._gaussianFilter(renderer, texture, texture.width); } var matrix = new Matrix4(); matrix.copy(lightCamera.viewMatrix).multiplyLeft(lightCamera.projectionMatrix); directionalLightMatrices.push(matrix.array); lightCamera.projectionMatrix.copy(lightProjMatrix); } this._frameBuffer.unbind(renderer); renderer.setViewport(viewport); }; }(), renderSpotLightShadow: function(renderer, scene, light, spotLightMatrices, spotLightShadowMaps) { var texture = this._getTexture(light); var lightCamera = this._getSpotLightCamera(light); var _gl = renderer.gl; this._frameBuffer.attach(texture); this._frameBuffer.bind(renderer); _gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT); var defaultShadowMaterial = this._getDepthMaterial(light); var passConfig = { getMaterial: function(renderable) { return renderable.shadowDepthMaterial || defaultShadowMaterial; }, isMaterialChanged: isDepthMaterialChanged, getUniform: getDepthMaterialUniform, ifRender: function(renderable) { return renderable.castShadow; }, sortCompare: Renderer.opaqueSortCompare }; var renderList = scene.updateRenderList(lightCamera); renderer.renderPass(renderList.opaque, lightCamera, passConfig); this._frameBuffer.unbind(renderer); if (this.softShadow === ShadowMapPass.VSM) { this._gaussianFilter(renderer, texture, texture.width); } var matrix = new Matrix4(); matrix.copy(lightCamera.worldTransform).invert().multiplyLeft(lightCamera.projectionMatrix); spotLightShadowMaps.push(texture); spotLightMatrices.push(matrix.array); }, renderPointLightShadow: function(renderer, scene, light, pointLightShadowMaps) { var texture = this._getTexture(light); var _gl = renderer.gl; pointLightShadowMaps.push(texture); var defaultShadowMaterial = this._getDepthMaterial(light); var passConfig = { getMaterial: function(renderable) { return renderable.shadowDepthMaterial || defaultShadowMaterial; }, getUniform: getDepthMaterialUniform, sortCompare: Renderer.opaqueSortCompare }; var renderListEachSide = { px: [], py: [], pz: [], nx: [], ny: [], nz: [] }; var bbox = new BoundingBox(); var lightWorldPosition = light.getWorldPosition().array; var lightBBox = new BoundingBox(); var range = light.range; lightBBox.min.setArray(lightWorldPosition); lightBBox.max.setArray(lightWorldPosition); var extent = new Vector3(range, range, range); lightBBox.max.add(extent); lightBBox.min.sub(extent); var targetsNeedRender = { px: false, py: false, pz: false, nx: false, ny: false, nz: false }; scene.traverse(function(renderable) { if (renderable.isRenderable() && renderable.castShadow) { var geometry = renderable.geometry; if (!geometry.boundingBox) { for (var i2 = 0; i2 < targets.length; i2++) { renderListEachSide[targets[i2]].push(renderable); } return; } bbox.transformFrom(geometry.boundingBox, renderable.worldTransform); if (!bbox.intersectBoundingBox(lightBBox)) { return; } bbox.updateVertices(); for (var i2 = 0; i2 < targets.length; i2++) { targetsNeedRender[targets[i2]] = false; } for (var i2 = 0; i2 < 8; i2++) { var vtx = bbox.vertices[i2]; var x = vtx[0] - lightWorldPosition[0]; var y = vtx[1] - lightWorldPosition[1]; var z = vtx[2] - lightWorldPosition[2]; var absx = Math.abs(x); var absy = Math.abs(y); var absz = Math.abs(z); if (absx > absy) { if (absx > absz) { targetsNeedRender[x > 0 ? "px" : "nx"] = true; } else { targetsNeedRender[z > 0 ? "pz" : "nz"] = true; } } else { if (absy > absz) { targetsNeedRender[y > 0 ? "py" : "ny"] = true; } else { targetsNeedRender[z > 0 ? "pz" : "nz"] = true; } } } for (var i2 = 0; i2 < targets.length; i2++) { if (targetsNeedRender[targets[i2]]) { renderListEachSide[targets[i2]].push(renderable); } } } }); for (var i = 0; i < 6; i++) { var target = targets[i]; var camera = this._getPointLightCamera(light, target); this._frameBuffer.attach(texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i); this._frameBuffer.bind(renderer); _gl.clear(_gl.COLOR_BUFFER_BIT | _gl.DEPTH_BUFFER_BIT); renderer.renderPass(renderListEachSide[target], camera, passConfig); } this._frameBuffer.unbind(renderer); }, _getDepthMaterial: function(light) { var shadowMaterial = this._lightMaterials[light.__uid__]; var isPointLight = light.type === "POINT_LIGHT"; if (!shadowMaterial) { var shaderPrefix = isPointLight ? "clay.sm.distance." : "clay.sm.depth."; shadowMaterial = new Material({ precision: this.precision, shader: new Shader(Shader.source(shaderPrefix + "vertex"), Shader.source(shaderPrefix + "fragment")) }); this._lightMaterials[light.__uid__] = shadowMaterial; } if (light.shadowSlopeScale != null) { shadowMaterial.setUniform("slopeScale", light.shadowSlopeScale); } if (light.shadowBias != null) { shadowMaterial.setUniform("bias", light.shadowBias); } if (this.softShadow === ShadowMapPass.VSM) { shadowMaterial.define("fragment", "USE_VSM"); } else { shadowMaterial.undefine("fragment", "USE_VSM"); } if (isPointLight) { shadowMaterial.set("lightPosition", light.getWorldPosition().array); shadowMaterial.set("range", light.range); } return shadowMaterial; }, _gaussianFilter: function(renderer, texture, size) { var parameter = { width: size, height: size, type: Texture.FLOAT }; var tmpTexture = this._texturePool.get(parameter); this._frameBuffer.attach(tmpTexture); this._frameBuffer.bind(renderer); this._gaussianPassH.setUniform("texture", texture); this._gaussianPassH.setUniform("textureWidth", size); this._gaussianPassH.render(renderer); this._frameBuffer.attach(texture); this._gaussianPassV.setUniform("texture", tmpTexture); this._gaussianPassV.setUniform("textureHeight", size); this._gaussianPassV.render(renderer); this._frameBuffer.unbind(renderer); this._texturePool.put(tmpTexture); }, _getTexture: function(light, cascade) { var key = light.__uid__; var texture = this._textures[key]; var resolution = light.shadowResolution || 512; cascade = cascade || 1; if (!texture) { if (light.type === "POINT_LIGHT") { texture = new TextureCube(); } else { texture = new Texture2D(); } texture.width = resolution * cascade; texture.height = resolution; if (this.softShadow === ShadowMapPass.VSM) { texture.type = Texture.FLOAT; texture.anisotropic = 4; } else { texture.minFilter = glenum.NEAREST; texture.magFilter = glenum.NEAREST; texture.useMipmap = false; } this._textures[key] = texture; } return texture; }, _getPointLightCamera: function(light, target) { if (!this._lightCameras.point) { this._lightCameras.point = { px: new PerspectiveCamera(), nx: new PerspectiveCamera(), py: new PerspectiveCamera(), ny: new PerspectiveCamera(), pz: new PerspectiveCamera(), nz: new PerspectiveCamera() }; } var camera = this._lightCameras.point[target]; camera.far = light.range; camera.fov = 90; camera.position.set(0, 0, 0); switch (target) { case "px": camera.lookAt(Vector3.POSITIVE_X, Vector3.NEGATIVE_Y); break; case "nx": camera.lookAt(Vector3.NEGATIVE_X, Vector3.NEGATIVE_Y); break; case "py": camera.lookAt(Vector3.POSITIVE_Y, Vector3.POSITIVE_Z); break; case "ny": camera.lookAt(Vector3.NEGATIVE_Y, Vector3.NEGATIVE_Z); break; case "pz": camera.lookAt(Vector3.POSITIVE_Z, Vector3.NEGATIVE_Y); break; case "nz": camera.lookAt(Vector3.NEGATIVE_Z, Vector3.NEGATIVE_Y); break; } light.getWorldPosition(camera.position); camera.update(); return camera; }, _getDirectionalLightCamera: function() { var lightViewMatrix = new Matrix4(); var sceneViewBoundingBox = new BoundingBox(); var lightViewBBox = new BoundingBox(); return function(light, scene, sceneCamera) { if (!this._lightCameras.directional) { this._lightCameras.directional = new OrthoCamera(); } var camera = this._lightCameras.directional; sceneViewBoundingBox.copy(scene.viewBoundingBoxLastFrame); sceneViewBoundingBox.intersection(sceneCamera.frustum.boundingBox); camera.position.copy(sceneViewBoundingBox.min).add(sceneViewBoundingBox.max).scale(0.5).transformMat4(sceneCamera.worldTransform); camera.rotation.copy(light.rotation); camera.scale.copy(light.scale); camera.updateWorldTransform(); Matrix4.invert(lightViewMatrix, camera.worldTransform); Matrix4.multiply(lightViewMatrix, lightViewMatrix, sceneCamera.worldTransform); lightViewBBox.copy(sceneViewBoundingBox).applyTransform(lightViewMatrix); var min = lightViewBBox.min.array; var max = lightViewBBox.max.array; camera.position.set((min[0] + max[0]) / 2, (min[1] + max[1]) / 2, max[2]).transformMat4(camera.worldTransform); camera.near = 0; camera.far = -min[2] + max[2]; if (isNaN(this.lightFrustumBias)) { camera.far *= 4; } else { camera.far += this.lightFrustumBias; } camera.left = min[0]; camera.right = max[0]; camera.top = max[1]; camera.bottom = min[1]; camera.update(true); return camera; }; }(), _getSpotLightCamera: function(light) { if (!this._lightCameras.spot) { this._lightCameras.spot = new PerspectiveCamera(); } var camera = this._lightCameras.spot; camera.fov = light.penumbraAngle * 2; camera.far = light.range; camera.worldTransform.copy(light.worldTransform); camera.updateProjectionMatrix(); mat4.invert(camera.viewMatrix.array, camera.worldTransform.array); return camera; }, dispose: function(renderer) { var _gl = renderer.gl || renderer; if (this._frameBuffer) { this._frameBuffer.dispose(_gl); } for (var name in this._textures) { this._textures[name].dispose(_gl); } this._texturePool.clear(renderer.gl); this._depthMaterials = {}; this._distanceMaterials = {}; this._textures = {}; this._lightCameras = {}; this._shadowMapNumber = { "POINT_LIGHT": 0, "DIRECTIONAL_LIGHT": 0, "SPOT_LIGHT": 0 }; this._meshMaterials = {}; for (var i = 0; i < this._receivers.length; i++) { var mesh = this._receivers[i]; if (mesh.material) { var material = mesh.material; material.undefine("fragment", "POINT_LIGHT_SHADOW_COUNT"); material.undefine("fragment", "DIRECTIONAL_LIGHT_SHADOW_COUNT"); material.undefine("fragment", "AMBIENT_LIGHT_SHADOW_COUNT"); material.set("shadowEnabled", 0); } } this._receivers = []; this._lightsCastShadow = []; } }); ShadowMapPass.VSM = 1; ShadowMapPass.PCF = 2; var ShadowMapPass$1 = ShadowMapPass; export { ShadowMapPass$1 as default };