Browse Source

Introduce FramebufferTexture. (#22916)

Michael Herzog 3 years ago
parent
commit
c748762b7e

+ 3 - 14
examples/jsm/objects/Lensflare.js

@@ -2,14 +2,12 @@ import {
 	AdditiveBlending,
 	Box2,
 	BufferGeometry,
-	ClampToEdgeWrapping,
 	Color,
-	DataTexture,
+	FramebufferTexture,
 	InterleavedBuffer,
 	InterleavedBufferAttribute,
 	Mesh,
 	MeshBasicMaterial,
-	NearestFilter,
 	RGBFormat,
 	RawShaderMaterial,
 	Vector2,
@@ -34,17 +32,8 @@ class Lensflare extends Mesh {
 
 		// textures
 
-		const tempMap = new DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, RGBFormat );
-		tempMap.minFilter = NearestFilter;
-		tempMap.magFilter = NearestFilter;
-		tempMap.wrapS = ClampToEdgeWrapping;
-		tempMap.wrapT = ClampToEdgeWrapping;
-
-		const occlusionMap = new DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, RGBFormat );
-		occlusionMap.minFilter = NearestFilter;
-		occlusionMap.magFilter = NearestFilter;
-		occlusionMap.wrapS = ClampToEdgeWrapping;
-		occlusionMap.wrapT = ClampToEdgeWrapping;
+		const tempMap = new FramebufferTexture( 16, 16, RGBFormat );
+		const occlusionMap = new FramebufferTexture( 16, 16, RGBFormat );
 
 		// material
 

+ 17 - 33
examples/jsm/utils/RoughnessMipmapper.js

@@ -14,7 +14,8 @@ import {
 	PlaneGeometry,
 	RawShaderMaterial,
 	Vector2,
-	WebGLRenderTarget
+	WebGLRenderTarget,
+	FramebufferTexture
 } from '../../../build/three.module.js';
 
 const _mipmapMaterial = _getMipmapMaterial();
@@ -68,42 +69,27 @@ class RoughnessMipmapper {
 
 		}
 
-		if ( width !== roughnessMap.image.width || height !== roughnessMap.image.height ) {
+		const newRoughnessTexture = new FramebufferTexture( width, height, roughnessMap.format );
+		newRoughnessTexture.wrapS = roughnessMap.wrapS;
+		newRoughnessTexture.wrapT = roughnessMap.wrapT;
+		newRoughnessTexture.minFilter = roughnessMap.minFilter;
+		newRoughnessTexture.magFilter = roughnessMap.magFilter;
 
-			const params = {
-				wrapS: roughnessMap.wrapS,
-				wrapT: roughnessMap.wrapT,
-				magFilter: roughnessMap.magFilter,
-				minFilter: roughnessMap.minFilter,
-				depthBuffer: false
-			};
+		material.roughnessMap = newRoughnessTexture;
 
-			const newRoughnessTarget = new WebGLRenderTarget( width, height, params );
+		if ( material.metalnessMap == roughnessMap ) material.metalnessMap = material.roughnessMap;
 
-			newRoughnessTarget.texture.generateMipmaps = true;
+		if ( material.aoMap == roughnessMap ) material.aoMap = material.roughnessMap;
 
-			// Setting the render target causes the memory to be allocated.
+		// Copy UV transform parameters
 
-			_renderer.setRenderTarget( newRoughnessTarget );
+		material.roughnessMap.offset.copy( roughnessMap.offset );
+		material.roughnessMap.repeat.copy( roughnessMap.repeat );
+		material.roughnessMap.center.copy( roughnessMap.center );
+		material.roughnessMap.rotation = roughnessMap.rotation;
 
-			material.roughnessMap = newRoughnessTarget.texture;
-
-			if ( material.metalnessMap == roughnessMap ) material.metalnessMap = material.roughnessMap;
-
-			if ( material.aoMap == roughnessMap ) material.aoMap = material.roughnessMap;
-
-			// Copy UV transform parameters
-
-			material.roughnessMap.offset.copy( roughnessMap.offset );
-			material.roughnessMap.repeat.copy( roughnessMap.repeat );
-			material.roughnessMap.center.copy( roughnessMap.center );
-			material.roughnessMap.rotation = roughnessMap.rotation;
-			material.roughnessMap.image = roughnessMap.image;
-
-			material.roughnessMap.matrixAutoUpdate = roughnessMap.matrixAutoUpdate;
-			material.roughnessMap.matrix.copy( roughnessMap.matrix );
-
-		}
+		material.roughnessMap.matrixAutoUpdate = roughnessMap.matrixAutoUpdate;
+		material.roughnessMap.matrix.copy( roughnessMap.matrix );
 
 		_mipmapMaterial.uniforms.roughnessMap.value = roughnessMap;
 
@@ -133,8 +119,6 @@ class RoughnessMipmapper {
 
 			_renderer.copyFramebufferToTexture( position, material.roughnessMap, mip );
 
-			_mipmapMaterial.uniforms.roughnessMap.value = material.roughnessMap;
-
 		}
 
 		if ( roughnessMap !== material.roughnessMap ) roughnessMap.dispose();

+ 1 - 3
examples/webgl_framebuffer_texture.html

@@ -95,9 +95,7 @@
 
 				//
 
-				const data = new Uint8Array( textureSize * textureSize * 3 );
-
-				texture = new THREE.DataTexture( data, textureSize, textureSize, THREE.RGBFormat );
+				texture = new THREE.FramebufferTexture( textureSize, textureSize, THREE.RGBFormat );
 				texture.minFilter = THREE.NearestFilter;
 				texture.magFilter = THREE.NearestFilter;
 

+ 1 - 0
src/Three.js

@@ -26,6 +26,7 @@ export { Line } from './objects/Line.js';
 export { Points } from './objects/Points.js';
 export { Group } from './objects/Group.js';
 export { VideoTexture } from './textures/VideoTexture.js';
+export { FramebufferTexture } from './textures/FramebufferTexture.js';
 export { DataTexture } from './textures/DataTexture.js';
 export { DataTexture2DArray } from './textures/DataTexture2DArray.js';
 export { DataTexture3D } from './textures/DataTexture3D.js';

+ 7 - 0
src/renderers/WebGLRenderer.js

@@ -2038,6 +2038,13 @@ function WebGLRenderer( parameters = {} ) {
 
 	this.copyFramebufferToTexture = function ( position, texture, level = 0 ) {
 
+		if ( texture.isFramebufferTexture !== true ) {
+
+			console.error( 'THREE.WebGLRenderer: copyFramebufferToTexture() can only be used with FramebufferTexture.' );
+			return;
+
+		}
+
 		const levelScale = Math.pow( 2, - level );
 		const width = Math.floor( texture.image.width * levelScale );
 		const height = Math.floor( texture.image.height * levelScale );

+ 4 - 0
src/renderers/webgl/WebGLTextures.js

@@ -709,6 +709,10 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 			state.texImage3D( _gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );
 
+		} else if ( texture.isFramebufferTexture ) {
+
+			// texture data extracted from framebuffers require mutuable textures defined via gl.copyTexImage2D()
+
 		} else {
 
 			// regular Texture (image, video, canvas)

+ 25 - 0
src/textures/FramebufferTexture.js

@@ -0,0 +1,25 @@
+import { Texture } from './Texture.js';
+import { NearestFilter } from '../constants.js';
+
+class FramebufferTexture extends Texture {
+
+	constructor( width, height, format ) {
+
+		super( { width, height } );
+
+		this.format = format;
+
+		this.magFilter = NearestFilter;
+		this.minFilter = NearestFilter;
+
+		this.generateMipmaps = false;
+
+		this.needsUpdate = true;
+
+	}
+
+}
+
+FramebufferTexture.prototype.isFramebufferTexture = true;
+
+export { FramebufferTexture };