I met a very strange problem.
What I want to achieve is to render the depth of scene 1 to depth texture 1, then write depth texture 1 to depth texture 2 of scene 2, and then sample and render depth texture 2 using scene 3’s shader. The problem I encountered is that the depth sampled by scene 2 is correct for rendering, and the model is located in the center. The position of the model sampled and rendered by scene 3 runs to the upper right corner. What is the reason for this? Is there a problem with the code?
this is right rendering result of scene2
this is scene3 rendering result
here is my code
<script id="fragmentShader1" type="x-shader/x-fragment">
uniform vec2 resolution;
uniform sampler2D depthTexture;
void main() {
vec2 screenUv =gl_FragCoord.xy/resolution;
float depth = texture2D(depthTexture, screenUv).r;
gl_FragDepth=depth;
gl_FragColor =vec4(depth,depth,depth,1.0);
#include <encodings_fragment>
}
</script>
<script id="vertexShader2" type="x-shader/x-vertex">
void main() {
gl_Position = vec4( position, 1.0 );
}
</script>
<script id="fragmentShader2" type="x-shader/x-fragment">
uniform vec2 resolution;
uniform sampler2D depthTexture;
void main() {
vec2 screenUv =gl_FragCoord.xy/resolution.xy;
float depth =texture2D(depthTexture, screenUv).r;
gl_FragColor =vec4(depth,depth,depth,1.0);
// gl_FragColor =vec4(screenUv,0.0,1.0);
#include <encodings_fragment>
}
</script>
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "D:/webgl/three/three.module.js",
"three/addons/": "D:/webgl/three/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
import Stats from 'three/addons/libs/stats.module.js';
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
let camera, scene3, scene1, scene2, renderer, stats, BufferTexture1, BufferTexture2;
const pixelRatio = window.devicePixelRatio || 1;
init();
animate();
function init() {
scene3 = new THREE.Scene();
scene1 = new THREE.Scene();
scene2 = new THREE.Scene();
camera = new THREE.PerspectiveCamera(36, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(2, 2, 4);
BufferTexture1 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
BufferTexture1.depthTexture = new THREE.DepthTexture();
BufferTexture2 = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
BufferTexture2.depthTexture = new THREE.DepthTexture();
const cubegeometry = new THREE.BoxGeometry(2, 2, 2);
const cubematerial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(cubegeometry, cubematerial);
scene1.add(cube);
const geometry1 = new THREE.BufferGeometry();
const vertices1 = new Float32Array([
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0
]);
const Mat1 =
new THREE.ShaderMaterial({
side: THREE.DoubleSide,
uniforms: { resolution: { value: new THREE.Vector2(window.innerWidth * pixelRatio, window.innerHeight * pixelRatio) }, depthTexture: { value: BufferTexture1.depthTexture } },
vertexShader: document.getElementById('vertexShader1').textContent,
fragmentShader: document.getElementById('fragmentShader1').textContent
});
geometry1.setAttribute('position', new THREE.BufferAttribute(vertices1, 3));
const mesh1 = new THREE.Mesh(geometry1, Mat1);
scene2.add(mesh1);
const geometry2 = new THREE.BufferGeometry();
const vertices2 = new Float32Array([
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0
]);
const Mat2 =
new THREE.ShaderMaterial({
side: THREE.DoubleSide,
uniforms: { resolution: { value: new THREE.Vector2(window.innerWidth * pixelRatio, window.innerHeight * pixelRatio) }, depthTexture: { value: BufferTexture2.depthTexture }, color: { value: null } },
vertexShader: document.getElementById('vertexShader2').textContent,
fragmentShader: document.getElementById('fragmentShader2').textContent
});
geometry2.setAttribute('position', new THREE.BufferAttribute(vertices2, 3));
const mesh2 = new THREE.Mesh(geometry2, Mat2);
scene3.add(mesh2);
// Stats
stats = new Stats();
document.body.appendChild(stats.dom);
// Renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.shadowMap.enabled = true;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x263238);
window.addEventListener('resize', onWindowResize);
document.body.appendChild(renderer.domElement);
// Controls
const controls = new OrbitControls(camera, renderer.domElement);
controls.minDistance = 0;
controls.maxDistance = 30;
controls.update();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
stats.begin();
renderer.setRenderTarget(BufferTexture1);
renderer.clear();
renderer.render(scene1, camera);
renderer.setRenderTarget(BufferTexture2);
renderer.clear();
renderer.render(scene2, camera);
renderer.setRenderTarget(null);
renderer.render(scene3, camera);
stats.end();
}
</script>