浏览代码

ShaderNode: Rework ConvertType (#26025)

* Rework ConvertType

* Fix

* Fix both bugs remaining

* Fix DeepScan issue
Levi Pesin 2 年之前
父节点
当前提交
6c94900923

+ 4 - 0
examples/jsm/nodes/core/NodeBuilder.js

@@ -282,6 +282,10 @@ class NodeBuilder {
 
 			return `${ this.getType( type ) }( ${ getConst( value.x ) }, ${ getConst( value.y ) }, ${ getConst( value.z ) }, ${ getConst( value.w ) } )`;
 
+		} else if ( typeLength > 4 && value && ( value.isMatrix3 || value.isMatrix4 ) ) {
+
+			return `${ this.getType( type ) }( ${ value.elements.map( getConst ).join( ', ' ) } )`;
+
 		} else if ( typeLength > 4 ) {
 
 			return `${ this.getType( type ) }()`;

+ 6 - 0
examples/jsm/nodes/core/NodeUtils.js

@@ -137,6 +137,12 @@ export function getValueFromType( type, ...params ) {
 
 	const last4 = type ? type.slice( - 4 ) : undefined;
 
+	if ( ( last4 === 'vec2' || last4 === 'vec3' || last4 === 'vec4' ) && params.length === 1 ) { // ensure same behaviour as in NodeBuilder.format()
+
+		params = last4 === 'vec2' ? [ params[ 0 ], params[ 0 ] ] : [ params[ 0 ], params[ 0 ], params[ 0 ] ];
+
+	}
+
 	if ( type === 'color' ) {
 
 		return new Color( ...params );

+ 7 - 7
examples/jsm/nodes/display/ToneMappingNode.js

@@ -1,6 +1,6 @@
 import TempNode from '../core/TempNode.js';
 import { addNodeClass } from '../core/Node.js';
-import { ShaderNode, nodeObject, float, vec3, mat3 } from '../shadernode/ShaderNode.js';
+import { ShaderNode, nodeObject, float, mat3 } from '../shadernode/ShaderNode.js';
 
 import { NoToneMapping, LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping } from 'three';
 
@@ -49,16 +49,16 @@ const ACESFilmicToneMappingNode = new ShaderNode( ( { color, exposure } ) => {
 
 	// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
 	const ACESInputMat = mat3(
-		vec3( 0.59719, 0.07600, 0.02840 ), // transposed from source
-		vec3( 0.35458, 0.90834, 0.13383 ),
-		vec3( 0.04823, 0.01566, 0.83777 )
+		0.59719, 0.35458, 0.04823,
+		0.07600, 0.90834, 0.01566,
+		0.02840, 0.13383, 0.83777
 	);
 
 	// ODT_SAT => XYZ => D60_2_D65 => sRGB
 	const ACESOutputMat = mat3(
-		vec3( 1.60475, - 0.10208, - 0.00327 ), // transposed from source
-		vec3( - 0.53108, 1.10813, - 0.07276 ),
-		vec3( - 0.07367, - 0.00605, 1.07602 )
+		1.60475, - 0.53108, - 0.07367,
+		- 0.10208, 1.10813, - 0.00605,
+		- 0.00327, - 0.07276, 1.07602
 	);
 
 	color = color.mul( exposure ).div( 0.6 );

+ 27 - 24
examples/jsm/nodes/shadernode/ShaderNode.js

@@ -97,18 +97,14 @@ const ShaderNodeObject = function ( obj, altType = null ) {
 
 		return nodeObject;
 
-	} else if ( ( altType === null ) && ( ( type === 'float' ) || ( type === 'boolean' ) ) ) {
+	} else if ( ( altType === null && ( type === 'float' || type === 'boolean' ) ) || ( type && type !== 'shader' && type !== 'string' ) ) {
 
-		return nodeObject( getAutoTypedConstNode( obj ) );
+		return nodeObject( getConstNode( obj, altType ) );
 
 	} else if ( type === 'shader' ) {
 
 		return shader( obj );
 
-	} else if ( type && type !== 'string' ) {
-
-		return nodeObject( new ConstNode( obj, altType ) );
-
 	}
 
 	return obj;
@@ -241,7 +237,7 @@ const cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap
 
 const constNodesCacheMap = new Map( [ ...boolsCacheMap, ...floatsCacheMap ] );
 
-const getAutoTypedConstNode = ( value ) => {
+const getConstNode = ( value, type ) => {
 
 	if ( constNodesCacheMap.has( value ) ) {
 
@@ -253,46 +249,53 @@ const getAutoTypedConstNode = ( value ) => {
 
 	} else {
 
-		return new ConstNode( value );
+		return new ConstNode( value, type );
 
 	}
 
 };
 
-const ConvertType = function ( type, cacheMap = null ) {
+const safeGetNodeType = ( node ) => {
 
-	return ( ...params ) => {
+	try {
 
-		if ( params.length === 0 ) {
+		return node.getNodeType();
 
-			return nodeObject( new ConstNode( getValueFromType( type ), type ) );
+	} catch {
 
-		} else {
+		return undefined;
 
-			if ( type === 'color' && params[ 0 ].isNode !== true ) {
+	}
 
-				params = [ getValueFromType( type, ...params ) ];
+};
 
-			}
+const ConvertType = function ( type, cacheMap = null ) {
 
-			if ( params.length === 1 && cacheMap !== null && cacheMap.has( params[ 0 ] ) ) {
+	return ( ...params ) => {
 
-				return cacheMap.get( params[ 0 ] );
+		if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => typeof param !== 'object' ) ) ) {
 
-			}
+			params = [ getValueFromType( type, ...params ) ];
 
-			const nodes = params.map( getAutoTypedConstNode );
+		}
 
-			if ( nodes.length === 1 ) {
+		if ( params.length === 1 && cacheMap !== null && cacheMap.has( params[ 0 ] ) ) {
 
-				return nodeObject( nodes[ 0 ].nodeType === type || getValueType( nodes[ 0 ].value ) === type ? nodes[ 0 ] : new ConvertNode( nodes[ 0 ], type ) );
+			return nodeObject( cacheMap.get( params[ 0 ] ) );
 
-			}
+		}
+
+		if ( params.length === 1 ) {
 
-			return nodeObject( new JoinNode( nodes, type ) );
+			const node = getConstNode( params[ 0 ], type );
+			if ( safeGetNodeType( node ) === type ) return nodeObject( node );
+			return nodeObject( new ConvertNode( node, type ) );
 
 		}
 
+		const nodes = params.map( param => getConstNode( param ) );
+		return nodeObject( new JoinNode( nodes, type ) );
+
 	};
 
 };