Spaces:
Running
Running
File size: 4,664 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 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 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
/**
* @author sunag / http://www.sunag.com.br/
*/
import { TempNode } from '../core/TempNode.js';
import { FloatNode } from '../inputs/FloatNode.js';
import { FunctionNode } from '../core/FunctionNode.js';
import { NormalNode } from '../accessors/NormalNode.js';
import { PositionNode } from '../accessors/PositionNode.js';
function BumpMapNode( value, scale ) {
TempNode.call( this, 'v3' );
this.value = value;
this.scale = scale || new FloatNode( 1 );
this.toNormalMap = false;
}
BumpMapNode.Nodes = ( function () {
var dHdxy_fwd = new FunctionNode( [
// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen
// http://api.unrealengine.com/attachments/Engine/Rendering/LightingAndShadows/BumpMappingWithoutTangentSpace/mm_sfgrad_bump.pdf
// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
"vec2 dHdxy_fwd( sampler2D bumpMap, vec2 vUv, float bumpScale ) {",
// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
" vec2 dSTdx = dFdx( vUv );",
" vec2 dSTdy = dFdy( vUv );",
" float Hll = bumpScale * texture2D( bumpMap, vUv ).x;",
" float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;",
" float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;",
" return vec2( dBx, dBy );",
"}"
].join( "\n" ), null, { derivatives: true } );
var perturbNormalArb = new FunctionNode( [
"vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {",
// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
" vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );",
" vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );",
" vec3 vN = surf_norm;", // normalized
" vec3 R1 = cross( vSigmaY, vN );",
" vec3 R2 = cross( vN, vSigmaX );",
" float fDet = dot( vSigmaX, R1 );",
" fDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );",
" vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );",
" return normalize( abs( fDet ) * surf_norm - vGrad );",
"}"
].join( "\n" ), [ dHdxy_fwd ], { derivatives: true } );
var bumpToNormal = new FunctionNode( [
"vec3 bumpToNormal( sampler2D bumpMap, vec2 uv, float scale ) {",
" vec2 dSTdx = dFdx( uv );",
" vec2 dSTdy = dFdy( uv );",
" float Hll = texture2D( bumpMap, uv ).x;",
" float dBx = texture2D( bumpMap, uv + dSTdx ).x - Hll;",
" float dBy = texture2D( bumpMap, uv + dSTdy ).x - Hll;",
" return vec3( .5 - ( dBx * scale ), .5 - ( dBy * scale ), 1.0 );",
"}"
].join( "\n" ), null, { derivatives: true } );
return {
dHdxy_fwd: dHdxy_fwd,
perturbNormalArb: perturbNormalArb,
bumpToNormal: bumpToNormal
};
} )();
BumpMapNode.prototype = Object.create( TempNode.prototype );
BumpMapNode.prototype.constructor = BumpMapNode;
BumpMapNode.prototype.nodeType = "BumpMap";
BumpMapNode.prototype.generate = function ( builder, output ) {
if ( builder.isShader( 'fragment' ) ) {
if ( this.toNormalMap ) {
var bumpToNormal = builder.include( BumpMapNode.Nodes.bumpToNormal );
return builder.format( bumpToNormal + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' +
this.value.uv.build( builder, 'v2' ) + ', ' +
this.scale.build( builder, 'f' ) + ' )', this.getType( builder ), output );
} else {
var derivativeHeight = builder.include( BumpMapNode.Nodes.dHdxy_fwd ),
perturbNormalArb = builder.include( BumpMapNode.Nodes.perturbNormalArb );
this.normal = this.normal || new NormalNode();
this.position = this.position || new PositionNode( PositionNode.VIEW );
var derivativeHeightCode = derivativeHeight + '( ' + this.value.build( builder, 'sampler2D' ) + ', ' +
this.value.uv.build( builder, 'v2' ) + ', ' +
this.scale.build( builder, 'f' ) + ' )';
return builder.format( perturbNormalArb + '( -' + this.position.build( builder, 'v3' ) + ', ' +
this.normal.build( builder, 'v3' ) + ', ' +
derivativeHeightCode + ' )', this.getType( builder ), output );
}
} else {
console.warn( "THREE.BumpMapNode is not compatible with " + builder.shader + " shader." );
return builder.format( 'vec3( 0.0 )', this.getType( builder ), output );
}
};
BumpMapNode.prototype.copy = function ( source ) {
TempNode.prototype.copy.call( this, source );
this.value = source.value;
this.scale = source.scale;
};
BumpMapNode.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 { BumpMapNode };
|