Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TSL: TangentNode and BitangentNode - Improve tree shaking using TSL #28410

Merged
merged 3 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/jsm/nodes/Nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export * from './shadernode/ShaderNode.js';
// accessors
export { TBNViewMatrix, parallaxDirection, parallaxUV, transformedBentNormalView } from './accessors/AccessorsUtils.js';
export { default as UniformsNode, uniforms } from './accessors/UniformsNode.js';
export { default as BitangentNode, bitangentGeometry, bitangentLocal, bitangentView, bitangentWorld, transformedBitangentView, transformedBitangentWorld } from './accessors/BitangentNode.js';
export * from './accessors/BitangentNode.js';
export { default as BufferAttributeNode, bufferAttribute, dynamicBufferAttribute, instancedBufferAttribute, instancedDynamicBufferAttribute } from './accessors/BufferAttributeNode.js';
export { default as BufferNode, buffer } from './accessors/BufferNode.js';
export { default as CameraNode, cameraProjectionMatrix, cameraProjectionMatrixInverse, cameraViewMatrix, cameraNormalMatrix, cameraWorldMatrix, cameraPosition, cameraNear, cameraFar, cameraLogDepth } from './accessors/CameraNode.js';
Expand All @@ -101,7 +101,7 @@ export { default as ReflectVectorNode, reflectVector } from './accessors/Reflect
export { default as SkinningNode, skinning } from './accessors/SkinningNode.js';
export { default as SceneNode, backgroundBlurriness, backgroundIntensity } from './accessors/SceneNode.js';
export { default as StorageBufferNode, storage, storageObject } from './accessors/StorageBufferNode.js';
export { default as TangentNode, tangentGeometry, tangentLocal, tangentView, tangentWorld, transformedTangentView, transformedTangentWorld } from './accessors/TangentNode.js';
export * from './accessors/TangentNode.js';
export { default as TextureNode, texture, textureLoad, /*textureLevel,*/ sampler } from './accessors/TextureNode.js';
export { default as TextureStoreNode, textureStore } from './accessors/TextureStoreNode.js';
export { default as UVNode, uv } from './accessors/UVNode.js';
Expand Down
90 changes: 7 additions & 83 deletions examples/jsm/nodes/accessors/BitangentNode.js
Original file line number Diff line number Diff line change
@@ -1,89 +1,13 @@
import Node, { addNodeClass } from '../core/Node.js';
import { varying } from '../core/VaryingNode.js';
import { normalize } from '../math/MathNode.js';
import { cameraViewMatrix } from './CameraNode.js';
import { normalGeometry, normalLocal, normalView, normalWorld, transformedNormalView } from './NormalNode.js';
import { tangentGeometry, tangentLocal, tangentView, tangentWorld, transformedTangentView } from './TangentNode.js';
import { nodeImmutable } from '../shadernode/ShaderNode.js';

class BitangentNode extends Node {
const getBitangent = ( crossNormalTangent ) => crossNormalTangent.mul( tangentGeometry.w ).xyz;

constructor( scope = BitangentNode.LOCAL ) {

super( 'vec3' );

this.scope = scope;

}

getHash( /*builder*/ ) {

return `bitangent-${this.scope}`;

}

generate( builder ) {

const scope = this.scope;

let crossNormalTangent;

if ( scope === BitangentNode.GEOMETRY ) {

crossNormalTangent = normalGeometry.cross( tangentGeometry );

} else if ( scope === BitangentNode.LOCAL ) {

crossNormalTangent = normalLocal.cross( tangentLocal );

} else if ( scope === BitangentNode.VIEW ) {

crossNormalTangent = normalView.cross( tangentView );

} else if ( scope === BitangentNode.WORLD ) {

crossNormalTangent = normalWorld.cross( tangentWorld );

}

const vertexNode = crossNormalTangent.mul( tangentGeometry.w ).xyz;

const outputNode = normalize( varying( vertexNode ) );

return outputNode.build( builder, this.getNodeType( builder ) );

}

serialize( data ) {

super.serialize( data );

data.scope = this.scope;

}

deserialize( data ) {

super.deserialize( data );

this.scope = data.scope;

}

}

BitangentNode.GEOMETRY = 'geometry';
BitangentNode.LOCAL = 'local';
BitangentNode.VIEW = 'view';
BitangentNode.WORLD = 'world';

export default BitangentNode;

export const bitangentGeometry = nodeImmutable( BitangentNode, BitangentNode.GEOMETRY );
export const bitangentLocal = nodeImmutable( BitangentNode, BitangentNode.LOCAL );
export const bitangentView = nodeImmutable( BitangentNode, BitangentNode.VIEW );
export const bitangentWorld = nodeImmutable( BitangentNode, BitangentNode.WORLD );
export const transformedBitangentView = normalize( transformedNormalView.cross( transformedTangentView ).mul( tangentGeometry.w ) );
export const transformedBitangentWorld = normalize( transformedBitangentView.transformDirection( cameraViewMatrix ) );

addNodeClass( 'BitangentNode', BitangentNode );
export const bitangentGeometry = varying( getBitangent( normalGeometry.cross( tangentGeometry ) ) ).normalize();
export const bitangentLocal = varying( getBitangent( normalLocal.cross( tangentLocal ) ) ).normalize();
export const bitangentView = varying( getBitangent( normalView.cross( tangentView ) ) ).normalize();
export const bitangentWorld = varying( getBitangent( normalWorld.cross( tangentWorld ) ) ).normalize();
export const transformedBitangentView = getBitangent( transformedNormalView.cross( transformedTangentView ) ).normalize();
export const transformedBitangentWorld = transformedBitangentView.transformDirection( cameraViewMatrix ).normalize();
108 changes: 11 additions & 97 deletions examples/jsm/nodes/accessors/TangentNode.js
Original file line number Diff line number Diff line change
@@ -1,109 +1,23 @@
import Node, { addNodeClass } from '../core/Node.js';
import { attribute } from '../core/AttributeNode.js';
import { temp } from '../core/VarNode.js';
import { varying } from '../core/VaryingNode.js';
import { normalize } from '../math/MathNode.js';
import { cameraViewMatrix } from './CameraNode.js';
import { modelViewMatrix } from './ModelNode.js';
import { nodeImmutable, vec4 } from '../shadernode/ShaderNode.js';
import { tslFn, vec4 } from '../shadernode/ShaderNode.js';

class TangentNode extends Node {
export const tangentGeometry = /*#__PURE__*/ tslFn( ( stack, builder ) => {

constructor( scope = TangentNode.LOCAL ) {
if ( builder.geometry.hasAttribute( 'tangent' ) === false ) {

super();

this.scope = scope;

}

getHash( /*builder*/ ) {

return `tangent-${this.scope}`;

}

getNodeType() {

const scope = this.scope;

if ( scope === TangentNode.GEOMETRY ) {

return 'vec4';

}

return 'vec3';

}


generate( builder ) {

const scope = this.scope;

let outputNode = null;

if ( scope === TangentNode.GEOMETRY ) {

outputNode = attribute( 'tangent', 'vec4' );

if ( builder.geometry.hasAttribute( 'tangent' ) === false ) {

builder.geometry.computeTangents();

}

} else if ( scope === TangentNode.LOCAL ) {

outputNode = varying( tangentGeometry.xyz );

} else if ( scope === TangentNode.VIEW ) {

const vertexNode = modelViewMatrix.mul( vec4( tangentLocal, 0 ) ).xyz;
outputNode = normalize( varying( vertexNode ) );

} else if ( scope === TangentNode.WORLD ) {

const vertexNode = tangentView.transformDirection( cameraViewMatrix );
outputNode = normalize( varying( vertexNode ) );

}

return outputNode.build( builder, this.getNodeType( builder ) );

}

serialize( data ) {

super.serialize( data );

data.scope = this.scope;
builder.geometry.computeTangents();

}

deserialize( data ) {

super.deserialize( data );

this.scope = data.scope;

}

}

TangentNode.GEOMETRY = 'geometry';
TangentNode.LOCAL = 'local';
TangentNode.VIEW = 'view';
TangentNode.WORLD = 'world';

export default TangentNode;
return attribute( 'tangent', 'vec4' );

export const tangentGeometry = nodeImmutable( TangentNode, TangentNode.GEOMETRY );
export const tangentLocal = nodeImmutable( TangentNode, TangentNode.LOCAL );
export const tangentView = nodeImmutable( TangentNode, TangentNode.VIEW );
export const tangentWorld = nodeImmutable( TangentNode, TangentNode.WORLD );
export const transformedTangentView = temp( tangentView, 'TransformedTangentView' );
export const transformedTangentWorld = normalize( transformedTangentView.transformDirection( cameraViewMatrix ) );
} )();

addNodeClass( 'TangentNode', TangentNode );
export const tangentLocal = /*#__PURE__*/ varying( tangentGeometry.xyz, 'tangentLocal' );
export const tangentView = /*#__PURE__*/ varying( modelViewMatrix.mul( vec4( tangentLocal, 0 ) ).xyz, 'tangentView' ).normalize();
export const tangentWorld = /*#__PURE__*/ varying( tangentView.transformDirection( cameraViewMatrix ), 'tangentWorld' ).normalize();
export const transformedTangentView = /*#__PURE__*/ tangentView.toVar( 'transformedTangentView' );
export const transformedTangentWorld = /*#__PURE__*/ transformedTangentView.transformDirection( cameraViewMatrix ).normalize();