Spaces:
Running
Running
File size: 3,205 Bytes
6cd9596 |
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 |
/**
* @author sunag / http://www.sunag.com.br/
*/
import { TempNode } from '../core/TempNode.js';
import { Vector2Node } from '../inputs/Vector2Node.js';
import { FunctionNode } from '../core/FunctionNode.js';
import { UVNode } from '../accessors/UVNode.js';
import { NormalNode } from '../accessors/NormalNode.js';
import { PositionNode } from '../accessors/PositionNode.js';
function NormalMapNode( value, scale ) {
TempNode.call( this, 'v3' );
this.value = value;
this.scale = scale || new Vector2Node( 1, 1 );
}
NormalMapNode.Nodes = ( function () {
var perturbNormal2Arb = new FunctionNode( [
// Per-Pixel Tangent Space Normal Mapping
// http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
"vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, vec2 normalScale ) {",
// 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( mUv.st );",
" vec2 st1 = dFdy( mUv.st );",
" float scale = sign( st1.t * st0.s - st0.t * st1.s );", // we do not care about the magnitude
" vec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );",
" vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );",
" vec3 N = normalize( surf_norm );",
" mat3 tsn = mat3( S, T, N );",
" vec3 mapN = map * 2.0 - 1.0;",
" mapN.xy *= normalScale;",
" mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );",
" return normalize( tsn * mapN );",
"}"
].join( "\n" ), null, { derivatives: true } );
return {
perturbNormal2Arb: perturbNormal2Arb
};
} )();
NormalMapNode.prototype = Object.create( TempNode.prototype );
NormalMapNode.prototype.constructor = NormalMapNode;
NormalMapNode.prototype.nodeType = "NormalMap";
NormalMapNode.prototype.generate = function ( builder, output ) {
if ( builder.isShader( 'fragment' ) ) {
var perturbNormal2Arb = builder.include( NormalMapNode.Nodes.perturbNormal2Arb );
this.normal = this.normal || new NormalNode();
this.position = this.position || new PositionNode( PositionNode.VIEW );
this.uv = this.uv || new UVNode();
return builder.format( perturbNormal2Arb + '( -' + this.position.build( builder, 'v3' ) + ', ' +
this.normal.build( builder, 'v3' ) + ', ' +
this.value.build( builder, 'v3' ) + ', ' +
this.uv.build( builder, 'v2' ) + ', ' +
this.scale.build( builder, 'v2' ) + ' )', this.getType( builder ), output );
} else {
console.warn( "THREE.NormalMapNode is not compatible with " + builder.shader + " shader." );
return builder.format( 'vec3( 0.0 )', this.getType( builder ), output );
}
};
NormalMapNode.prototype.copy = function ( source ) {
TempNode.prototype.copy.call( this, source );
this.value = source.value;
this.scale = source.scale;
};
NormalMapNode.prototype.toJSON = function ( meta ) {
var data = this.getJSONNode( meta );
if ( ! data ) {
data = this.createJSONNode( meta );
data.value = this.value.toJSON( meta ).uuid;
data.scale = this.scale.toJSON( meta ).uuid;
}
return data;
};
export { NormalMapNode };
|