浏览代码

WebGLRenderer: Added .copyFramebufferToTexture()

Mugen87 7 年之前
父节点
当前提交
d1ce80c9f8
共有 4 个文件被更改,包括 237 次插入1 次删除
  1. 12 0
      build/three.js
  2. 4 1
      docs/api/renderers/WebGLRenderer.html
  3. 209 0
      examples/webgl_framebuffer_texture.html
  4. 12 0
      src/renderers/WebGLRenderer.js

+ 12 - 0
build/three.js

@@ -23764,6 +23764,18 @@
 
 		};
 
+		this.copyFramebufferToTexture = function ( x, y, texture, level ) {
+
+			var width = texture.image.width;
+			var height = texture.image.height;
+			var internalFormat = utils.convert( texture.format );
+
+			this.setTexture2D( texture, 0 );
+
+			_gl.copyTexImage2D( _gl.TEXTURE_2D, level || 0, internalFormat, x, y, width, height, 0 );
+
+		};
+
 	}
 
 	/**

+ 4 - 1
docs/api/renderers/WebGLRenderer.html

@@ -52,7 +52,7 @@
 
 		[page:Boolean preserveDrawingBuffer] - whether to preserve the buffers until manually cleared
 		or overwritten. Default is *false*.<br />
-		
+
 		[page:String powerPreference] - Provides a hint to the user agent indicating what configuration
 		of GPU is suitable for this WebGL context. Can be *"high-performance"*, *"low-power"* or *"default"*. Default is *"default"*.<br />
 
@@ -324,6 +324,9 @@
 		<h3>[method:null compile]( [page:Scene scene], [page:Camera camera] )</h3>
 		<div>Compiles all materials in the scene with the camera. This is useful to precompile shaders before the first rendering.</div>
 
+		<h3>[method:null copyFramebufferToTexture]( [page:Number x], [page:Number y], [page:Texture texture], [page:Number level] )</h3>
+		<div>Copies pixels from the current WebGLFramebuffer into a 2D texture. Enables access to [link:https://developer.mozilla.org/de/docs/Web/API/WebGLRenderingContext/copyTexImage2D WebGLRenderingContext.copyTexImage2D].</div>
+
 		<h3>[method:null dispose]( )</h3>
 		<div>Dispose of the current rendering context.</div>
 

+ 209 - 0
examples/webgl_framebuffer_texture.html

@@ -0,0 +1,209 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - framebuffer - texture</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				background:#777;
+				padding:0;
+				margin:0;
+				overflow:hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px;
+				width: 100%;
+				color: #ffffff;
+				padding: 5px;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+			}
+
+			a {
+				color: #ffffff;
+			}
+
+			#overlay {
+				position: fixed;
+		    display: flex;
+		    flex-direction: column;
+		    justify-content: center;
+		    align-items: center;
+		    height: 100%;
+		    width: 100%;
+				top: 0;
+  			z-index: 999;
+			}
+
+			#overlay > div {
+		    height: 256px;
+		    width: 256px;
+				border: 1px solid white;
+			}
+		</style>
+
+		<script src="../build/three.js"></script>
+		<script src="js/controls/OrbitControls.js"></script>
+		<script src="js/Detector.js"></script>
+
+	</head>
+	<body>
+
+		<div id="container"></div>
+		<div id="info">
+			<a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> framebuffer to texture <br/>
+			The area of the white square is copied from the framebuffer to a texture (shown in the top-left corner).
+		</div>
+
+		<div id="overlay">
+			<div>
+			</div>
+		</div>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var camera, scene, renderer;
+			var mesh, sprite, texture;
+
+			var cameraOrtho, sceneOrtho;
+
+			var dpr = window.devicePixelRatio;
+
+			var imageWidth = 256 * dpr;
+			var imageHeight = 256 * dpr;
+
+			init();
+			animate();
+
+			function init() {
+
+				//
+
+				var width = window.innerWidth;
+				var height = window.innerHeight;
+
+				camera = new THREE.PerspectiveCamera( 70, width / height, 1, 1000 );
+				camera.position.z = 20;
+
+				cameraOrtho = new THREE.OrthographicCamera( - width / 2, width / 2, height / 2, - height / 2, 1, 10 );
+				cameraOrtho.position.z = 10;
+
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0x20252f );
+				sceneOrtho = new THREE.Scene();
+
+				//
+
+				var geometry = new THREE.TorusKnotBufferGeometry( 3, 1, 256, 32 );
+				var material = new THREE.MeshStandardMaterial( { color: 0x6083c2 } );
+
+				mesh = new THREE.Mesh( geometry, material );
+				scene.add( mesh );
+
+				//
+				var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
+				scene.add( ambientLight );
+
+				var pointLight = new THREE.PointLight( 0xffffff, 0.8 );
+				camera.add( pointLight );
+				scene.add( camera );
+
+				//
+
+				texture = new THREE.Texture();
+				texture.image = new Image( imageWidth, imageHeight );
+				texture.format = THREE.RGBFormat;
+				texture.minFilter = texture.magFilter = THREE.NearestFilter;
+
+				//
+
+				var spriteMaterial = new THREE.SpriteMaterial( { map: texture } );
+				sprite = new THREE.Sprite( spriteMaterial );
+				sprite.scale.set( imageWidth, imageHeight, 1 );
+				sceneOrtho.add( sprite );
+
+				updateSpritePosition();
+
+				//
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.autoClear = false;
+				document.body.appendChild( renderer.domElement );
+
+				//
+
+				var overlay = document.getElementById( 'overlay' );
+				var controls = new THREE.OrbitControls( camera, overlay );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				var width = window.innerWidth;
+				var height = window.innerHeight;
+
+				camera.aspect = width / height;
+				camera.updateProjectionMatrix();
+
+				cameraOrtho.left = - width / 2;
+				cameraOrtho.right = width / 2;
+				cameraOrtho.top = height / 2;
+				cameraOrtho.bottom = - height / 2;
+				cameraOrtho.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				updateSpritePosition();
+
+			}
+
+			function updateSpritePosition() {
+
+				var halfWidth = window.innerWidth / 2;
+				var halfHeight = window.innerHeight / 2;
+
+				var halfImageWidth = imageWidth / 2;
+				var halfImageHeight = imageHeight / 2;
+
+				sprite.position.set( - halfWidth + halfImageWidth, halfHeight - halfImageHeight, 1 );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				mesh.rotation.x += 0.005;
+				mesh.rotation.y += 0.01;
+
+				renderer.clear();
+				renderer.render( scene, camera );
+
+				// calculate start position for copying data
+
+				var x = ( window.innerWidth * dpr / 2 ) - ( imageWidth / 2 );
+				var y = ( window.innerHeight * dpr / 2 ) - ( imageHeight / 2 );
+
+				renderer.copyFramebufferToTexture( x, y, texture );
+
+				renderer.clearDepth();
+				renderer.render( sceneOrtho, cameraOrtho );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 12 - 0
src/renderers/WebGLRenderer.js

@@ -2559,6 +2559,18 @@ function WebGLRenderer( parameters ) {
 
 	};
 
+	this.copyFramebufferToTexture = function ( x, y, texture, level ) {
+
+		var width = texture.image.width;
+		var height = texture.image.height;
+		var internalFormat = utils.convert( texture.format );
+
+		this.setTexture2D( texture, 0 );
+
+		_gl.copyTexImage2D( _gl.TEXTURE_2D, level || 0, internalFormat, x, y, width, height, 0 );
+
+	};
+
 }