123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- import PositionNode from '../accessors/PositionNode.js';
- import NormalNode from '../accessors/NormalNode.js';
- import UVNode from '../accessors/UVNode.js';
- import MathNode from '../math/MathNode.js';
- import OperatorNode from '../math/OperatorNode.js';
- import FloatNode from '../inputs/FloatNode.js';
- import TempNode from '../core/TempNode.js';
- import FunctionNode from '../core/FunctionNode.js';
- import ModelNode from '../accessors/ModelNode.js';
- import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from 'three';
- // Normal Mapping Without Precomputed Tangents
- // http://www.thetenthplanet.de/archives/1180
- export const perturbNormal2Arb = new FunctionNode( `
- vec3 ( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection, const in vec2 uv ) {
- // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
- vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );
- vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );
- vec2 st0 = dFdx( uv.st );
- vec2 st1 = dFdy( uv.st );
- vec3 N = surf_norm; // normalized
- vec3 q1perp = cross( q1, N );
- vec3 q0perp = cross( N, q0 );
- vec3 T = q1perp * st0.x + q0perp * st1.x;
- vec3 B = q1perp * st0.y + q0perp * st1.y;
- float det = max( dot( T, T ), dot( B, B ) );
- float scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );
- return normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );
- }` );
- class NormalMapNode extends TempNode {
- constructor( value ) {
- super( 'vec3' );
- this.value = value;
- this.normalMapType = TangentSpaceNormalMap;
- }
- generate( builder, output ) {
- const type = this.getType( builder );
- const normalMapType = this.normalMapType;
- const nodeData = builder.getDataFromNode( this );
- const normalOP = new OperatorNode( '*', this.value, new FloatNode( 2.0 ).setConst( true ) );
- const normalMap = new OperatorNode( '-', normalOP, new FloatNode( 1.0 ).setConst( true ) );
- if ( normalMapType === ObjectSpaceNormalMap ) {
- const vertexNormalNode = new OperatorNode( '*', new ModelNode( ModelNode.NORMAL_MATRIX ), normalMap );
- const normal = new MathNode( MathNode.NORMALIZE, vertexNormalNode );
- return normal.build( builder, output );
- } else if ( normalMapType === TangentSpaceNormalMap ) {
- let perturbNormal2ArbCall = nodeData.perturbNormal2ArbCall;
- if (perturbNormal2ArbCall === undefined) {
- perturbNormal2ArbCall = perturbNormal2Arb.call( {
- eye_pos: new PositionNode( PositionNode.VIEW ),
- surf_norm: new NormalNode( NormalNode.VIEW ),
- mapN: normalMap,
- faceDirection: new FloatNode( 1.0 ).setConst( true ),
- uv: new UVNode()
- } );
- nodeData.perturbNormal2ArbCall = perturbNormal2ArbCall;
- }
- const snippet = perturbNormal2ArbCall.build( builder, output );
-
- return builder.format( snippet, type, output );
-
- }
- }
- }
- export default NormalMapNode;
|