UNPKG

@animech-public/playcanvas

Version:
97 lines (94 loc) 3.08 kB
import { Color } from '../../core/math/color.js'; import { PIXELFORMAT_RGBA8, FILTER_NEAREST, ADDRESS_CLAMP_TO_EDGE } from '../../platform/graphics/constants.js'; import { Texture } from '../../platform/graphics/texture.js'; import { RenderPass } from '../../platform/graphics/render-pass.js'; import { BlendState } from '../../platform/graphics/blend-state.js'; import { RenderTarget } from '../../platform/graphics/render-target.js'; import { LAYERID_DEPTH, SHADER_DEPTH } from '../constants.js'; const webgl1DepthClearColor = new Color(254.0 / 255, 254.0 / 255, 254.0 / 255, 254.0 / 255); const tempMeshInstances = []; const lights = [[], [], []]; const _depthUniformNames = ['uSceneDepthMap', 'uDepthMap']; class RenderPassDepth extends RenderPass { constructor(device, renderer, camera) { super(device); this.renderer = renderer; this.camera = camera; this.setupRenderTarget(); } destroy() { super.destroy(); if (this.renderTarget) { this.renderTarget.destroyTextureBuffers(); this.renderTarget.destroy(); this.renderTarget = null; } } update(scene) { this.scene = scene; } setupRenderTarget() { const texture = new Texture(this.device, { name: _depthUniformNames[0], format: PIXELFORMAT_RGBA8, width: 4, height: 4, mipmaps: false, minFilter: FILTER_NEAREST, magFilter: FILTER_NEAREST, addressU: ADDRESS_CLAMP_TO_EDGE, addressV: ADDRESS_CLAMP_TO_EDGE }); const renderTarget = new RenderTarget({ name: `${_depthUniformNames[0]}RT}`, colorBuffer: texture, depth: true, stencil: false }); this.init(renderTarget, {}); this.setClearColor(webgl1DepthClearColor); this.setClearDepth(1.0); } before() { const device = this.device; const colorBuffer = this.renderTarget.colorBuffer; _depthUniformNames.forEach(name => device.scope.resolve(name).setValue(colorBuffer)); } execute() { const { device, renderer, camera, scene, renderTarget } = this; const layers = scene.layers.layerList; const subLayerEnabled = scene.layers.subLayerEnabled; const isTransparent = scene.layers.subLayerList; for (let i = 0; i < layers.length; i++) { const layer = layers[i]; if (layer.enabled && subLayerEnabled[i]) { if (layer.camerasSet.has(camera)) { if (layer.id === LAYERID_DEPTH) { break; } const culledInstances = layer.getCulledInstances(camera); const meshInstances = isTransparent[i] ? culledInstances.transparent : culledInstances.opaque; for (let j = 0; j < meshInstances.length; j++) { var _meshInstance$materia; const meshInstance = meshInstances[j]; if ((_meshInstance$materia = meshInstance.material) != null && _meshInstance$materia.depthWrite) { tempMeshInstances.push(meshInstance); } } renderer.setCameraUniforms(camera, renderTarget); renderer.renderForward(camera, tempMeshInstances, lights, SHADER_DEPTH, meshInstance => { device.setBlendState(BlendState.NOBLEND); }, layer); tempMeshInstances.length = 0; } } } } } export { RenderPassDepth };