63 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			63 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | import Node, { addNodeClass } from '../core/Node.js'; | ||
|  | import { add } from '../math/OperatorNode.js'; | ||
|  | import { normalLocal } from '../accessors/NormalNode.js'; | ||
|  | import { positionLocal } from '../accessors/PositionNode.js'; | ||
|  | import { texture } from '../accessors/TextureNode.js'; | ||
|  | import { addNodeElement, nodeProxy, float, vec3 } from '../shadernode/ShaderNode.js'; | ||
|  | 
 | ||
|  | class TriplanarTexturesNode extends Node { | ||
|  | 
 | ||
|  | 	constructor( textureXNode, textureYNode = null, textureZNode = null, scaleNode = float( 1 ), positionNode = positionLocal, normalNode = normalLocal ) { | ||
|  | 
 | ||
|  | 		super( 'vec4' ); | ||
|  | 
 | ||
|  | 		this.textureXNode = textureXNode; | ||
|  | 		this.textureYNode = textureYNode; | ||
|  | 		this.textureZNode = textureZNode; | ||
|  | 
 | ||
|  | 		this.scaleNode = scaleNode; | ||
|  | 
 | ||
|  | 		this.positionNode = positionNode; | ||
|  | 		this.normalNode = normalNode; | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	setup() { | ||
|  | 
 | ||
|  | 		const { textureXNode, textureYNode, textureZNode, scaleNode, positionNode, normalNode } = this; | ||
|  | 
 | ||
|  | 		// Ref: https://github.com/keijiro/StandardTriplanar
 | ||
|  | 
 | ||
|  | 		// Blending factor of triplanar mapping
 | ||
|  | 		let bf = normalNode.abs().normalize(); | ||
|  | 		bf = bf.div( bf.dot( vec3( 1.0 ) ) ); | ||
|  | 
 | ||
|  | 		// Triplanar mapping
 | ||
|  | 		const tx = positionNode.yz.mul( scaleNode ); | ||
|  | 		const ty = positionNode.zx.mul( scaleNode ); | ||
|  | 		const tz = positionNode.xy.mul( scaleNode ); | ||
|  | 
 | ||
|  | 		// Base color
 | ||
|  | 		const textureX = textureXNode.value; | ||
|  | 		const textureY = textureYNode !== null ? textureYNode.value : textureX; | ||
|  | 		const textureZ = textureZNode !== null ? textureZNode.value : textureX; | ||
|  | 
 | ||
|  | 		const cx = texture( textureX, tx ).mul( bf.x ); | ||
|  | 		const cy = texture( textureY, ty ).mul( bf.y ); | ||
|  | 		const cz = texture( textureZ, tz ).mul( bf.z ); | ||
|  | 
 | ||
|  | 		return add( cx, cy, cz ); | ||
|  | 
 | ||
|  | 	} | ||
|  | 
 | ||
|  | } | ||
|  | 
 | ||
|  | export default TriplanarTexturesNode; | ||
|  | 
 | ||
|  | export const triplanarTextures = nodeProxy( TriplanarTexturesNode ); | ||
|  | export const triplanarTexture = ( ...params ) => triplanarTextures( ...params ); | ||
|  | 
 | ||
|  | addNodeElement( 'triplanarTexture', triplanarTexture ); | ||
|  | 
 | ||
|  | addNodeClass( 'TriplanarTexturesNode', TriplanarTexturesNode ); |