Quellcode durchsuchen

WebGLRenderer: Refactored render loop and fix transmission in VR (#22426)

* WebGLRenderer: Refactored rende loop and fix transmission in VR.

* Examples: Added transmission to webxr_vr_sandbox.

* Updated webxr_vr_sandbox screenshot.

* Updated builds.

* Added thickness slider to webxr_vr_sandbox.

* Updated webxr_vr_sandbox screenshot.

* Revert "Updated builds."

This reverts commit c5e295fbe018829fd57fe9ff41832c03fe754298.
Mr.doob vor 3 Jahren
Ursprung
Commit
14663f5891

BIN
examples/screenshots/webxr_vr_sandbox.jpg


BIN
examples/textures/equirectangular/moonless_golf_1k.hdr


+ 32 - 43
examples/webxr_vr_sandbox.html

@@ -11,6 +11,7 @@
 
 			import * as THREE from '../build/three.module.js';
 
+			import { RGBELoader } from './jsm/loaders/RGBELoader.js';
 			import { Lensflare, LensflareElement } from './jsm/objects/Lensflare.js';
 			import { Reflector } from './jsm/objects/Reflector.js';
 			import { VRButton } from './jsm/webxr/VRButton.js';
@@ -25,12 +26,13 @@
 			let reflector;
 
 			const parameters = {
-				radius: 0.5,
+				radius: 0.6,
 				tube: 0.2,
 				tubularSegments: 150,
 				radialSegments: 20,
 				p: 2,
-				q: 3
+				q: 3,
+				thickness: 0.5
 			};
 
 			init();
@@ -38,12 +40,18 @@
 
 			function init() {
 
-				const background = new THREE.CubeTextureLoader()
-					.setPath( 'textures/cube/MilkyWay/' )
-					.load( [ 'dark-s_px.jpg', 'dark-s_nx.jpg', 'dark-s_py.jpg', 'dark-s_ny.jpg', 'dark-s_pz.jpg', 'dark-s_nz.jpg' ] );
-
 				scene = new THREE.Scene();
-				scene.background = background;
+
+				new RGBELoader()
+					.setPath( 'textures/equirectangular/' )
+					.load( 'moonless_golf_1k.hdr', function ( texture ) {
+
+						texture.mapping = THREE.EquirectangularReflectionMapping;
+
+						scene.background = texture;
+						scene.environment = texture;
+
+					} );
 
 				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 10 );
 				camera.position.set( 0, 1.6, 1.5 );
@@ -51,49 +59,25 @@
 				//
 
 				const torusGeometry = new THREE.TorusKnotGeometry( ...Object.values( parameters ) );
-				const torusMaterial = new THREE.MeshStandardMaterial( { roughness: 0.01, metalness: 0.2, envMap: background } );
+				const torusMaterial = new THREE.MeshPhysicalMaterial( {
+					transmission: 1.0, roughness: 0, metalness: 0.25, thickness: 0.5
+				} );
 				const torus = new THREE.Mesh( torusGeometry, torusMaterial );
 				torus.name = 'torus';
-				torus.position.y = 1.25;
+				torus.position.y = 1.5;
 				torus.position.z = - 2;
-				torus.castShadow = true;
-				torus.receiveShadow = true;
 				scene.add( torus );
 
 				const cylinderGeometry = new THREE.CylinderGeometry( 1, 1, 0.1, 50 );
-				const cylinderMaterial = new THREE.MeshPhongMaterial();
+				const cylinderMaterial = new THREE.MeshStandardMaterial();
 				const cylinder = new THREE.Mesh( cylinderGeometry, cylinderMaterial );
 				cylinder.position.z = - 2;
-				cylinder.castShadow = true;
-				cylinder.receiveShadow = true;
 				scene.add( cylinder );
 
-				const light1 = new THREE.DirectionalLight( 0x8800ff );
-				light1.position.set( - 1, 1.5, - 1.5 );
-				light1.castShadow = true;
-				light1.shadow.camera.zoom = 4;
-				scene.add( light1 );
-				light1.target.position.set( 0, 0, - 2 );
-				scene.add( light1.target );
-
-				// const helper1 = new THREE.CameraHelper( light.shadow.camera );
-				// scene.add( helper1 );
-
-				const light2 = new THREE.DirectionalLight( 0xff0000 );
-				light2.position.set( 1, 1.5, - 2.5 );
-				light2.castShadow = true;
-				light2.shadow.camera.zoom = 4;
-				scene.add( light2 );
-				light2.target.position.set( 0, 0, - 2 );
-				scene.add( light2.target );
-
-				// const helper2 = new THREE.CameraHelper( light.shadow.camera );
-				// scene.add( helper2 );
-
 				// lensflare
 				const loader = new THREE.TextureLoader();
-				const texture0 = loader.load( "textures/lensflare/lensflare0.png" );
-				const texture3 = loader.load( "textures/lensflare/lensflare3.png" );
+				const texture0 = loader.load( 'textures/lensflare/lensflare0.png' );
+				const texture3 = loader.load( 'textures/lensflare/lensflare3.png' );
 
 				const lensflare = new Lensflare();
 				lensflare.position.set( 0, 5, - 5 );
@@ -111,17 +95,16 @@
 					textureHeight: window.innerHeight * window.devicePixelRatio
 				} );
 				reflector.position.x = 1;
-				reflector.position.y = 1.25;
+				reflector.position.y = 1.5;
 				reflector.position.z = - 3;
 				reflector.rotation.y = - Math.PI / 4;
-				scene.add( reflector );
+				// TOFIX: Reflector breaks transmission
+				// scene.add( reflector );
 
 				const frameGeometry = new THREE.BoxGeometry( 2.1, 2.1, 0.1 );
 				const frameMaterial = new THREE.MeshPhongMaterial();
 				const frame = new THREE.Mesh( frameGeometry, frameMaterial );
 				frame.position.z = - 0.07;
-				frame.castShadow = true;
-				frame.receiveShadow = true;
 				reflector.add( frame );
 
 				//
@@ -130,7 +113,6 @@
 				renderer.autoClear = false;
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.shadowMap.enabled = true;
 				renderer.xr.enabled = true;
 				document.body.appendChild( renderer.domElement );
 
@@ -172,6 +154,12 @@
 
 				}
 
+				function onThicknessChange() {
+
+					torus.material.thickness = parameters.thickness;
+
+				}
+
 				const gui = new GUI( { width: 300 } );
 				gui.add( parameters, 'radius', 0.0, 1.0 ).onChange( onChange );
 				gui.add( parameters, 'tube', 0.0, 1.0 ).onChange( onChange );
@@ -179,6 +167,7 @@
 				gui.add( parameters, 'radialSegments', 2, 20, 1 ).onChange( onChange );
 				gui.add( parameters, 'p', 1, 10, 1 ).onChange( onChange );
 				gui.add( parameters, 'q', 0, 10, 1 ).onChange( onChange );
+				gui.add( parameters, 'thickness', 0, 1 ).onChange( onThicknessChange );
 				gui.domElement.style.visibility = 'hidden';
 
 				const group = new InteractiveGroup( renderer, camera );

+ 44 - 50
src/renderers/WebGLRenderer.js

@@ -1033,9 +1033,6 @@ function WebGLRenderer( parameters = {} ) {
 
 		shadowMap.render( shadowsArray, scene, camera );
 
-		currentRenderState.setupLights( _this.physicallyCorrectLights );
-		currentRenderState.setupLightsView( camera );
-
 		if ( _clippingEnabled === true ) clipping.endShadows();
 
 		//
@@ -1048,13 +1045,25 @@ function WebGLRenderer( parameters = {} ) {
 
 		// render scene
 
-		const opaqueObjects = currentRenderList.opaque;
-		const transmissiveObjects = currentRenderList.transmissive;
-		const transparentObjects = currentRenderList.transparent;
+		currentRenderState.setupLights( _this.physicallyCorrectLights );
 
-		if ( opaqueObjects.length > 0 ) renderObjects( opaqueObjects, scene, camera );
-		if ( transmissiveObjects.length > 0 ) renderTransmissiveObjects( opaqueObjects, transmissiveObjects, scene, camera );
-		if ( transparentObjects.length > 0 ) renderObjects( transparentObjects, scene, camera );
+		if ( camera.isArrayCamera ) {
+
+			const cameras = camera.cameras;
+
+			for ( let i = 0, l = cameras.length; i < l; i ++ ) {
+
+				const camera2 = cameras[ i ];
+
+				renderScene( currentRenderList, scene, camera2, camera2.viewport );
+
+			}
+
+		} else {
+
+			renderScene( currentRenderList, scene, camera );
+
+		}
 
 		//
 
@@ -1239,7 +1248,25 @@ function WebGLRenderer( parameters = {} ) {
 
 	}
 
-	function renderTransmissiveObjects( opaqueObjects, transmissiveObjects, scene, camera ) {
+	function renderScene( currentRenderList, scene, camera, viewport ) {
+
+		const opaqueObjects = currentRenderList.opaque;
+		const transmissiveObjects = currentRenderList.transmissive;
+		const transparentObjects = currentRenderList.transparent;
+
+		currentRenderState.setupLightsView( camera );
+
+		if ( transmissiveObjects.length > 0 ) renderTransmissionPass( opaqueObjects, scene, camera );
+
+		if ( viewport ) state.viewport( _currentViewport.copy( viewport ) );
+
+		if ( opaqueObjects.length > 0 ) renderObjects( opaqueObjects, scene, camera );
+		if ( transmissiveObjects.length > 0 ) renderObjects( transmissiveObjects, scene, camera );
+		if ( transparentObjects.length > 0 ) renderObjects( transparentObjects, scene, camera );
+
+	}
+
+	function renderTransmissionPass( opaqueObjects, scene, camera ) {
 
 		if ( _transmissionRenderTarget === null ) {
 
@@ -1275,55 +1302,22 @@ function WebGLRenderer( parameters = {} ) {
 
 		_this.setRenderTarget( currentRenderTarget );
 
-		renderObjects( transmissiveObjects, scene, camera );
-
 	}
 
 	function renderObjects( renderList, scene, camera ) {
 
 		const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
 
-		if ( camera.isArrayCamera ) {
-
-			const cameras = camera.cameras;
-
-			for ( let i = 0, l = cameras.length; i < l; i ++ ) {
-
-				const camera2 = cameras[ i ];
-
-				state.viewport( _currentViewport.copy( camera2.viewport ) );
-
-				currentRenderState.setupLightsView( camera2 );
-
-				for ( let j = 0, jl = renderList.length; j < jl; j ++ ) {
-
-					const renderItem = renderList[ j ];
-
-					const object = renderItem.object;
-					const geometry = renderItem.geometry;
-					const material = overrideMaterial === null ? renderItem.material : overrideMaterial;
-					const group = renderItem.group;
-
-					if ( object.layers.test( camera2.layers ) ) {
-
-						renderObject( object, scene, camera2, geometry, material, group );
-
-					}
-
-				}
-
-			}
-
-		} else {
+		for ( let i = 0, l = renderList.length; i < l; i ++ ) {
 
-			for ( let j = 0, jl = renderList.length; j < jl; j ++ ) {
+			const renderItem = renderList[ i ];
 
-				const renderItem = renderList[ j ];
+			const object = renderItem.object;
+			const geometry = renderItem.geometry;
+			const material = overrideMaterial === null ? renderItem.material : overrideMaterial;
+			const group = renderItem.group;
 
-				const object = renderItem.object;
-				const geometry = renderItem.geometry;
-				const material = overrideMaterial === null ? renderItem.material : overrideMaterial;
-				const group = renderItem.group;
+			if ( object.layers.test( camera.layers ) ) {
 
 				renderObject( object, scene, camera, geometry, material, group );