Browse Source

WebGPURenderer: Enhance GLSL Error in WebGLBackend (#28594)

* add node.outputCode and improve glsl errors in webglbackend

* cleanup

* split PRs
Renaud Rohlinger 1 năm trước cách đây
mục cha
commit
62fa25e092

+ 5 - 0
examples/jsm/renderers/common/Renderer.js

@@ -133,6 +133,11 @@ class Renderer {
 			enabled: false
 		};
 
+		this.debug = {
+			checkShaderErrors: true,
+			onShaderError: null
+		};
+
 	}
 
 	async init() {

+ 86 - 7
examples/jsm/renderers/webgl/WebGLBackend.js

@@ -875,6 +875,90 @@ class WebGLBackend extends Backend {
 
 	}
 
+
+
+	_handleSource( string, errorLine ) {
+
+		const lines = string.split( '\n' );
+		const lines2 = [];
+
+		const from = Math.max( errorLine - 6, 0 );
+		const to = Math.min( errorLine + 6, lines.length );
+
+		for ( let i = from; i < to; i ++ ) {
+
+			const line = i + 1;
+			lines2.push( `${line === errorLine ? '>' : ' '} ${line}: ${lines[ i ]}` );
+
+		}
+
+		return lines2.join( '\n' );
+
+	}
+
+	_getShaderErrors( gl, shader, type ) {
+
+		const status = gl.getShaderParameter( shader, gl.COMPILE_STATUS );
+		const errors = gl.getShaderInfoLog( shader ).trim();
+
+		if ( status && errors === '' ) return '';
+
+		const errorMatches = /ERROR: 0:(\d+)/.exec( errors );
+		if ( errorMatches ) {
+
+			const errorLine = parseInt( errorMatches[ 1 ] );
+			return type.toUpperCase() + '\n\n' + errors + '\n\n' + this._handleSource( gl.getShaderSource( shader ), errorLine );
+
+		} else {
+
+			return errors;
+
+		}
+
+	}
+
+	_logProgramError( programGPU, glFragmentShader, glVertexShader ) {
+
+		if ( this.renderer.debug.checkShaderErrors ) {
+
+			const gl = this.gl;
+
+			const programLog = gl.getProgramInfoLog( programGPU ).trim();
+
+			if ( gl.getProgramParameter( programGPU, gl.LINK_STATUS ) === false ) {
+
+
+				if ( typeof this.renderer.debug.onShaderError === 'function' ) {
+
+					this.renderer.debug.onShaderError( gl, programGPU, glVertexShader, glFragmentShader );
+
+				} else {
+
+					// default error reporting
+
+					const vertexErrors = this._getShaderErrors( gl, glVertexShader, 'vertex' );
+					const fragmentErrors = this._getShaderErrors( gl, glFragmentShader, 'fragment' );
+
+					console.error(
+						'THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' +
+						'VALIDATE_STATUS ' + gl.getProgramParameter( programGPU, gl.VALIDATE_STATUS ) + '\n\n' +
+						'Program Info Log: ' + programLog + '\n' +
+						vertexErrors + '\n' +
+						fragmentErrors
+					);
+
+				}
+
+			} else if ( programLog !== '' ) {
+
+				console.warn( 'THREE.WebGLProgram: Program Info Log:', programLog );
+
+			}
+
+		}
+
+	}
+
 	_completeCompile( renderObject, pipeline ) {
 
 		const gl = this.gl;
@@ -883,10 +967,7 @@ class WebGLBackend extends Backend {
 
 		if ( gl.getProgramParameter( programGPU, gl.LINK_STATUS ) === false ) {
 
-			console.error( 'THREE.WebGLBackend:', gl.getProgramInfoLog( programGPU ) );
-
-			console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( fragmentShader ) );
-			console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( vertexShader ) );
+			this._logProgramError( programGPU, fragmentShader, vertexShader );
 
 		}
 
@@ -951,10 +1032,8 @@ class WebGLBackend extends Backend {
 
 		if ( gl.getProgramParameter( programGPU, gl.LINK_STATUS ) === false ) {
 
-			console.error( 'THREE.WebGLBackend:', gl.getProgramInfoLog( programGPU ) );
+			this._logProgramError( programGPU, fragmentShader, vertexShader );
 
-			console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( fragmentShader ) );
-			console.error( 'THREE.WebGLBackend:', gl.getShaderInfoLog( vertexShader ) );
 
 		}
 

+ 1 - 1
examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js

@@ -615,7 +615,7 @@ ${ flowData.code }
 
 				const extentions = this.renderer.backend.extensions;
 
-				if ( extentions.has( 'OES_texture_float_linear' ) )  {
+				if ( extentions.has( 'OES_texture_float_linear' ) ) {
 
 					extentions.get( 'OES_texture_float_linear' );
 					result = true;

+ 1 - 1
examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js

@@ -689,7 +689,7 @@ ${ flowData.code }
 
 			snippets.push( snippet );
 
-			snippets.push( `\nvar<private> output : ${ name };\n\n`);
+			snippets.push( `\nvar<private> output : ${ name };\n\n` );
 
 		}