diff --git a/examples/jsm/nodes/Nodes.js b/examples/jsm/nodes/Nodes.js index 509dad59938adc..0fb7472b3bb054 100644 --- a/examples/jsm/nodes/Nodes.js +++ b/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'; diff --git a/examples/jsm/nodes/accessors/ModelViewProjectionNode.js b/examples/jsm/nodes/accessors/ModelViewProjectionNode.js index 448eb414980688..23d597fd2d7ec9 100644 --- a/examples/jsm/nodes/accessors/ModelViewProjectionNode.js +++ b/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 ) { diff --git a/examples/jsm/nodes/shadernode/ShaderNode.js b/examples/jsm/nodes/shadernode/ShaderNode.js index 53c6becd343efc..7ee0cafbcd8ade 100644 --- a/examples/jsm/nodes/shadernode/ShaderNode.js +++ b/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 ) { diff --git a/examples/jsm/nodes/utils/SetNode.js b/examples/jsm/nodes/utils/SetNode.js new file mode 100644 index 00000000000000..2481f1b05e74ff --- /dev/null +++ b/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 ); diff --git a/examples/jsm/renderers/common/Background.js b/examples/jsm/renderers/common/Background.js index 629e63f4cbc65e..d56840b47b6480 100644 --- a/examples/jsm/renderers/common/Background.js +++ b/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;