提交 3e4cee36 编写于 作者: S sunag
上级 70479488
......@@ -57,12 +57,6 @@ export * from './math/CondNode';
export * from './procedural/NoiseNode';
export * from './procedural/CheckerNode';
// bsdfs
export * from './bsdfs/BlinnShininessExponentNode';
export * from './bsdfs/BlinnExponentToRoughnessNode';
export * from './bsdfs/RoughnessToBlinnExponentNode';
// misc
export * from './misc/TextureCubeUVNode';
......@@ -79,6 +73,7 @@ export * from './utils/TimerNode';
export * from './utils/VelocityNode';
export * from './utils/UVTransformNode';
export * from './utils/MaxMIPLevelNode';
export * from './utils/SpecularMIPLevelNode';
export * from './utils/ColorSpaceNode';
// effects
......
......@@ -59,12 +59,6 @@ export { CondNode } from './math/CondNode.js';
export { NoiseNode } from './procedural/NoiseNode.js';
export { CheckerNode } from './procedural/CheckerNode.js';
// bsdfs
export { BlinnShininessExponentNode } from './bsdfs/BlinnShininessExponentNode.js';
export { BlinnExponentToRoughnessNode } from './bsdfs/BlinnExponentToRoughnessNode.js';
export { RoughnessToBlinnExponentNode } from './bsdfs/RoughnessToBlinnExponentNode.js';
// misc
export { TextureCubeUVNode } from './misc/TextureCubeUVNode.js';
......@@ -81,6 +75,7 @@ export { TimerNode } from './utils/TimerNode.js';
export { VelocityNode } from './utils/VelocityNode.js';
export { UVTransformNode } from './utils/UVTransformNode.js';
export { MaxMIPLevelNode } from './utils/MaxMIPLevelNode.js';
export { SpecularMIPLevelNode } from './utils/SpecularMIPLevelNode.js';
export { ColorSpaceNode } from './utils/ColorSpaceNode.js';
export { SubSlotNode } from './utils/SubSlotNode.js';
......
......@@ -55,11 +55,22 @@ ReflectNode.prototype.generate = function ( builder, output ) {
case ReflectNode.VECTOR:
var viewNormalNode = builder.context.viewNormal || new NormalNode();
var roughnessNode = builder.context.roughness;
var viewNormal = viewNormalNode.build( builder, 'v3' );
var viewPosition = new PositionNode( PositionNode.VIEW ).build( builder, 'v3' );
var roughness = roughnessNode ? roughnessNode.build( builder, 'f' ) : undefined;
var code = `inverseTransformDirection( reflect( -normalize( ${viewPosition} ), ${viewNormal} ), viewMatrix )`;
var method = `reflect( -normalize( ${viewPosition} ), ${viewNormal} )`;
if ( viewNormalNode && roughness ) {
// Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane.
method = `normalize( mix( ${method}, ${viewNormal}, ${roughness} * ${roughness} ) )`;
}
var code = `inverseTransformDirection( ${method}, viewMatrix )`;
if ( isUnique ) {
......
import { TempNode } from '../core/TempNode';
import { NodeBuilder } from '../core/NodeBuilder';
import { BlinnShininessExponentNode } from './BlinnShininessExponentNode';
export class BlinnExponentToRoughnessNode extends TempNode {
constructor(blinnExponent?: BlinnShininessExponentNode);
blinnExponent: BlinnShininessExponentNode;
nodeType: string;
generate(builder: NodeBuilder, output: string): string;
copy(source: BlinnExponentToRoughnessNode): this;
}
/**
* @author sunag / http://www.sunag.com.br/
*/
import { TempNode } from '../core/TempNode.js';
import { BlinnShininessExponentNode } from './BlinnShininessExponentNode.js';
function BlinnExponentToRoughnessNode( blinnExponent ) {
TempNode.call( this, 'f' );
this.blinnExponent = blinnExponent || new BlinnShininessExponentNode();
}
BlinnExponentToRoughnessNode.prototype = Object.create( TempNode.prototype );
BlinnExponentToRoughnessNode.prototype.constructor = BlinnExponentToRoughnessNode;
BlinnExponentToRoughnessNode.prototype.nodeType = "BlinnExponentToRoughness";
BlinnExponentToRoughnessNode.prototype.generate = function ( builder, output ) {
return builder.format( 'BlinnExponentToGGXRoughness( ' + this.blinnExponent.build( builder, 'f' ) + ' )', this.type, output );
};
BlinnExponentToRoughnessNode.prototype.copy = function ( source ) {
TempNode.prototype.copy.call( this, source );
this.blinnExponent = source.blinnExponent;
return this;
};
BlinnExponentToRoughnessNode.prototype.toJSON = function ( meta ) {
var data = this.getJSONNode( meta );
if ( ! data ) {
data = this.createJSONNode( meta );
data.blinnExponent = this.blinnExponent;
}
return data;
};
export { BlinnExponentToRoughnessNode };
import { TempNode } from '../core/TempNode';
import { NodeBuilder } from '../core/NodeBuilder';
export class BlinnShininessExponentNode extends TempNode {
constructor();
nodeType: string;
generate(builder: NodeBuilder, output: string): string;
}
/**
* @author sunag / http://www.sunag.com.br/
*/
import { TempNode } from '../core/TempNode.js';
function BlinnShininessExponentNode() {
TempNode.call( this, 'f' );
}
BlinnShininessExponentNode.prototype = Object.create( TempNode.prototype );
BlinnShininessExponentNode.prototype.constructor = BlinnShininessExponentNode;
BlinnShininessExponentNode.prototype.nodeType = "BlinnShininessExponent";
BlinnShininessExponentNode.prototype.generate = function ( builder, output ) {
if ( builder.isCache( 'clearcoat' ) ) {
return builder.format( 'Material_Clearcoat_BlinnShininessExponent( material )', this.type, output );
} else {
return builder.format( 'Material_BlinnShininessExponent( material )', this.type, output );
}
};
export { BlinnShininessExponentNode };
......@@ -41,7 +41,7 @@ CubeTextureNode.prototype.generate = function ( builder, output ) {
if ( bias === undefined && builder.context.bias ) {
bias = new builder.context.bias( this ).build( builder, 'f' );
bias = builder.context.bias.setTexture( this ).build( builder, 'f' );
}
......
......@@ -42,7 +42,7 @@ TextureNode.prototype.generate = function ( builder, output ) {
if ( bias === undefined && builder.context.bias ) {
bias = new builder.context.bias( this ).build( builder, 'f' );
bias = builder.context.bias.setTexture( this ).build( builder, 'f' );
}
......
......@@ -11,7 +11,7 @@ import { Node } from '../../core/Node.js';
import { ExpressionNode } from '../../core/ExpressionNode.js';
import { ColorNode } from '../../inputs/ColorNode.js';
import { FloatNode } from '../../inputs/FloatNode.js';
import { RoughnessToBlinnExponentNode } from '../../bsdfs/RoughnessToBlinnExponentNode.js';
import { SpecularMIPLevelNode } from '../../utils/SpecularMIPLevelNode.js';
function StandardNode() {
......@@ -129,8 +129,12 @@ StandardNode.prototype.build = function ( builder ) {
} else {
var specularRoughness = new ExpressionNode('material.specularRoughness', 'f' );
var clearcoatRoughness = new ExpressionNode('material.clearcoatRoughness', 'f' );
var contextEnvironment = {
bias: RoughnessToBlinnExponentNode,
roughness: specularRoughness,
bias: new SpecularMIPLevelNode( specularRoughness ),
viewNormal: new ExpressionNode('normal', 'v3'),
gamma: true
};
......@@ -140,7 +144,8 @@ StandardNode.prototype.build = function ( builder ) {
};
var contextClearcoatEnvironment = {
bias: RoughnessToBlinnExponentNode,
roughness: clearcoatRoughness,
bias: new SpecularMIPLevelNode( clearcoatRoughness ),
viewNormal: new ExpressionNode('clearcoatNormal', 'v3'),
gamma: true
};
......@@ -235,7 +240,6 @@ StandardNode.prototype.build = function ( builder ) {
builder.requires.transparent = alpha !== undefined;
builder.addParsCode( [
"varying vec3 vViewPosition;",
"#ifndef FLAT_SHADED",
......@@ -457,7 +461,7 @@ StandardNode.prototype.build = function ( builder ) {
if ( builder.requires.irradiance ) {
output.push( "irradiance += PI * " + environment.irradiance.result + ";" );
output.push( "iblIrradiance += PI * " + environment.irradiance.result + ";" );
}
......
......@@ -20,37 +20,52 @@ function NormalMapNode( value, scale ) {
NormalMapNode.Nodes = ( function () {
var perturbNormal2Arb = new FunctionNode( [
var perturbNormal2Arb = new FunctionNode(
// Per-Pixel Tangent Space Normal Mapping
// http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
// 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 vUv, vec2 normalScale ) {
"vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 map, vec2 mUv, vec2 normalScale ) {",
// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
// 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( vUv.st );
vec2 st1 = dFdy( vUv.st );
" 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
" 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 );
" 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;
" vec3 mapN = map * 2.0 - 1.0;",
mapN.xy *= normalScale;
" mapN.xy *= normalScale;",
" mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );",
#ifdef DOUBLE_SIDED
" return normalize( tsn * mapN );",
// Workaround for Adreno GPUs gl_FrontFacing bug. See #15850 and #10331
// http://hacksoflife.blogspot.com/2009/11/per-pixel-tangent-space-normal-mapping.html?showComment=1522254677437#c5087545147696715943
vec3 NfromST = cross( S, T );
if( dot( NfromST, N ) > 0.0 ) {
"}"
S *= -1.0;
T *= -1.0;
].join( "\n" ), null, { derivatives: true } );
}
#else
mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );
#endif
mat3 tsn = mat3( S, T, N );
return normalize( tsn * mapN );
}`, null, { derivatives: true } );
return {
perturbNormal2Arb: perturbNormal2Arb
......
......@@ -9,26 +9,26 @@ import { TextureCubeUVNode } from './TextureCubeUVNode.js';
import { ReflectNode } from '../accessors/ReflectNode.js';
import { NormalNode } from '../accessors/NormalNode.js';
import { ColorSpaceNode } from '../utils/ColorSpaceNode.js';
import { BlinnExponentToRoughnessNode } from '../bsdfs/BlinnExponentToRoughnessNode.js';
import { SpecularMIPLevelNode } from '../utils/SpecularMIPLevelNode.js';
function TextureCubeNode( value, textureSize, uv, bias ) {
TempNode.call( this, 'v4' );
this.value = value;
this.textureSize = textureSize || new FloatNode( 1024 );
this.uv = uv || new ReflectNode( ReflectNode.VECTOR );
this.bias = bias || new BlinnExponentToRoughnessNode();
textureSize = textureSize || new FloatNode( 1024 );
this.radianceCache = { uv: new TextureCubeUVNode(
this.uv,
this.textureSize,
this.bias
uv || new ReflectNode( ReflectNode.VECTOR ),
textureSize,
// bias should be replaced in builder.context in build process
bias
) };
this.irradianceCache = { uv: new TextureCubeUVNode(
new NormalNode( NormalNode.WORLD ),
this.textureSize,
textureSize,
new FloatNode( 1 ).setReadonly( true )
) };
......@@ -83,6 +83,12 @@ TextureCubeNode.prototype.generate = function ( builder, output ) {
builder.require( 'irradiance' );
if ( builder.context.bias ) {
builder.context.bias.setTexture( this );
}
var cache = builder.slot === 'irradiance' ? this.irradianceCache : this.radianceCache;
var result = this.generateTextureCubeUV( builder, cache );
......
......@@ -7,13 +7,13 @@ import { ConstNode } from '../core/ConstNode.js';
import { StructNode } from '../core/StructNode.js';
import { FunctionNode } from '../core/FunctionNode.js';
function TextureCubeUVNode( uv, textureSize, blinnExponentToRoughness ) {
function TextureCubeUVNode( uv, textureSize, bias ) {
TempNode.call( this, 'TextureCubeUVData' ); // TextureCubeUVData is type as StructNode
this.uv = uv;
this.textureSize = textureSize;
this.blinnExponentToRoughness = blinnExponentToRoughness;
this.bias = bias;
}
......@@ -171,8 +171,10 @@ TextureCubeUVNode.prototype.generate = function ( builder, output ) {
var textureCubeUV = builder.include( TextureCubeUVNode.Nodes.textureCubeUV );
var biasNode = this.bias || builder.context.bias;
return builder.format( textureCubeUV + '( ' + this.uv.build( builder, 'v3' ) + ', ' +
this.blinnExponentToRoughness.build( builder, 'f' ) + ', ' +
biasNode.build( builder, 'f' ) + ', ' +
this.textureSize.build( builder, 'f' ) + ' )', this.getType( builder ), output );
} else {
......
import { TempNode } from '../core/TempNode';
import { NodeBuilder } from '../core/NodeBuilder';
import { MaxMIPLevelNode } from '../utils/MaxMIPLevelNode';
import { BlinnShininessExponentNode } from './BlinnShininessExponentNode';
import { FunctionNode } from '../core/FunctionNode';
export class RoughnessToBlinnExponentNode extends TempNode {
export class SpecularMIPLevelNode extends TempNode {
constructor(texture: Node);
texture: Node;
maxMIPLevel: MaxMIPLevelNode;
blinnShininessExponent: BlinnShininessExponentNode;
nodeType: string;
generate(builder: NodeBuilder, output: string): string;
copy(source: RoughnessToBlinnExponentNode): this;
copy(source: SpecularMIPLevelNode): this;
static Nodes: {
getSpecularMIPLevel: FunctionNode;
......
......@@ -4,30 +4,27 @@
import { TempNode } from '../core/TempNode.js';
import { FunctionNode } from '../core/FunctionNode.js';
import { MaxMIPLevelNode } from '../utils/MaxMIPLevelNode.js';
import { BlinnShininessExponentNode } from './BlinnShininessExponentNode.js';
import { MaxMIPLevelNode } from './MaxMIPLevelNode.js';
function RoughnessToBlinnExponentNode( texture ) {
function SpecularMIPLevelNode( roughness, texture ) {
TempNode.call( this, 'f' );
this.roughness = roughness;
this.texture = texture;
this.maxMIPLevel = new MaxMIPLevelNode( texture );
this.blinnShininessExponent = new BlinnShininessExponentNode();
this.maxMIPLevel = undefined;
}
RoughnessToBlinnExponentNode.Nodes = ( function () {
SpecularMIPLevelNode.Nodes = ( function () {
var getSpecularMIPLevel = new FunctionNode( [
// taken from here: http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html
"float getSpecularMIPLevel( const in float blinnShininessExponent, const in float maxMIPLevelScalar ) {",
"float getSpecularMIPLevel( const in float roughness, const in float maxMIPLevelScalar ) {",
// float envMapWidth = pow( 2.0, maxMIPLevelScalar );
// float desiredMIPLevel = log2( envMapWidth * sqrt( 3.0 ) ) - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );
" float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );",
" float sigma = PI * roughness * roughness / ( 1.0 + roughness );",
" float desiredMIPLevel = maxMIPLevelScalar + log2( sigma );",
// clamp to allowable LOD ranges.
" return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );",
......@@ -41,23 +38,32 @@ RoughnessToBlinnExponentNode.Nodes = ( function () {
} )();
RoughnessToBlinnExponentNode.prototype = Object.create( TempNode.prototype );
RoughnessToBlinnExponentNode.prototype.constructor = RoughnessToBlinnExponentNode;
RoughnessToBlinnExponentNode.prototype.nodeType = "RoughnessToBlinnExponent";
SpecularMIPLevelNode.prototype = Object.create( TempNode.prototype );
SpecularMIPLevelNode.prototype.constructor = SpecularMIPLevelNode;
SpecularMIPLevelNode.prototype.nodeType = "SpecularMIPLevel";
SpecularMIPLevelNode.prototype.setTexture = function( texture ) {
this.texture = texture;
return this;
};
RoughnessToBlinnExponentNode.prototype.generate = function ( builder, output ) {
SpecularMIPLevelNode.prototype.generate = function ( builder, output ) {
if ( builder.isShader( 'fragment' ) ) {
this.maxMIPLevel = this.maxMIPLevel || new MaxMIPLevelNode();
this.maxMIPLevel.texture = this.texture;
var getSpecularMIPLevel = builder.include( RoughnessToBlinnExponentNode.Nodes.getSpecularMIPLevel );
var getSpecularMIPLevel = builder.include( SpecularMIPLevelNode.Nodes.getSpecularMIPLevel );
return builder.format( getSpecularMIPLevel + '( ' + this.blinnShininessExponent.build( builder, 'f' ) + ', ' + this.maxMIPLevel.build( builder, 'f' ) + ' )', this.type, output );
return builder.format( getSpecularMIPLevel + '( ' + this.roughness.build( builder, 'f' ) + ', ' + this.maxMIPLevel.build( builder, 'f' ) + ' )', this.type, output );
} else {
console.warn( "THREE.RoughnessToBlinnExponentNode is not compatible with " + builder.shader + " shader." );
console.warn( "THREE.SpecularMIPLevelNode is not compatible with " + builder.shader + " shader." );
return builder.format( '0.0', this.type, output );
......@@ -65,17 +71,18 @@ RoughnessToBlinnExponentNode.prototype.generate = function ( builder, output ) {
};
RoughnessToBlinnExponentNode.prototype.copy = function ( source ) {
SpecularMIPLevelNode.prototype.copy = function ( source ) {
TempNode.prototype.copy.call( this, source );
this.texture = source.texture;
this.roughness = source.roughness;
return this;
};
RoughnessToBlinnExponentNode.prototype.toJSON = function ( meta ) {
SpecularMIPLevelNode.prototype.toJSON = function ( meta ) {
var data = this.getJSONNode( meta );
......@@ -84,6 +91,7 @@ RoughnessToBlinnExponentNode.prototype.toJSON = function ( meta ) {
data = this.createJSONNode( meta );
data.texture = this.texture;
data.roughness = this.roughness;
}
......@@ -91,4 +99,4 @@ RoughnessToBlinnExponentNode.prototype.toJSON = function ( meta ) {
};
export { RoughnessToBlinnExponentNode };
export { SpecularMIPLevelNode };
......@@ -582,7 +582,7 @@
subSlotNode.slots['radiance'] = new Nodes.OperatorNode( radiance, envNode, Nodes.OperatorNode.MUL );
subSlotNode.slots['irradiance'] = new Nodes.OperatorNode( irradiance, envNode, Nodes.OperatorNode.MUL );
mtl.environment = subSlotNode
mtl.environment = subSlotNode;
// GUI
......@@ -2488,7 +2488,7 @@
// MATERIAL
var bias = new Nodes.FloatNode( .5 );
var maxMIPLevel = new Nodes.MaxMIPLevelNode( new Nodes.TextureCubeNode( cubemap ) );
var maxMIPLevel = new Nodes.MaxMIPLevelNode( new Nodes.TextureCubeNode( cubemap, undefined, undefined, bias ) );
var mipsBias = new Nodes.OperatorNode( bias, maxMIPLevel, Nodes.OperatorNode.MUL );
mtl = new Nodes.PhongNodeMaterial();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册