forked from mrdoob/three.js
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgetParallaxCorrectNormal.js
37 lines (32 loc) · 1.69 KB
/
getParallaxCorrectNormal.js
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
import { positionWorld } from '../../accessors/Position.js';
import { float, Fn, min, normalize, sub, vec3 } from '../../tsl/TSLBase.js';
/**
* This computes a parallax corrected normal which is used for box-projected cube mapping (BPCEM).
*
* Reference: {@link https://devlog-martinsh.blogspot.com/2011/09/box-projected-cube-environment-mapping.html}
*
* ```js
* const uvNode = getParallaxCorrectNormal( reflectVector, vec3( 200, 100, 100 ), vec3( 0, - 50, 0 ) );
* material.envNode = pmremTexture( renderTarget.texture, uvNode );
* ```
*
* @tsl
* @function
* @param {Node<vec3>} normal - The normal to correct.
* @param {Node<vec3>} cubeSize - The cube size should reflect the size of the environment (BPCEM is usually applied in closed environments like rooms).
* @param {Node<vec3>} cubePos - The cube position.
* @return {Node<vec3>} The parallax corrected normal.
*/
const getParallaxCorrectNormal = /*@__PURE__*/ Fn( ( [ normal, cubeSize, cubePos ] ) => {
const nDir = normalize( normal ).toVar();
const rbmax = sub( float( 0.5 ).mul( cubeSize.sub( cubePos ) ), positionWorld ).div( nDir ).toVar();
const rbmin = sub( float( - 0.5 ).mul( cubeSize.sub( cubePos ) ), positionWorld ).div( nDir ).toVar();
const rbminmax = vec3().toVar();
rbminmax.x = nDir.x.greaterThan( float( 0 ) ).select( rbmax.x, rbmin.x );
rbminmax.y = nDir.y.greaterThan( float( 0 ) ).select( rbmax.y, rbmin.y );
rbminmax.z = nDir.z.greaterThan( float( 0 ) ).select( rbmax.z, rbmin.z );
const correction = min( min( rbminmax.x, rbminmax.y ), rbminmax.z ).toVar();
const boxIntersection = positionWorld.add( nDir.mul( correction ) ).toVar();
return boxIntersection.sub( cubePos );
} );
export default getParallaxCorrectNormal;