未验证 提交 d9c4c8e1 编写于 作者: S sunag 提交者: GitHub

Node: add analyze() to optimization and validation (#23475)

* ShaderNode: fix use of swizzle in some nodes

* cleanup

* prevent use of vec4

* fix conversion format

* add Node.analyze()

* TempNode: not created var if it's is used only once
上级 34d92592
......@@ -302,16 +302,16 @@ export const and = ShaderNodeProxy( OperatorNode, '&&' );
export const element = ShaderNodeProxy( ArrayElementNode );
export const normalGeometry = new NormalNode( NormalNode.GEOMETRY );
export const normalLocal = new NormalNode( NormalNode.LOCAL );
export const normalWorld = new NormalNode( NormalNode.WORLD );
export const normalView = new NormalNode( NormalNode.VIEW );
export const transformedNormalView = new VarNode( new NormalNode( NormalNode.VIEW ), 'TransformedNormalView', 'vec3' );
export const normalGeometry = ShaderNodeObject( new NormalNode( NormalNode.GEOMETRY ) );
export const normalLocal = ShaderNodeObject( new NormalNode( NormalNode.LOCAL ) );
export const normalWorld = ShaderNodeObject( new NormalNode( NormalNode.WORLD ) );
export const normalView = ShaderNodeObject( new NormalNode( NormalNode.VIEW ) );
export const transformedNormalView = ShaderNodeObject( new VarNode( new NormalNode( NormalNode.VIEW ), 'TransformedNormalView', 'vec3' ) );
export const positionLocal = new PositionNode( PositionNode.LOCAL );
export const positionWorld = new PositionNode( PositionNode.WORLD );
export const positionView = new PositionNode( PositionNode.VIEW );
export const positionViewDirection = new PositionNode( PositionNode.VIEW_DIRECTION );
export const positionLocal = ShaderNodeObject( new PositionNode( PositionNode.LOCAL ) );
export const positionWorld = ShaderNodeObject( new PositionNode( PositionNode.WORLD ) );
export const positionView = ShaderNodeObject( new PositionNode( PositionNode.VIEW ) );
export const positionViewDirection = ShaderNodeObject( new PositionNode( PositionNode.VIEW_DIRECTION ) );
export const PI = float( 3.141592653589793 );
export const PI2 = float( 6.283185307179586 );
......@@ -320,11 +320,11 @@ export const RECIPROCAL_PI = float( 0.3183098861837907 );
export const RECIPROCAL_PI2 = float( 0.15915494309189535 );
export const EPSILON = float( 1e-6 );
export const diffuseColor = new PropertyNode( 'DiffuseColor', 'vec4' );
export const roughness = new PropertyNode( 'Roughness', 'float' );
export const metalness = new PropertyNode( 'Metalness', 'float' );
export const alphaTest = new PropertyNode( 'AlphaTest', 'float' );
export const specularColor = new PropertyNode( 'SpecularColor', 'color' );
export const diffuseColor = ShaderNodeObject( new PropertyNode( 'DiffuseColor', 'vec4' ) );
export const roughness = ShaderNodeObject( new PropertyNode( 'Roughness', 'float' ) );
export const metalness = ShaderNodeObject( new PropertyNode( 'Metalness', 'float' ) );
export const alphaTest = ShaderNodeObject( new PropertyNode( 'AlphaTest', 'float' ) );
export const specularColor = ShaderNodeObject( new PropertyNode( 'SpecularColor', 'color' ) );
export const abs = ShaderNodeProxy( MathNode, 'abs' );
export const acos = ShaderNodeProxy( MathNode, 'acos' );
......
......@@ -50,6 +50,30 @@ class Node {
}
analyze( builder ) {
const hash = this.getHash( builder );
const sharedNode = builder.getNodeFromHash( hash );
if ( sharedNode !== undefined && this !== sharedNode ) {
return sharedNode.analyze( builder );
}
const nodeData = builder.getDataFromNode( this );
nodeData.dependenciesCount = nodeData.dependenciesCount === undefined ? 1 : nodeData.dependenciesCount + 1;
const nodeKeys = getNodesKeys( this );
for ( const property of nodeKeys ) {
this[ property ].analyze( builder );
}
}
build( builder, output = null ) {
const hash = this.getHash( builder );
......@@ -64,6 +88,7 @@ class Node {
builder.addNode( this );
builder.addStack( this );
const nodeData = builder.getDataFromNode( this );
const isGenerateOnce = this.generate.length === 1;
let snippet = null;
......@@ -71,7 +96,6 @@ class Node {
if ( isGenerateOnce ) {
const type = this.getNodeType( builder );
const nodeData = builder.getDataFromNode( this );
snippet = nodeData.snippet;
......
......@@ -58,7 +58,8 @@ class NodeBuilder {
console.warn( 'Recursive node: ', node );
}
*/
*/
this.stack.push( node );
}
......@@ -449,25 +450,9 @@ class NodeBuilder {
}
getAttributes( shaderStage ) {
let snippet = '';
if ( shaderStage === 'vertex' ) {
const attributes = this.attributes;
for ( let index = 0; index < attributes.length; index ++ ) {
const attribute = attributes[ index ];
snippet += `layout(location = ${index}) in ${attribute.type} ${attribute.name}; `;
getAttributes( /*shaderStage*/ ) {
}
}
return snippet;
console.warn( 'Abstract function.' );
}
......@@ -543,12 +528,32 @@ class NodeBuilder {
build() {
// stage 1: analyze nodes to possible optimization and validation
for ( const shaderStage of shaderStages ) {
this.setShaderStage( shaderStage );
const flowNodes = this.flowNodes[ shaderStage ];
for ( const node of flowNodes ) {
node.analyze( this );
}
}
// stage 2: pre-build vertex code used in fragment shader
if ( this.context.vertex && this.context.vertex.isNode ) {
this.flowNodeFromShaderStage( 'vertex', this.context.vertex );
}
// stage 3: generate shader
for ( const shaderStage of shaderStages ) {
this.setShaderStage( shaderStage );
......@@ -565,6 +570,8 @@ class NodeBuilder {
this.setShaderStage( null );
// stage 4: build code for a specific output
this.buildCode();
return this;
......
......@@ -11,10 +11,9 @@ class TempNode extends Node {
build( builder, output ) {
const type = builder.getVectorType( this.getNodeType( builder, output ) );
const nodeData = builder.getDataFromNode( this );
if ( builder.context.temp !== false && type !== 'void ' && output !== 'void' ) {
const nodeData = builder.getDataFromNode( this );
if ( builder.context.temp !== false && type !== 'void ' && output !== 'void' && nodeData.dependenciesCount > 1 ) {
if ( nodeData.snippet === undefined ) {
......
......@@ -107,7 +107,7 @@ export const RE_Direct_Physical = new ShaderNode( ( inputs ) => {
irradiance = mul( irradiance, PI ); // punctual light
addTo( directDiffuse, mul( irradiance, BRDF_Lambert( { diffuseColor } ) ) );
addTo( directDiffuse, mul( irradiance, BRDF_Lambert( { diffuseColor: diffuseColor.rgb } ) ) );
addTo( directSpecular, mul( irradiance, BRDF_GGX( { lightDirection, f0: specularColor, f90: 1, roughness } ) ) );
......
......@@ -231,7 +231,7 @@ class MathNode extends TempNode {
}
return `${ builder.getMethod( method ) }( ${params.join( ', ' )} )`;
return builder.format( `${ builder.getMethod( method ) }( ${params.join( ', ' )} )`, type, output );
}
......
import NodeBuilder from '../../nodes/core/NodeBuilder.js';
import NodeBuilder, { shaderStages } from '../../nodes/core/NodeBuilder.js';
import SlotNode from './SlotNode.js';
import GLSLNodeParser from '../../nodes/parsers/GLSLNodeParser.js';
import WebGLPhysicalContextNode from './WebGLPhysicalContextNode.js';
import { ShaderChunk, ShaderLib, UniformsUtils, UniformsLib,
LinearEncoding, RGBAFormat, UnsignedByteType, sRGBEncoding } from 'three';
const shaderStages = [ 'vertex', 'fragment' ];
LinearEncoding, RGBAFormat, UnsignedByteType, sRGBEncoding } from 'three';
const nodeShaderLib = {
LineBasicNodeMaterial: ShaderLib.basic,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册