I succeeded! But now I lose the depth information… So my effects pass has no depth information and certain effects like SSAO no longer work…
I would like to retrieve the depth information either from my renderTargetFull, or use that of my personalized depth pass (which allows for better results with materials with alphaTest).
Do you have any idea how to do it?
const renderPass = new HalfResolutionPass(this.scene, this.cameraMesh, {
resolutionScale: 0.5
})
this.postprocessing.renderPass = renderPass;
this.cameraMesh.composer.addPass(renderPass);
const depthPass = new DepthPass(this.scene, this.cameraMesh, {
resolutionScale: 1,
});
depthPass.renderToScreen = false;
const depthTexture = depthPass.texture;
depthTexture.generateMipmaps = false;
depthTexture.magFilter = NearestFilter;
depthTexture.minFilter = NearestFilter;
this.postprocessing.depthPass = depthPass;
this.cameraMesh.composer.addPass(depthPass);
this.cameraMesh.depthPass = depthPass;
this.cameraMesh.depthTexture = depthTexture;
const effects = [];
export class HalfResolutionPass extends POSTPROCESSING.Pass {
constructor(scene, camera, {
resolutionScale = 0.5,
} = {}) {
super("RenderPass", scene, camera);
this.needsSwap = false;
this.clearPass = new POSTPROCESSING.ClearPass();
this.ignoreBackground = false;
this.skipShadowMapUpdate = false;
this.clearPass.overrideClearAlpha = 0;
this.renderTargetHalf = new WebGLRenderTarget(1, 1, {
depthBuffer: true
// alpha: true,
});
this.renderTargetFull = new WebGLRenderTarget(1, 1, {
depthBuffer: true
});
this.renderTargetHalf.texture.name = "HalfResolutionPass.Half";
this.renderTargetFull.texture.name = "HalfResolutionPass.Full";
this.upsamplingMaterial = new POSTPROCESSING.UpsamplingMaterial();
this.upsamplingMaterial.vertexShader = `
varying vec2 vUv;
void main() {
vUv = position.xy * 0.5 + 0.5;
gl_Position = vec4(position.xy, 1.0, 1.0);
}
`
this.upsamplingMaterial.fragmentShader =`
uniform highp sampler2D inputBuffer;
uniform highp sampler2D supportBuffer;
varying vec2 vUv;
void main() {
vec4 lowColor = texture2D(inputBuffer, vUv);
vec4 highColor = texture2D(supportBuffer, vUv);
float lowAlpha = lowColor.a;
float highAlpha = highColor.a;
// LowColor doit être au premier plan
if (lowAlpha > 0.0) {
gl_FragColor = mix(lowColor, highColor, 1.0 - lowAlpha);
} else {
gl_FragColor = highColor;
}
#include <colorspace_fragment>
}
`
this.fullscreenMaterial = this.upsamplingMaterial;
this.resolution = new Vector2();
this.resolutionScale = resolutionScale;
this.finalScene = new Scene();
}
set renderToScreen(value) {
super.renderToScreen = value;
this.clearPass.renderToScreen = value;
}
get clear() {
return this.clearPass.enabled;
}
set clear(value) {
this.clearPass.enabled = value;
}
render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest) {
// Pas rendre le fond
this.clearPass.setSize(this.resolution.x, this.resolution.y);
// this.clearPass.render(renderer, inputBuffer)
this.clearPass.render(renderer, this.renderTargetFull)
this.clearPass.setSize(this.resolution.x * this.resolutionScale, this.resolution.y * this.resolutionScale);
this.clearPass.render(renderer, this.renderTargetHalf)
const halfMeshes = [];
const fullMeshes = [];
this.fullscreenMaterial = null;
this.screen.visible = false;
this.scene.children.forEach((child) => {
if (!child.visible) {
return
}
if (child.halfResolution) {
halfMeshes.push(child);
child.visible = true;
} else {
fullMeshes.push(child);
child.visible = false;
}
});
const background = this.scene.background;
this.scene.background = null;
renderer.shadowMap.autoUpdate = false;
renderer.setRenderTarget(this.renderTargetHalf);
renderer.render(this.scene, this.camera);
for (let i = 0; i < fullMeshes.length; i++) {
const child = fullMeshes[i];
child.visible = true;
}
for (let i = 0; i < halfMeshes.length; i++) {
const child = halfMeshes[i];
child.visible = false;
}
renderer.shadowMap.autoUpdate = true;
renderer.setRenderTarget(this.renderTargetFull);
renderer.render(this.scene, this.camera);
for (let i = 0; i < fullMeshes.length; i++) {
const child = fullMeshes[i];
child.visible = false;
}
this.fullscreenMaterial = this.upsamplingMaterial;
this.screen.visible = true;
this.fullscreenMaterial.uniforms.inputBuffer.value = this.renderTargetHalf.texture;
this.fullscreenMaterial.uniforms.supportBuffer.value = this.renderTargetFull.texture;
this.scene.background = null;
renderer.shadowMap.autoUpdate = false;
renderer.setRenderTarget(inputBuffer);
renderer.render(this.scene, this.camera);
this.scene.background = background;
renderer.shadowMap.autoUpdate = true;
for (let i = 0; i < halfMeshes.length; i++) {
const child = halfMeshes[i];
child.visible = true;
}
for (let i = 0; i < fullMeshes.length; i++) {
const child = fullMeshes[i];
child.visible = true;
}
}
setSize(width, height) {
const resolution = this.resolution;
resolution.set(width, height);
this.renderTargetHalf.setSize(Math.round(resolution.x * this.resolutionScale), Math.round(resolution.y * this.resolutionScale));
this.renderTargetFull.setSize(resolution.x, resolution.y);
}
initialize(renderer, alpha, frameBufferType) {
if(frameBufferType !== undefined) {
this.renderTargetHalf.texture.type = frameBufferType;
this.renderTargetFull.texture.type = frameBufferType;
if(frameBufferType !== UnsignedByteType) {
this.downsamplingMaterial.defines.FRAMEBUFFER_PRECISION_HIGH = "1";
this.upsamplingMaterial.defines.FRAMEBUFFER_PRECISION_HIGH = "1";
} else if(renderer !== null && renderer.outputColorSpace === SRGBColorSpace) {
this.renderTargetHalf.texture.colorSpace = SRGBColorSpace;
this.renderTargetFull.texture.colorSpace = SRGBColorSpace;
}
}
}
}