three 基础库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

100 lines
2.4 KiB

import Node from '../core/Node.js';
import AttributeNode from '../core/AttributeNode.js';
import VaryNode from '../core/VaryNode.js';
import ModelNode from '../accessors/ModelNode.js';
import MathNode from '../math/MathNode.js';
import OperatorNode from '../math/OperatorNode.js';
import { transformDirection } from '../functions/MathFunctions.js';
class PositionNode extends Node {
static LOCAL = 'local';
static WORLD = 'world';
static VIEW = 'view';
static VIEW_DIRECTION = 'viewDirection';
constructor( scope = PositionNode.POSITION ) {
super( 'vec3' );
this.scope = scope;
}
generate( builder, output ) {
const type = this.getType( builder );
const nodeData = builder.getDataFromNode( this, builder.shaderStage );
const scope = this.scope;
let localPositionNode = nodeData.localPositionNode;
if ( localPositionNode === undefined ) {
localPositionNode = new AttributeNode( 'position', 'vec3' );
nodeData.localPositionNode = localPositionNode;
}
let outputNode = localPositionNode;
if ( scope === PositionNode.WORLD ) {
let worldPositionNode = nodeData.worldPositionNode;
if ( worldPositionNode === undefined ) {
const vertexPositionNode = transformDirection.call( { dir: localPositionNode, matrix: new ModelNode( ModelNode.WORLD_MATRIX ) } );
worldPositionNode = new VaryNode( vertexPositionNode );
nodeData.worldPositionNode = worldPositionNode;
}
outputNode = worldPositionNode;
} else if ( scope === PositionNode.VIEW ) {
let viewPositionNode = nodeData.viewPositionNode;
if ( viewPositionNode === undefined ) {
const vertexPositionNode = new OperatorNode( '*', new ModelNode( ModelNode.VIEW_MATRIX ), localPositionNode );
viewPositionNode = new VaryNode( vertexPositionNode );
nodeData.viewPositionNode = viewPositionNode;
}
outputNode = viewPositionNode;
} else if ( scope === PositionNode.VIEW_DIRECTION ) {
let viewDirPositionNode = nodeData.viewDirPositionNode;
if ( viewDirPositionNode === undefined ) {
const vertexPositionNode = new MathNode( MathNode.NEGATE, new PositionNode( PositionNode.VIEW ) );
viewDirPositionNode = new MathNode( MathNode.NORMALIZE, new VaryNode( vertexPositionNode ) );
nodeData.viewDirPositionNode = viewDirPositionNode;
}
outputNode = viewDirPositionNode;
}
const positionSnipped = outputNode.build( builder, type );
return builder.format( positionSnipped, type, output );
}
}
export default PositionNode;