Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render order issue with scissor and texture background #30451

Closed
xintongxia opened this issue Feb 3, 2025 · 2 comments
Closed

Render order issue with scissor and texture background #30451

xintongxia opened this issue Feb 3, 2025 · 2 comments
Labels
Milestone

Comments

@xintongxia
Copy link

Description

https://jsfiddle.net/ZincCooper/f2753vg4/90/

object in main view will cover object in the scissor view, might be something wrong in my setup?

Reproduction steps

  1. open the jsfiddle https://jsfiddle.net/ZincCooper/f2753vg4/100/
  2. zoom in
  3. the red box in the main view will cover the blue box in the scissor view

Code

import * as THREE from 'three';
/* import * as THREE from 'threeGPU'; */
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';

// Create renderer
const renderer = new THREE.WebGLRenderer({  antialias: true });
/* const renderer = new THREE.WebGPURenderer({  antialias: true, forceWebGL: true, }); */
/* const renderer = new THREE.WebGPURenderer({ antialias: true, forceWebGL: false, }); */ 
/* await renderer.init(); */
renderer.setSize(window.innerWidth, window.innerHeight);

document.body.appendChild(renderer.domElement);

const backgroundImageUrl = 'https://raw.githubusercontent.com/mrdoob/three.js/refs/heads/dev/examples/textures/equirectangular/royal_esplanade_1k.hdr'

// Create two cameras
const camera1 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera1.position.z = 5;

const camera2 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera2.position.z = 5;

const controls = new OrbitControls( camera1, renderer.domElement );

// Create a shared scene
const scene1 = new THREE.Scene();
scene1.background = new THREE.Color('#232389');

const scene2 = new THREE.Scene();
const COLOR_YELLOW =  new THREE.Color('#898923');
const COLOR_GREEN =  new THREE.Color('#238923');
scene2.background = COLOR_YELLOW;

const geometry = new THREE.BoxGeometry();
const material1 = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const material2 = new THREE.MeshBasicMaterial({ color: 0x0000ff });

const cube1 = new THREE.Mesh(geometry, material1);
cube1.position.x = -1;
scene1.add(cube1);

const cube2 = new THREE.Mesh(geometry, material2);
cube2.position.x = 1;
scene2.add(cube2);


let backgroundTexture;
new RGBELoader()
	.load(backgroundImageUrl, function ( texture ) {
	  texture.mapping = THREE.EquirectangularReflectionMapping;
    backgroundTexture = texture;

    scene2.background = texture;
    scene2.backgroundIntensity = 1.0;
    scene2.backgroundBlurriness = 1.0;
 })

// Animation loop
function render() {
    renderer.clear();

    // Render first view (left half)
    const width = window.innerWidth;
    const height = window.innerHeight;
    
    const halfWidth = width / 2;
    const halfHeight = height / 2;
    
    renderer.autoClear = false;
    renderer.setViewport(0, 0, width, height);
    renderer.render(scene1, camera1);

    renderer.setScissorTest(true);
    
    renderer.setViewport(0, 0, halfWidth, halfHeight);
    renderer.setScissor(0, 0, halfWidth, halfHeight);
    
    renderer.render(scene2, camera2);
    // renderer.clear();
        
    renderer.setViewport(halfWidth, 0, halfWidth, halfHeight);
    renderer.setScissor(halfWidth, 0, halfWidth, halfHeight);

    renderer.render(scene2, camera2);
    
    renderer.autoClear = true;
    renderer.setScissorTest(false);
      
    requestAnimationFrame(render);
}

render();

Live example

https://jsfiddle.net/ZincCooper/f2753vg4/90/

Screenshots

background is texture
Image

background is solid color
Image

Version

173

Device

Desktop

Browser

Chrome

OS

MacOS

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 4, 2025

might be something wrong in my setup?

The problem is that you don't clear the viewports correctly which means the depth buffer contains values from the first render pass. It's best if you call renderer.clear(); every time you render into a sub-view.

https://jsfiddle.net/g6f9qo7L/

@Mugen87 Mugen87 closed this as completed Feb 4, 2025
@Mugen87 Mugen87 added this to the r174 milestone Feb 4, 2025
@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 4, 2025

Also notice that the viewport conventions in WebGPURenderer are different than in WebGLRenderer. The origin in WebGPURenderer is the top-left corner whereas in WebGLRenderer bottom-left.

We have changed that on purpose so WebGPURenderer matches the WebGPU spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants