Buckets:
| import TempNode from '../core/TempNode.js'; | |
| import { add } from '../math/OperatorNode.js'; | |
| import { normalView, transformNormalToView } from '../accessors/Normal.js'; | |
| import { positionView } from '../accessors/Position.js'; | |
| import { TBNViewMatrix } from '../accessors/AccessorsUtils.js'; | |
| import { uv } from '../accessors/UV.js'; | |
| import { faceDirection } from './FrontFacingNode.js'; | |
| import { Fn, nodeProxy, vec3 } from '../tsl/TSLBase.js'; | |
| import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from '../../constants.js'; | |
| // Normal Mapping Without Precomputed Tangents | |
| // http://www.thetenthplanet.de/archives/1180 | |
| const perturbNormal2Arb = /*@__PURE__*/ Fn( ( 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(); | |
| } ); | |
| /** | |
| * This class can be used for applying normals maps to materials. | |
| * | |
| * ```js | |
| * material.normalNode = normalMap( texture( normalTex ) ); | |
| * ``` | |
| * | |
| * @augments TempNode | |
| */ | |
| class NormalMapNode extends TempNode { | |
| static get type() { | |
| return 'NormalMapNode'; | |
| } | |
| /** | |
| * Constructs a new normal map node. | |
| * | |
| * @param {Node<vec3>} node - Represents the normal map data. | |
| * @param {?Node<vec2>} [scaleNode=null] - Controls the intensity of the effect. | |
| */ | |
| constructor( node, scaleNode = null ) { | |
| super( 'vec3' ); | |
| /** | |
| * Represents the normal map data. | |
| * | |
| * @type {Node<vec3>} | |
| */ | |
| this.node = node; | |
| /** | |
| * Controls the intensity of the effect. | |
| * | |
| * @type {?Node<vec2>} | |
| * @default null | |
| */ | |
| this.scaleNode = scaleNode; | |
| /** | |
| * The normal map type. | |
| * | |
| * @type {(TangentSpaceNormalMap|ObjectSpaceNormalMap)} | |
| * @default TangentSpaceNormalMap | |
| */ | |
| 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 = transformNormalToView( normalMap ); | |
| } 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; | |
| /** | |
| * TSL function for creating a normal map node. | |
| * | |
| * @tsl | |
| * @function | |
| * @param {Node<vec3>} node - Represents the normal map data. | |
| * @param {?Node<vec2>} [scaleNode=null] - Controls the intensity of the effect. | |
| * @returns {NormalMapNode} | |
| */ | |
| export const normalMap = /*@__PURE__*/ nodeProxy( NormalMapNode ).setParameterLength( 1, 2 ); | |
Xet Storage Details
- Size:
- 3.34 kB
- Xet hash:
- dbacdcc869b95745d7ee3c7fede3d4f733630e6176f9dd125b3dd6f45a275705
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.