@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
97 lines (94 loc) • 3.08 kB
JavaScript
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 };