90 lines
2.3 KiB
JavaScript
90 lines
2.3 KiB
JavaScript
|
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 {
|
||
|
|
||
|
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 );
|