123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import TempNode from '../core/TempNode.js';
- import { add } from '../math/OperatorNode.js';
- import { modelNormalMatrix } from '../accessors/ModelNode.js';
- import { normalView } from '../accessors/NormalNode.js';
- import { positionView } from '../accessors/PositionNode.js';
- import { TBNViewMatrix } from '../accessors/AccessorsUtils.js';
- import { uv } from '../accessors/UVNode.js';
- import { faceDirection } from './FrontFacingNode.js';
- import { addNodeClass } from '../core/Node.js';
- import { addNodeElement, tslFn, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
- import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from 'three';
- // Normal Mapping Without Precomputed Tangents
- // http://www.thetenthplanet.de/archives/1180
- const perturbNormal2Arb = tslFn( ( inputs ) => {
- const { eye_pos, surf_norm, mapN, uv } = inputs;
- const q0 = eye_pos.dFdx();
- const q1 = eye_pos.dFdy();
- const st0 = uv.dFdx();
- const st1 = uv.dFdy();
- const N = surf_norm; // normalized
- const q1perp = q1.cross( N );
- const q0perp = N.cross( q0 );
- const T = q1perp.mul( st0.x ).add( q0perp.mul( st1.x ) );
- const B = q1perp.mul( st0.y ).add( q0perp.mul( st1.y ) );
- const det = T.dot( T ).max( B.dot( B ) );
- const scale = faceDirection.mul( det.inverseSqrt() );
- return add( T.mul( mapN.x, scale ), B.mul( mapN.y, scale ), N.mul( mapN.z ) ).normalize();
- } );
- class NormalMapNode extends TempNode {
- constructor( node, scaleNode = null ) {
- super( 'vec3' );
- this.node = node;
- this.scaleNode = scaleNode;
- this.normalMapType = TangentSpaceNormalMap;
- }
- setup( builder ) {
- const { normalMapType, scaleNode } = this;
- let normalMap = this.node.mul( 2.0 ).sub( 1.0 );
- if ( scaleNode !== null ) {
- normalMap = vec3( normalMap.xy.mul( scaleNode ), normalMap.z );
- }
- let outputNode = null;
- if ( normalMapType === ObjectSpaceNormalMap ) {
- outputNode = modelNormalMatrix.mul( normalMap ).normalize();
- } else if ( normalMapType === TangentSpaceNormalMap ) {
- const tangent = builder.hasGeometryAttribute( 'tangent' );
- if ( tangent === true ) {
- outputNode = TBNViewMatrix.mul( normalMap ).normalize();
- } else {
- outputNode = perturbNormal2Arb( {
- eye_pos: positionView,
- surf_norm: normalView,
- mapN: normalMap,
- uv: uv()
- } );
- }
- }
- return outputNode;
- }
- }
- export default NormalMapNode;
- export const normalMap = nodeProxy( NormalMapNode );
- addNodeElement( 'normalMap', normalMap );
- addNodeClass( 'NormalMapNode', NormalMapNode );
|