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

Nodes: Optional varying interpolation (#24821)

* Extends NodeVarying from NodeVar and added .needsInterpolation property

* Add .needsInterpolation approach

* Optional varying interpolation

* cleanup
sunag 2 лет назад
Родитель
Сommit
0f89c6c4f5

+ 7 - 4
examples/jsm/nodes/core/NodeVarying.js

@@ -1,11 +1,14 @@
-class NodeVarying {
+import NodeVar from './NodeVar.js';
+
+class NodeVarying extends NodeVar {
 
 	constructor( name, type ) {
 
-		this.isNodeVarying = true;
+		super( name, type );
 
-		this.name = name;
-		this.type = type;
+		this.needsInterpolation = false;
+
+		this.isNodeVarying = true;
 
 	}
 

+ 4 - 2
examples/jsm/nodes/core/VaryingNode.js

@@ -28,12 +28,14 @@ class VaryingNode extends Node {
 
 	generate( builder ) {
 
+		const { name, node } = this;
 		const type = this.getNodeType( builder );
-		const node = this.node;
-		const name = this.name;
 
 		const nodeVarying = builder.getVaryingFromNode( this, type );
 
+		// this property can be used to check if the varying can be optimized for a var
+		nodeVarying.needsInterpolation ||= builder.shaderStage === 'fragment';
+
 		if ( name !== null ) {
 
 			nodeVarying.name = name;

+ 20 - 4
examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js

@@ -511,15 +511,31 @@ class WebGLNodeBuilder extends NodeBuilder {
 
 	}
 
-	getVaryings( /* shaderStage */ ) {
+	getVaryings( shaderStage ) {
 
 		let snippet = '';
 
 		const varyings = this.varyings;
 
-		for ( const varying of varyings ) {
+		if ( shaderStage === 'vertex' ) {
+
+			for ( const varying of varyings ) {
+
+				snippet += `${varying.needsInterpolation ? 'varying' : '/*varying*/'} ${varying.type} ${varying.name}; `;
+
+			}
+
+		} else if ( shaderStage === 'fragment' ) {
 
-			snippet += `varying ${varying.type} ${varying.name}; `;
+			for ( const varying of varyings ) {
+
+				if ( varying.needsInterpolation ) {
+
+					snippet += `varying ${varying.type} ${varying.name}; `;
+
+				}
+
+			}
 
 		}
 
@@ -702,7 +718,7 @@ ${this.shader[ getShaderStageProperty( shaderStage ) ]}
 			this.addCode(
 				shaderStage,
 				'main() {',
-				this.flowCode[ shaderStage ]
+				'\n\t' + this.flowCode[ shaderStage ]
 			);
 
 		}

+ 21 - 3
examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js

@@ -200,7 +200,7 @@ class WebGPUNodeBuilder extends NodeBuilder {
 
 	getPropertyName( node, shaderStage = this.shaderStage ) {
 
-		if ( node.isNodeVarying === true ) {
+		if ( node.isNodeVarying === true && node.needsInterpolation === true ) {
 
 			if ( shaderStage === 'vertex' ) {
 
@@ -463,24 +463,42 @@ class WebGPUNodeBuilder extends NodeBuilder {
 			this.getBuiltin( 'position', 'Vertex', 'vec4<f32>', 'vertex' );
 
 			const varyings = this.varyings;
+			const vars = this.vars[ shaderStage ];
 
 			for ( let index = 0; index < varyings.length; index ++ ) {
 
 				const varying = varyings[ index ];
 
-				snippets.push( `@location( ${index} ) ${ varying.name } : ${ this.getType( varying.type ) }` );
+				if ( varying.needsInterpolation ) {
+
+					snippets.push( `@location( ${index} ) ${ varying.name } : ${ this.getType( varying.type ) }` );
+
+				} else if ( vars.includes( varying ) === false ) {
+
+					vars.push( varying );
+
+				}
 
 			}
 
 		} else if ( shaderStage === 'fragment' ) {
 
 			const varyings = this.varyings;
+			const vars = this.vars[ shaderStage ];
 
 			for ( let index = 0; index < varyings.length; index ++ ) {
 
 				const varying = varyings[ index ];
 
-				snippets.push( `@location( ${index} ) ${ varying.name } : ${ this.getType( varying.type ) }` );
+				if ( varying.needsInterpolation ) {
+
+					snippets.push( `@location( ${index} ) ${ varying.name } : ${ this.getType( varying.type ) }` );
+
+				} else if ( vars.includes( varying ) === false ) {
+
+					vars.push( varying );
+
+				}
 
 			}