Layering Two Scenes together render

I display the plane with an orthographicCamera in one renderer,
Project a line using a perspective camera
I would like to implement a line being drawn on that plane.
ow can we implement it?

The current state of the code is this:
Adding a camera does not work.

const container = document.getElementById('webgl-container');

let renderer;
const scene = new THREE.Scene();
const gui = new GUI();
const orthographicCamera = setupOrthographicCamera();
scene.add(orthographicCamera);
const perspectiveCamera = setupPerspectiveCamera();
scene.add(perspectiveCamera);

function init() {
  renderer = new THREE.WebGL1Renderer({ antialias: true, logarithmicDepthBuffer:  true });
  renderer.shadowMap.enabled = true;
  renderer.setPixelRatio(window.devicePixelRatio);

  container.appendChild(renderer.domElement);

  const controller = setupControls(orthographicCamera, container);


  const cube = setupModel();
  scene.add(cube);
  setupLine();
  render();
}

function setupLine() {
    const PATH_SEGMENTS = 32;
    const THICKNESS = 0.5;
    const SHADER_THICKNESS = 0.4;
    const Roundness = 12;
    const IS_Closed = false;

    const linePoints = [new THREE.Vector3(0, 0, 0).multiplyScalar(2.5)];
    const lineMaterial = new THREE.ShaderMaterial({
        uniforms: {
          color: { value: new THREE.Color("red") },
          maxZ: { value: 0.0 },  // 초기값으로 0.0 설정
          minZ: { value: 0.0 }   // 초기값으로 0.0 설정
        },
        vertexShader: `
        uniform float maxZ;
        uniform float minZ;
          varying float alpha;
          void main() {
            float range = maxZ - minZ;
            alpha = smoothstep(0.7, 1.0, (abs(position.z - minZ) / range));
            alpha = min(alpha, 0.7);  // 최대 0.7까지 제한
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
          }
        `,
        fragmentShader: `
          uniform vec3 color;
          varying float alpha;
          void main() {
            gl_FragColor = vec4(color, 1.0 - alpha);  // 처음이 밝고 뒷부분이 어둡게
          }
        `,
        transparent: true,
        depthTest: false  // 선이 다른 객체를 가리지 않도록 depthTest를 비활성화
    });

    for (let i = 0; i < trajectory.length; i++) {
        linePoints.push( new THREE.Vector3(trajectory[i].x, trajectory[i].z, -trajectory[i].y).multiplyScalar(1));
    }

    let maxZ = Math.max(...linePoints.map(point => point.z));
    let minZ = Math.min(...linePoints.map(point => point.z));
    lineMaterial.uniforms.maxZ = { value: maxZ };
    lineMaterial.uniforms.minZ = { value: minZ };

    const tubeGeometry = new THREE.TubeGeometry(
        new THREE.CatmullRomCurve3(linePoints),
        PATH_SEGMENTS,
        THICKNESS,
        Roundness,
        IS_Closed //closed
    );

    const line = new THREE.Mesh(tubeGeometry, lineMaterial);
    line.layers.set(2);
    scene.add(line)
}

function setupOrthographicCamera() {
    const camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
    
    camera.layers.enable(1);
    camera.layers.set(1);

    const f2 = gui.addFolder('OrthographicCamera Controls');
    f2.add(camera, 'left', 1, 1000);
    f2.add(camera, 'right', 1, 1000);
    f2.add(camera, 'top', 1, 1000);
    f2.add(camera, 'bottom', 1, 1000);
    f2.add(camera, 'near', 1, 1000);
    f2.add(camera, 'far', 1, 1000);
    f2.add(camera.position, 'z', -1000, 1000);

    const cameraHelper = new THREE.CameraHelper(camera);
    scene.add(cameraHelper);
    return camera
}

function setupPerspectiveCamera() {
    const width = window.innerWidth;
    const height = window.innerHeight;
    const fov = 75;
    const near = 0.1;
    const far = 1000;
  
    const camera = new THREE.PerspectiveCamera(
      fov,
      width / height,
      near,
      far,
    );

    camera.layers.enable(2);
    camera.layers.set(2);
  
    camera.position.z = 10;

    const f1 = gui.addFolder('PerspectiveCamera Controls');
    f1.add(camera, 'fov', 1, 1000);
    f1.add(camera, 'aspect', 1, 1000);
    f1.add(camera, 'near', 1, 1000);
    f1.add(camera, 'far', 1, 1000);
    f1.add(camera.position, 'z', 1, 1000)

    const cameraHelper = new THREE.CameraHelper(camera);
    scene.add(cameraHelper);

    return camera;
}

function setupModel() {
    const textureLoader = new THREE.TextureLoader();
    const imageTexture = textureLoader.load('./assets/textures/FrontViewTexture/BG8.jpg');
    imageTexture.encoding = THREE.sRGBEncoding;
  
    const geometry = new THREE.PlaneGeometry(2, 2);
    const planeMaterial = new THREE.MeshBasicMaterial({ map: imageTexture });
  
    const cube = new THREE.Mesh(geometry, planeMaterial);
    cube.layers.set(1);

    return cube;
}

function setupControls(camera, container) {
  const controller = new OrbitControls(camera, container);
  return controller;
}

function render() {
  const width = container.clientWidth;
  const height = container.clientHeight;
  
  renderer.setSize(width, height);
  renderer.render(scene, perspectiveCamera);
  renderer.render(scene, orthographicCamera);

  requestAnimationFrame(render);
}

function resize() {
  const width = container.clientWidth;
  const height = container.clientHeight;
  orthographicCamera.updateProjectionMatrix();
  perspectiveCamera.updateProjectionMatrix();
  renderer.setSize(width, height);
}


window.addEventListener('resize', resize);
init();
const onAnimationFrame = () => {
  renderer.autoClear = false;
  renderer.clear();

  renderer.render(scene1, camera1);

  renderer.clearDepth();

  renderer.render(scene2, camera2);
};

This will render one scene above another, ignoring depth testing between scenes (make sure second scene does not have background, otherwise it’ll just overlay the first scene entirely.)

3 Likes

thank you.
Thanks to you, I solved the problem well!!