Skip to content

Commit

Permalink
Nodes: Triplanar Texture Mapping (#24714)
Browse files Browse the repository at this point in the history
* Added TriplanarTexturesNode

* Added triplanarTexture() in webgpu_materials example
  • Loading branch information
sunag committed Sep 30, 2022
1 parent d081c5a commit 430e610
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 1 deletion.
3 changes: 3 additions & 0 deletions examples/jsm/nodes/Nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ import RotateUVNode from './utils/RotateUVNode.js';
import SplitNode from './utils/SplitNode.js';
import SpriteSheetUVNode from './utils/SpriteSheetUVNode.js';
import TimerNode from './utils/TimerNode.js';
import TriplanarTexturesNode from './utils/TriplanarTexturesNode.js';

// loaders
import NodeLoader from './loaders/NodeLoader.js';
Expand Down Expand Up @@ -211,6 +212,7 @@ const nodeLib = {
SplitNode,
SpriteSheetUVNode,
TimerNode,
TriplanarTexturesNode,

// procedural
CheckerNode,
Expand Down Expand Up @@ -327,6 +329,7 @@ export {
SplitNode,
SpriteSheetUVNode,
TimerNode,
TriplanarTexturesNode,

// procedural
CheckerNode,
Expand Down
4 changes: 4 additions & 0 deletions examples/jsm/nodes/shadernode/ShaderNodeElements.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import RemapNode from '../utils/RemapNode.js';
import RotateUVNode from '../utils/RotateUVNode.js';
import SpriteSheetUVNode from '../utils/SpriteSheetUVNode.js';
import TimerNode from '../utils/TimerNode.js';
import TriplanarTexturesNode from '../utils/TriplanarTexturesNode.js';

// geometry
import RangeNode from '../geometry/RangeNode.js';
Expand Down Expand Up @@ -117,6 +118,9 @@ export const timerGlobal = ( timeScale, value = 0 ) => nodeObject( new TimerNode
export const timerDelta = ( timeScale, value = 0 ) => nodeObject( new TimerNode( TimerNode.DELTA, timeScale, value ) );
export const frameId = nodeImmutable( TimerNode, TimerNode.FRAME );

export const triplanarTextures = nodeProxy( TriplanarTexturesNode );
export const triplanarTexture = ( texture, ...params ) => triplanarTextures( texture, texture, texture, ...params );

// geometry

export const range = ( min, max ) => nodeObject( new RangeNode( min, max ) );
Expand Down
51 changes: 51 additions & 0 deletions examples/jsm/nodes/utils/TriplanarTexturesNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Node from '../core/Node.js';
import { float, vec3, add, mul, div, dot, normalize, abs, texture, positionWorld, normalWorld } from '../shadernode/ShaderNodeBaseElements.js';

class TriplanarTexturesNode extends Node {

constructor( textureXNode, textureYNode = null, textureZNode = null, scaleNode = float( 1 ), positionNode = positionWorld, normalNode = normalWorld ) {

super( 'vec4' );

this.textureXNode = textureXNode;
this.textureYNode = textureYNode;
this.textureZNode = textureZNode;

this.scaleNode = scaleNode;

this.positionNode = positionNode;
this.normalNode = normalNode;

}

construct() {

const { textureXNode, textureYNode, textureZNode, scaleNode, positionNode, normalNode } = this;

// Ref: https://github.com/keijiro/StandardTriplanar

// Blending factor of triplanar mapping
let bf = normalize( abs( normalNode ) );
bf = div( bf, dot( bf, vec3( 1.0 ) ) );

// Triplanar mapping
const tx = mul( positionNode.yz, scaleNode );
const ty = mul( positionNode.zx, scaleNode );
const tz = mul( positionNode.xy, scaleNode );

// Base color
const textureX = textureXNode.value;
const textureY = textureYNode !== null ? textureYNode.value : textureX;
const textureZ = textureZNode !== null ? textureZNode.value : textureX;

const cx = mul( texture( textureX, tx ), bf.x );
const cy = mul( texture( textureY, ty ), bf.y );
const cz = mul( texture( textureZ, tz ), bf.z );

return add( cx, cy, cz );

}

}

export default TriplanarTexturesNode;
7 changes: 6 additions & 1 deletion examples/webgpu_materials.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js';

import { ShaderNode, vec3, dot } from 'three/nodes';
import { ShaderNode, vec3, dot, triplanarTexture } from 'three/nodes';

import Stats from 'three/addons/libs/stats.module.js';

Expand Down Expand Up @@ -177,6 +177,11 @@
material.colorNode = getWGSLTextureSample.call( { tex: textureNode, tex_sampler: textureNode, uv: new Nodes.UVNode() } );
materials.push( material );

// Triplanar Texture Mapping
material = new Nodes.MeshBasicNodeMaterial();
material.colorNode = triplanarTexture( new Nodes.TextureNode( texture ) );
materials.push( material );

//
// Geometry
//
Expand Down

0 comments on commit 430e610

Please sign in to comment.