Просмотр исходного кода

EXRExporter: Add support for WebGPURenderer. (#29302)

Michael Herzog 1 год назад
Родитель
Сommit
59c9820c41

+ 19 - 11
examples/jsm/exporters/EXRExporter.js

@@ -21,20 +21,20 @@ const ZIP_COMPRESSION = 3;
 
 class EXRExporter {
 
-	parse( arg1, arg2, arg3 ) {
+	async parse( arg1, arg2, arg3 ) {
 
-		if ( ! arg1 || ! ( arg1.isWebGLRenderer || arg1.isDataTexture ) ) {
+		if ( ! arg1 || ! ( arg1.isWebGLRenderer || arg1.isWebGPURenderer || arg1.isDataTexture ) ) {
 
 			throw Error( 'EXRExporter.parse: Unsupported first parameter, expected instance of WebGLRenderer or DataTexture.' );
 
-		} else if ( arg1.isWebGLRenderer ) {
+		} else if ( arg1.isWebGLRenderer || arg1.isWebGPURenderer ) {
 
 			const renderer = arg1, renderTarget = arg2, options = arg3;
 
 			supportedRTT( renderTarget );
 
 			const info = buildInfoRTT( renderTarget, options ),
-				dataBuffer = getPixelData( renderer, renderTarget, info ),
+				dataBuffer = await getPixelData( renderer, renderTarget, info ),
 				rawContentBuffer = reorganizeDataBuffer( dataBuffer, info ),
 				chunks = compressData( rawContentBuffer, info );
 
@@ -61,7 +61,7 @@ class EXRExporter {
 
 function supportedRTT( renderTarget ) {
 
-	if ( ! renderTarget || ! renderTarget.isWebGLRenderTarget ) {
+	if ( ! renderTarget || ! renderTarget.isRenderTarget ) {
 
 		throw Error( 'EXRExporter.parse: Unsupported second parameter, expected instance of WebGLRenderTarget.' );
 
@@ -189,22 +189,30 @@ function buildInfoDT( texture, options = {} ) {
 
 }
 
-function getPixelData( renderer, rtt, info ) {
+async function getPixelData( renderer, rtt, info ) {
 
 	let dataBuffer;
 
-	if ( info.type === FloatType ) {
+	if ( renderer.isWebGLRenderer ) {
 
-		dataBuffer = new Float32Array( info.width * info.height * info.numInputChannels );
+		if ( info.type === FloatType ) {
+
+			dataBuffer = new Float32Array( info.width * info.height * info.numInputChannels );
+
+		} else {
+
+			dataBuffer = new Uint16Array( info.width * info.height * info.numInputChannels );
+
+		}
+
+		renderer.readRenderTargetPixels( rtt, 0, 0, info.width, info.height, dataBuffer );
 
 	} else {
 
-		dataBuffer = new Uint16Array( info.width * info.height * info.numInputChannels );
+		dataBuffer = await renderer.readRenderTargetPixelsAsync( rtt, 0, 0, info.width, info.height );
 
 	}
 
-	renderer.readRenderTargetPixels( rtt, 0, 0, info.width, info.height, dataBuffer );
-
 	return dataBuffer;
 
 }

+ 3 - 3
examples/misc_exporter_exr.html

@@ -178,7 +178,7 @@
 
 			}
 
-			function exportFile() {
+			async function exportFile() {
 
 				let result, exportType, exportCompression;
 
@@ -195,9 +195,9 @@
 					exportCompression = NO_COMPRESSION;
 
 				if ( params.target == 'pmrem' )
-					result = exporter.parse( renderer, renderTarget, { type: exportType, compression: exportCompression } );
+					result = await exporter.parse( renderer, renderTarget, { type: exportType, compression: exportCompression } );
 				else
-					result = exporter.parse( dataTexture, { type: exportType, compression: exportCompression } );
+					result = await exporter.parse( dataTexture, { type: exportType, compression: exportCompression } );
 
 				saveArrayBuffer( result, params.target + '.exr' );
 

+ 19 - 5
src/renderers/webgl-fallback/utils/WebGLTextureUtils.js

@@ -818,7 +818,7 @@ class WebGLTextureUtils {
 		gl.framebufferTexture2D( gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureGPU, 0 );
 
 		const typedArrayType = this._getTypedArrayType( glType );
-		const bytesPerTexel = this._getBytesPerTexel( glFormat );
+		const bytesPerTexel = this._getBytesPerTexel( glType, glFormat );
 
 		const elementCount = width * height;
 		const byteLength = elementCount * bytesPerTexel;
@@ -856,19 +856,33 @@ class WebGLTextureUtils {
 		if ( glType === gl.UNSIGNED_SHORT ) return Uint16Array;
 		if ( glType === gl.UNSIGNED_INT ) return Uint32Array;
 
+		if ( glType === gl.HALF_FLOAT ) return Uint16Array;
 		if ( glType === gl.FLOAT ) return Float32Array;
 
 		throw new Error( `Unsupported WebGL type: ${glType}` );
 
 	}
 
-	_getBytesPerTexel( glFormat ) {
+	_getBytesPerTexel( glType, glFormat ) {
 
 		const { gl } = this;
 
-		if ( glFormat === gl.RGBA ) return 4;
-		if ( glFormat === gl.RGB ) return 3;
-		if ( glFormat === gl.ALPHA ) return 1;
+		let bytesPerComponent = 0;
+
+		if ( glType === gl.UNSIGNED_BYTE ) bytesPerComponent = 1;
+
+		if ( glType === gl.UNSIGNED_SHORT_4_4_4_4 ||
+			glType === gl.UNSIGNED_SHORT_5_5_5_1 ||
+			glType === gl.UNSIGNED_SHORT_5_6_5 ||
+			glType === gl.UNSIGNED_SHORT ||
+			glType === gl.HALF_FLOAT ) bytesPerComponent = 2;
+
+		if ( glType === gl.UNSIGNED_INT ||
+			glType === gl.FLOAT ) bytesPerComponent = 4;
+
+		if ( glFormat === gl.RGBA ) return bytesPerComponent * 4;
+		if ( glFormat === gl.RGB ) return bytesPerComponent * 3;
+		if ( glFormat === gl.ALPHA ) return bytesPerComponent;
 
 	}
 

+ 3 - 3
src/renderers/webgpu/utils/WebGPUTextureUtils.js

@@ -792,9 +792,9 @@ class WebGPUTextureUtils {
 		if ( format === GPUTextureFormat.RG16Sint ) return Int16Array;
 		if ( format === GPUTextureFormat.RGBA16Uint ) return Uint16Array;
 		if ( format === GPUTextureFormat.RGBA16Sint ) return Int16Array;
-		if ( format === GPUTextureFormat.R16Float ) return Float32Array;
-		if ( format === GPUTextureFormat.RG16Float ) return Float32Array;
-		if ( format === GPUTextureFormat.RGBA16Float ) return Float32Array;
+		if ( format === GPUTextureFormat.R16Float ) return Uint16Array;
+		if ( format === GPUTextureFormat.RG16Float ) return Uint16Array;
+		if ( format === GPUTextureFormat.RGBA16Float ) return Uint16Array;
 
 
 		if ( format === GPUTextureFormat.R32Uint ) return Uint32Array;

粤ICP备19079148号