Sfoglia il codice sorgente

TSL: SetNode (#26785)

* Add SetNode

* Use viewProj.setZ()

* cleanup
sunag 1 anno fa
parent
commit
45505ed0ac

+ 1 - 0
examples/jsm/nodes/Nodes.js

@@ -54,6 +54,7 @@ export { default as OscNode, oscSine, oscSquare, oscTriangle, oscSawtooth } from
 export { default as PackingNode, directionToColor, colorToDirection } from './utils/PackingNode.js';
 export { default as RemapNode, remap, remapClamp } from './utils/RemapNode.js';
 export { default as RotateUVNode, rotateUV } from './utils/RotateUVNode.js';
+export { default as SetNode } from './utils/SetNode.js';
 export { default as SpecularMIPLevelNode, specularMIPLevel } from './utils/SpecularMIPLevelNode.js';
 export { default as SplitNode } from './utils/SplitNode.js';
 export { default as SpriteSheetUVNode, spritesheetUV } from './utils/SpriteSheetUVNode.js';

+ 3 - 2
examples/jsm/nodes/accessors/ModelViewProjectionNode.js

@@ -1,10 +1,11 @@
-import Node, { addNodeClass } from '../core/Node.js';
+import { addNodeClass } from '../core/Node.js';
+import TempNode from '../core/TempNode.js';
 import { cameraProjectionMatrix } from './CameraNode.js';
 import { modelViewMatrix } from './ModelNode.js';
 import { positionLocal } from './PositionNode.js';
 import { nodeProxy } from '../shadernode/ShaderNode.js';
 
-class ModelViewProjectionNode extends Node {
+class ModelViewProjectionNode extends TempNode {
 
 	constructor( positionNode = positionLocal ) {
 

+ 22 - 7
examples/jsm/nodes/shadernode/ShaderNode.js

@@ -3,6 +3,7 @@ import ArrayElementNode from '../utils/ArrayElementNode.js';
 import ConvertNode from '../utils/ConvertNode.js';
 import JoinNode from '../utils/JoinNode.js';
 import SplitNode from '../utils/SplitNode.js';
+import SetNode from '../utils/SetNode.js';
 import ConstNode from '../core/ConstNode.js';
 import { getValueFromType, getValueType } from '../core/NodeUtils.js';
 
@@ -17,6 +18,8 @@ export function addNodeElement( name, nodeElement ) {
 
 }
 
+const parseSwizzle = ( props ) => props.replace( /r|s/g, 'x' ).replace( /g|t/g, 'y' ).replace( /b|p/g, 'z' ).replace( /a|q/g, 'w' );
+
 const shaderNodeHandler = {
 
 	construct( NodeClosure, params ) {
@@ -51,19 +54,31 @@ const shaderNodeHandler = {
 
 				// accessing properties ( swizzle )
 
-				prop = prop
-					.replace( /r|s/g, 'x' )
-					.replace( /g|t/g, 'y' )
-					.replace( /b|p/g, 'z' )
-					.replace( /a|q/g, 'w' );
+				prop = parseSwizzle( prop );
 
 				return nodeObject( new SplitNode( node, prop ) );
 
-			} else if ( prop === 'width' || prop === 'height' ) {
+			} else if ( /^set[XYZWRGBASTPQ]{1,4}$/.test( prop ) === true ) {
+
+				// set properties ( swizzle )
+
+				prop = parseSwizzle( prop.slice( 3 ).toLowerCase() );
+
+				// sort to xyzw sequence
+
+				prop = prop.split( '' ).sort().join( '' );
+
+				return ( value ) => nodeObject( new SetNode( node, prop, value ) );
+
+			} else if ( prop === 'width' || prop === 'height' || prop === 'depth' ) {
 
 				// accessing property
 
-				return nodeObject( new SplitNode( node, prop === 'width' ? 'x' : 'y' ) );
+				if ( prop === 'width' ) prop = 'x';
+				else if ( prop === 'height' ) prop = 'y';
+				else if ( prop === 'depth' ) prop = 'z';
+
+				return nodeObject( new SplitNode( node, prop ) );
 
 			} else if ( /^\d+$/.test( prop ) === true ) {
 

+ 62 - 0
examples/jsm/nodes/utils/SetNode.js

@@ -0,0 +1,62 @@
+import { addNodeClass } from '../core/Node.js';
+import TempNode from '../core/TempNode.js';
+import { vectorComponents } from '../core/constants.js';
+
+class SetNode extends TempNode {
+
+	constructor( sourceNode, components, targetNode ) {
+
+		super();
+
+		this.sourceNode = sourceNode;
+		this.components = components;
+		this.targetNode = targetNode;
+
+	}
+
+	getNodeType( builder ) {
+
+		return this.sourceNode.getNodeType( builder );
+
+	}
+
+	generate( builder ) {
+
+		const { sourceNode, components, targetNode } = this;
+
+		const sourceType = this.getNodeType( builder );
+		const targetType = builder.getTypeFromLength( components.length );
+
+		const targetSnippet = targetNode.build( builder, targetType );
+		const sourceSnippet = sourceNode.build( builder, sourceType );
+
+		const length = builder.getTypeLength( sourceType );
+		const snippetValues = [];
+
+		for ( let i = 0; i < length; i ++ ) {
+
+			const component = vectorComponents[ i ];
+
+			if ( component === components[ 0 ] ) {
+
+				snippetValues.push( targetSnippet );
+
+				i += components.length - 1;
+
+			} else {
+
+				snippetValues.push( sourceSnippet + '.' + component );
+
+			}
+
+		}
+
+		return `${ builder.getType( sourceType ) }( ${ snippetValues.join( ', ' ) } )`;
+
+	}
+
+}
+
+export default SetNode;
+
+addNodeClass( SetNode );

+ 2 - 2
examples/jsm/renderers/common/Background.js

@@ -1,6 +1,6 @@
 import DataMap from './DataMap.js';
 import { Color, Mesh, SphereGeometry, BackSide } from 'three';
-import { vec4, context, normalWorld, backgroundBlurriness, backgroundIntensity, NodeMaterial, modelViewProjection } from '../../nodes/Nodes.js';
+import { context, normalWorld, backgroundBlurriness, backgroundIntensity, NodeMaterial, modelViewProjection } from '../../nodes/Nodes.js';
 
 let _clearAlpha;
 const _clearColor = new Color();
@@ -60,7 +60,7 @@ class Background extends DataMap {
 				} ).mul( backgroundIntensity );
 
 				let viewProj = modelViewProjection();
-				viewProj = vec4( viewProj.x, viewProj.y, viewProj.w, viewProj.w );
+				viewProj = viewProj.setZ( viewProj.w );
 
 				const nodeMaterial = new NodeMaterial();
 				nodeMaterial.outputNode = this.backgroundMeshNode;