-
-
Notifications
You must be signed in to change notification settings - Fork 36.4k
Expand file tree
/
Copy pathNormalMapNode.js
More file actions
153 lines (103 loc) · 3.36 KB
/
NormalMapNode.js
File metadata and controls
153 lines (103 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import TempNode from '../core/TempNode.js';
import { normalView, transformNormalToView } from '../accessors/Normal.js';
import { TBNViewMatrix } from '../accessors/AccessorsUtils.js';
import { nodeProxy, vec3 } from '../tsl/TSLBase.js';
import { TangentSpaceNormalMap, ObjectSpaceNormalMap, NoNormalPacking, NormalRGPacking, NormalGAPacking } from '../../constants.js';
import { directionToFaceDirection } from './FrontFacingNode.js';
import { unpackNormal } from '../utils/Packing.js';
import { error } from '../../utils.js';
/**
* 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;
/**
* Controls how to unpack the sampled normal map values.
*
* @type {string}
* @default NoNormalPacking
*/
this.unpackNormalMode = NoNormalPacking;
}
setup( builder ) {
const { normalMapType, scaleNode, unpackNormalMode } = this;
let normalMap = this.node.mul( 2.0 ).sub( 1.0 );
if ( normalMapType === TangentSpaceNormalMap ) {
if ( unpackNormalMode === NormalRGPacking ) {
normalMap = unpackNormal( normalMap.xy );
} else if ( unpackNormalMode === NormalGAPacking ) {
normalMap = unpackNormal( normalMap.yw );
} else if ( unpackNormalMode !== NoNormalPacking ) {
console.error( `THREE.NodeMaterial: Unexpected unpack normal mode: ${ unpackNormalMode }` );
}
} else {
if ( unpackNormalMode !== NoNormalPacking ) {
console.error( `THREE.NodeMaterial: Normal map type '${ normalMapType }' is not compatible with unpack normal mode '${ unpackNormalMode }'` );
}
}
if ( scaleNode !== null ) {
let scale = scaleNode;
if ( builder.isFlatShading() === true ) {
scale = directionToFaceDirection( scale );
}
normalMap = vec3( normalMap.xy.mul( scale ), normalMap.z );
}
let output = null;
if ( normalMapType === ObjectSpaceNormalMap ) {
output = transformNormalToView( normalMap );
} else if ( normalMapType === TangentSpaceNormalMap ) {
output = TBNViewMatrix.mul( normalMap ).normalize();
} else {
error( `NodeMaterial: Unsupported normal map type: ${ normalMapType }` );
output = normalView; // Fallback to default normal view
}
return output;
}
}
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 );