Skip to content

Renderer: Add MRT support to .readRenderTargetPixels(). #22403

Open
@LuckyTeresa

Description

Describe the bug
I used WebGLMultipleRenderTargets to output several textures , then I set one of these textures to WebGLRenderTarget's texture,
then I passed these WebGLRenderTexture to WebGLRenderer.readRenderTargetPixels to get one pixel’value, but I only got (0,0,0,0) from the Float32Array I have passed

To Reproduce

Steps to reproduce the behavior:
1、if "rt" is a WebGLRenderTarget, setRenderTarget to "rt", eg. renderer.setRenderTarget(rt);
2、render something to it;
3、if I have another WebglRenderTarget "rt2", rt2.setTexture(rt.texture);
4、const read = new Float32Array( 4 );renderer.readRenderTargetPixels( rt2,posX, posY, 1, 1, new Float32Array( 4 ) );

or you can copy following code to three.js/examples/webgl_read_float_buffer.html, and replace the script part. I have only changed a small of them

Code

// code goes here
                       <script type="module">
			import * as THREE from '../build/three.module.js';

			import Stats from './jsm/libs/stats.module.js';

			let container, stats;

			let cameraRTT, sceneRTT, sceneScreen, renderer, zmesh1, zmesh2, rtTexture2;

			let mouseX = 0, mouseY = 0;

			const windowHalfX = window.innerWidth / 2;
			const windowHalfY = window.innerHeight / 2;

			let rtTexture, material, quad, materialScreen;

			let delta = 0.01;
			let valueNode;

			init();
			animate();

			function init() {

				container = document.getElementById( 'container' );

				cameraRTT = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, - 10000, 10000 );
				cameraRTT.position.z = 100;

				//

				sceneRTT = new THREE.Scene();
				sceneScreen = new THREE.Scene();

				let light = new THREE.DirectionalLight( 0xffffff );
				light.position.set( 0, 0, 1 ).normalize();
				sceneRTT.add( light );

				light = new THREE.DirectionalLight( 0xffaaaa, 1.5 );
				light.position.set( 0, 0, - 1 ).normalize();
				sceneRTT.add( light );

				rtTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat, type: THREE.FloatType } );
				rtTexture2 = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat, type: THREE.FloatType } );

				material = new THREE.ShaderMaterial( {

					uniforms: { "time": { value: 0.0 } },
					vertexShader: document.getElementById( 'vertexShader' ).textContent,
					fragmentShader: document.getElementById( 'fragment_shader_pass_1' ).textContent

				} );

				materialScreen = new THREE.ShaderMaterial( {

					uniforms: { "tDiffuse": { value: rtTexture.texture } },
					vertexShader: document.getElementById( 'vertexShader' ).textContent,
					fragmentShader: document.getElementById( 'fragment_shader_screen' ).textContent,

					depthWrite: false

				} );

				const plane = new THREE.PlaneGeometry( window.innerWidth, window.innerHeight );

				quad = new THREE.Mesh( plane, material );
				quad.position.z = - 100;
				sceneRTT.add( quad );

				const geometry = new THREE.TorusGeometry( 100, 25, 15, 30 );

				const mat1 = new THREE.MeshPhongMaterial( { color: 0x555555, specular: 0xffaa00, shininess: 5 } );
				const mat2 = new THREE.MeshPhongMaterial( { color: 0x550000, specular: 0xff2200, shininess: 5 } );

				zmesh1 = new THREE.Mesh( geometry, mat1 );
				zmesh1.position.set( 0, 0, 100 );
				zmesh1.scale.set( 1.5, 1.5, 1.5 );
				sceneRTT.add( zmesh1 );

				zmesh2 = new THREE.Mesh( geometry, mat2 );
				zmesh2.position.set( 0, 150, 100 );
				zmesh2.scale.set( 0.75, 0.75, 0.75 );
				sceneRTT.add( zmesh2 );

				quad = new THREE.Mesh( plane, materialScreen );
				quad.position.z = - 100;
				sceneScreen.add( quad );

				renderer = new THREE.WebGLRenderer();
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				renderer.autoClear = false;

				container.appendChild( renderer.domElement );

				stats = new Stats();
				container.appendChild( stats.dom );

				valueNode = document.getElementById( 'values' );

				document.addEventListener( 'mousemove', onDocumentMouseMove );

			}

			function onDocumentMouseMove( event ) {

				mouseX = ( event.clientX - windowHalfX );
				mouseY = ( event.clientY - windowHalfY );
				// console.log(mouseX, mouseY);

			}

			//

			function animate() {

				requestAnimationFrame( animate );

				render();
				stats.update();

			}

			function render() {

				const time = Date.now() * 0.0015;

				if ( zmesh1 && zmesh2 ) {

					zmesh1.rotation.y = - time;
					zmesh2.rotation.y = - time + Math.PI / 2;

				}

				if ( material.uniforms[ "time" ].value > 1 || material.uniforms[ "time" ].value < 0 ) {

					delta *= - 1;

				}

				material.uniforms[ "time" ].value += delta;

				renderer.clear();

				// Render first scene into texture

				// renderer.setRenderTarget( rtTexture );
				renderer.setRenderTarget( rtTexture2 );
				renderer.clear();
				renderer.render( sceneRTT, cameraRTT );

				materialScreen.uniforms.tDiffuse.value = rtTexture2.texture;

				// Render full screen quad with generated texture

				renderer.setRenderTarget( null );
				renderer.render( sceneScreen, cameraRTT );

				const read = new Float32Array( 4 );
				console.log(windowHalfX + mouseX, windowHalfY - mouseY);
				rtTexture.setTexture(rtTexture2.texture);
				renderer.readRenderTargetPixels( rtTexture, windowHalfX + mouseX, windowHalfY - mouseY, 1, 1, read );

				valueNode.innerHTML = 'r:' + read[ 0 ] + '<br/>g:' + read[ 1 ] + '<br/>b:' + read[ 2 ];

			}
                       </script>

Live example
no live example,I cann't visit these links

Expected behavior
I hope I can get a effective value from the ArrayBufferView object, rather than 0.

Screenshots

Platform:

  • Device: [Desktop]
  • OS: [Windows10]
  • Browser: [Chrome]
  • Three.js version: [master, r130.1]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions