diff --git a/examples/jsm/nodes/accessors/ReflectNode.js b/examples/jsm/nodes/accessors/ReflectNode.js index b4134ed6bdd9c111c711b35d7eadefb4c528ecd7..ebfe9ef390cd491e407e3739c6e8282e8d86da36 100644 --- a/examples/jsm/nodes/accessors/ReflectNode.js +++ b/examples/jsm/nodes/accessors/ReflectNode.js @@ -54,7 +54,7 @@ ReflectNode.prototype.generate = function ( builder, output ) { case ReflectNode.VECTOR: - var viewNormalNode = builder.context.viewNormal || new NormalNode(); + var viewNormalNode = builder.context.viewNormal || new NormalNode( NormalNode.VIEW ); var roughnessNode = builder.context.roughness; var viewNormal = viewNormalNode.build( builder, 'v3' ); @@ -63,7 +63,7 @@ ReflectNode.prototype.generate = function ( builder, output ) { var method = `reflect( -normalize( ${viewPosition} ), ${viewNormal} )`; - if ( viewNormalNode && roughness ) { + if ( 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} ) )`; diff --git a/examples/jsm/nodes/misc/TextureCubeNode.js b/examples/jsm/nodes/misc/TextureCubeNode.js index 4e547b0dd2345743e2de0db71b78c9321d308e50..96fe19b5500c2fb2a58118e47eb2de398a2bfb69 100644 --- a/examples/jsm/nodes/misc/TextureCubeNode.js +++ b/examples/jsm/nodes/misc/TextureCubeNode.js @@ -10,26 +10,24 @@ import { ReflectNode } from '../accessors/ReflectNode.js'; import { NormalNode } from '../accessors/NormalNode.js'; import { ColorSpaceNode } from '../utils/ColorSpaceNode.js'; -function TextureCubeNode( value, textureSize, uv, bias ) { +function TextureCubeNode( value, uv, bias ) { TempNode.call( this, 'v4' ); this.value = value; - textureSize = textureSize || new FloatNode( 1024 ); - - this.radianceCache = { uv: new TextureCubeUVNode( + this.radianceNode = new TextureCubeUVNode( + this.value, uv || new ReflectNode( ReflectNode.VECTOR ), - textureSize, // bias should be replaced in builder.context in build process bias - ) }; + ); - this.irradianceCache = { uv: new TextureCubeUVNode( + this.irradianceNode = new TextureCubeUVNode( + this.value, new NormalNode( NormalNode.WORLD ), - textureSize, new FloatNode( 1 ).setReadonly( true ) - ) }; + ); } @@ -37,45 +35,6 @@ TextureCubeNode.prototype = Object.create( TempNode.prototype ); TextureCubeNode.prototype.constructor = TextureCubeNode; TextureCubeNode.prototype.nodeType = "TextureCube"; -TextureCubeNode.prototype.generateTextureCubeUV = function ( builder, cache ) { - - var uv_10 = cache.uv.build( builder ) + '.uv_10', - uv_20 = cache.uv.build( builder ) + '.uv_20', - t = cache.uv.build( builder ) + '.t'; - - var color10 = 'texture2D( ' + this.value.build( builder, 'sampler2D' ) + ', ' + uv_10 + ' )', - color20 = 'texture2D( ' + this.value.build( builder, 'sampler2D' ) + ', ' + uv_20 + ' )'; - - // add a custom context for fix incompatibility with the core - // include ColorSpace function only for vertex shader (in fragment shader color space functions is added automatically by core) - // this should be removed in the future - // context.include =: is used to include or not functions if used FunctionNode - // context.ignoreCache =: not create temp variables nodeT0..9 to optimize the code - var context = { include: builder.isShader( 'vertex' ), ignoreCache: true }; - var outputType = this.getType( builder ); - - builder.addContext( context ); - - cache.colorSpace10 = cache.colorSpace10 || new ColorSpaceNode( new ExpressionNode( '', outputType ) ); - cache.colorSpace10.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); - cache.colorSpace10.input.parse( color10 ); - - color10 = cache.colorSpace10.build( builder, outputType ); - - cache.colorSpace20 = cache.colorSpace20 || new ColorSpaceNode( new ExpressionNode( '', outputType ) ); - cache.colorSpace20.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); - cache.colorSpace20.input.parse( color20 ); - - color20 = cache.colorSpace20.build( builder, outputType ); - - // end custom context - - builder.removeContext(); - - return 'mix( ' + color10 + ', ' + color20 + ', ' + t + ' ).rgb'; - -}; - TextureCubeNode.prototype.generate = function ( builder, output ) { if ( builder.isShader( 'fragment' ) ) { @@ -88,10 +47,9 @@ TextureCubeNode.prototype.generate = function ( builder, output ) { } - var cache = builder.slot === 'irradiance' ? this.irradianceCache : this.radianceCache; - var result = this.generateTextureCubeUV( builder, cache ); + var scopeNode = builder.slot === 'irradiance' ? this.irradianceNode : this.radianceNode; - return builder.format( 'vec4( ' + result + ', 1.0 )', this.getType( builder ), output ); + return scopeNode.build( builder, output ); } else { diff --git a/examples/jsm/nodes/misc/TextureCubeUVNode.js b/examples/jsm/nodes/misc/TextureCubeUVNode.js index e4331e705c22633ffbd5c03099b33060ed054617..c1cadcdb20745f8d2721672e5d54ecac25fa1c5d 100644 --- a/examples/jsm/nodes/misc/TextureCubeUVNode.js +++ b/examples/jsm/nodes/misc/TextureCubeUVNode.js @@ -6,157 +6,159 @@ import { TempNode } from '../core/TempNode.js'; import { ConstNode } from '../core/ConstNode.js'; import { StructNode } from '../core/StructNode.js'; import { FunctionNode } from '../core/FunctionNode.js'; +import { FunctionCallNode } from '../core/FunctionCallNode.js'; +import { ExpressionNode } from '../core/ExpressionNode.js'; +import { ReflectNode } from '../accessors/ReflectNode.js'; +import { FloatNode } from '../inputs/FloatNode.js'; +import { OperatorNode } from '../math/OperatorNode.js'; +import { MathNode } from '../math/MathNode.js'; +import { CondNode } from '../math/CondNode.js'; +import { ColorSpaceNode } from '../utils/ColorSpaceNode.js'; -function TextureCubeUVNode( uv, textureSize, bias ) { +function TextureCubeUVNode( value, uv, bias ) { - TempNode.call( this, 'TextureCubeUVData' ); // TextureCubeUVData is type as StructNode + TempNode.call( this, 'v4' ); + this.value = value, this.uv = uv; - this.textureSize = textureSize; this.bias = bias; } TextureCubeUVNode.Nodes = ( function () { - var TextureCubeUVData = new StructNode( [ - "struct TextureCubeUVData {", - " vec2 uv_10;", - " vec2 uv_20;", - " float t;", - "}" - ].join( "\n" ) ); - - var getFaceFromDirection = new FunctionNode( [ - "int getFaceFromDirection(vec3 direction) {", - " vec3 absDirection = abs(direction);", - " int face = -1;", - " if( absDirection.x > absDirection.z ) {", - " if(absDirection.x > absDirection.y )", - " face = direction.x > 0.0 ? 0 : 3;", - " else", - " face = direction.y > 0.0 ? 1 : 4;", - " }", - " else {", - " if(absDirection.z > absDirection.y )", - " face = direction.z > 0.0 ? 2 : 5;", - " else", - " face = direction.y > 0.0 ? 1 : 4;", - " }", - " return face;", - "}" - ].join( "\n" ) ); - - var cubeUV_maxLods1 = new ConstNode( "#define cubeUV_maxLods1 ( log2( cubeUV_textureSize * 0.25 ) - 1.0 )" ); - var cubeUV_rangeClamp = new ConstNode( "#define cubeUV_rangeClamp ( exp2( ( 6.0 - 1.0 ) * 2.0 ) )" ); - - var MipLevelInfo = new FunctionNode( [ - "vec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness, in float cubeUV_textureSize ) {", - " float scale = exp2(cubeUV_maxLods1 - roughnessLevel);", - " float dxRoughness = dFdx(roughness);", - " float dyRoughness = dFdy(roughness);", - " vec3 dx = dFdx( vec * scale * dxRoughness );", - " vec3 dy = dFdy( vec * scale * dyRoughness );", - " float d = max( dot( dx, dx ), dot( dy, dy ) );", - // Clamp the value to the max mip level counts. hard coded to 6 mips" - " d = clamp(d, 1.0, cubeUV_rangeClamp);", - " float mipLevel = 0.5 * log2(d);", - " return vec2(floor(mipLevel), fract(mipLevel));", - "}" - ].join( "\n" ), [ cubeUV_maxLods1, cubeUV_rangeClamp ], { derivatives: true } ); - - var cubeUV_maxLods2 = new ConstNode( "#define cubeUV_maxLods2 ( log2( cubeUV_textureSize * 0.25 ) - 2.0 )" ); - var cubeUV_rcpTextureSize = new ConstNode( "#define cubeUV_rcpTextureSize ( 1.0 / cubeUV_textureSize )" ); - - var getCubeUV = new FunctionNode( [ - "vec2 getCubeUV( vec3 direction, float roughnessLevel, float mipLevel, in float cubeUV_textureSize ) {", - " mipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;", - " float a = 16.0 * cubeUV_rcpTextureSize;", - "", - " vec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );", - " vec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;", - // float powScale = exp2(roughnessLevel + mipLevel);" - " float powScale = exp2_packed.x * exp2_packed.y;", - // float scale = 1.0 / exp2(roughnessLevel + 2.0 + mipLevel);" - " float scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;", - // float mipOffset = 0.75*(1.0 - 1.0/exp2(mipLevel))/exp2(roughnessLevel);" - " float mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;", - "", - " bool bRes = mipLevel == 0.0;", - " scale = bRes && (scale < a) ? a : scale;", - "", - " vec3 r;", - " vec2 offset;", - " int face = getFaceFromDirection(direction);", - "", - " float rcpPowScale = 1.0 / powScale;", - "", - " if( face == 0) {", - " r = vec3(direction.x, -direction.z, direction.y);", - " offset = vec2(0.0+mipOffset,0.75 * rcpPowScale);", - " offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;", - " }", - " else if( face == 1) {", - " r = vec3(direction.y, direction.x, direction.z);", - " offset = vec2(scale+mipOffset, 0.75 * rcpPowScale);", - " offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;", - " }", - " else if( face == 2) {", - " r = vec3(direction.z, direction.x, direction.y);", - " offset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);", - " offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;", - " }", - " else if( face == 3) {", - " r = vec3(direction.x, direction.z, direction.y);", - " offset = vec2(0.0+mipOffset,0.5 * rcpPowScale);", - " offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;", - " }", - " else if( face == 4) {", - " r = vec3(direction.y, direction.x, -direction.z);", - " offset = vec2(scale+mipOffset, 0.5 * rcpPowScale);", - " offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;", - " }", - " else {", - " r = vec3(direction.z, -direction.x, direction.y);", - " offset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);", - " offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;", - " }", - " r = normalize(r);", - " float texelOffset = 0.5 * cubeUV_rcpTextureSize;", - " vec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;", - " vec2 base = offset + vec2( texelOffset );", - " return base + s * ( scale - 2.0 * texelOffset );", - "}" - ].join( "\n" ), [ cubeUV_maxLods2, cubeUV_rcpTextureSize, getFaceFromDirection ] ); - - var cubeUV_maxLods3 = new ConstNode( "#define cubeUV_maxLods3 ( log2( cubeUV_textureSize * 0.25 ) - 3.0 )" ); - - var textureCubeUV = new FunctionNode( [ - "TextureCubeUVData textureCubeUV( vec3 reflectedDirection, float roughness, in float cubeUV_textureSize ) {", - " float roughnessVal = roughness * cubeUV_maxLods3;", - " float r1 = floor(roughnessVal);", - " float r2 = r1 + 1.0;", - " float t = fract(roughnessVal);", - " vec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness, cubeUV_textureSize);", - " float s = mipInfo.y;", - " float level0 = mipInfo.x;", - " float level1 = level0 + 1.0;", - " level1 = level1 > 5.0 ? 5.0 : level1;", - "", - // round to nearest mipmap if we are not interpolating." - " level0 += min( floor( s + 0.5 ), 5.0 );", - "", - // Tri linear interpolation." - " vec2 uv_10 = getCubeUV(reflectedDirection, r1, level0, cubeUV_textureSize);", - " vec2 uv_20 = getCubeUV(reflectedDirection, r2, level0, cubeUV_textureSize);", - "", - " return TextureCubeUVData(uv_10, uv_20, t);", - "}" - ].join( "\n" ), [ TextureCubeUVData, cubeUV_maxLods3, MipLevelInfo, getCubeUV ] ); + var TextureCubeUVData = new StructNode( +`struct TextureCubeUVData { + vec4 tl; + vec4 tr; + vec4 br; + vec4 bl; + vec2 f; +}` ); + + var cubeUV_maxMipLevel = new ConstNode( `float cubeUV_maxMipLevel 8.0`, true ); + var cubeUV_minMipLevel = new ConstNode( `float cubeUV_minMipLevel 4.0`, true ); + var cubeUV_maxTileSize = new ConstNode( `float cubeUV_maxTileSize 256.0`, true ); + var cubeUV_minTileSize = new ConstNode( `float cubeUV_minTileSize 16.0`, true ); + + // These shader functions convert between the UV coordinates of a single face of + // a cubemap, the 0-5 integer index of a cube face, and the direction vector for + // sampling a textureCube (not generally normalized). + + var getFace = new FunctionNode( +`float getFace(vec3 direction) { + vec3 absDirection = abs(direction); + float face = -1.0; + if (absDirection.x > absDirection.z) { + if (absDirection.x > absDirection.y) + face = direction.x > 0.0 ? 0.0 : 3.0; + else + face = direction.y > 0.0 ? 1.0 : 4.0; + } else { + if (absDirection.z > absDirection.y) + face = direction.z > 0.0 ? 2.0 : 5.0; + else + face = direction.y > 0.0 ? 1.0 : 4.0; + } + return face; +}` ); + getFace.useKeywords = false; + + var getUV = new FunctionNode( +`vec2 getUV(vec3 direction, float face) { + vec2 uv; + if (face == 0.0) { + uv = vec2(-direction.z, direction.y) / abs(direction.x); + } else if (face == 1.0) { + uv = vec2(direction.x, -direction.z) / abs(direction.y); + } else if (face == 2.0) { + uv = direction.xy / abs(direction.z); + } else if (face == 3.0) { + uv = vec2(direction.z, direction.y) / abs(direction.x); + } else if (face == 4.0) { + uv = direction.xz / abs(direction.y); + } else { + uv = vec2(-direction.x, direction.y) / abs(direction.z); + } + return 0.5 * (uv + 1.0); +}` ); + getUV.useKeywords = false; + + var bilinearCubeUV = new FunctionNode( +`TextureCubeUVData bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) { + float face = getFace(direction); + float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0); + mipInt = max(mipInt, cubeUV_minMipLevel); + float faceSize = exp2(mipInt); + float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize); + vec2 uv = getUV(direction, face) * (faceSize - 1.0); + vec2 f = fract(uv); + uv += 0.5 - f; + if (face > 2.0) { + uv.y += faceSize; + face -= 3.0; + } + uv.x += face * faceSize; + if(mipInt < cubeUV_maxMipLevel){ + uv.y += 2.0 * cubeUV_maxTileSize; + } + uv.y += filterInt * 2.0 * cubeUV_minTileSize; + uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize); + uv *= texelSize; + vec4 tl = texture2D(envMap, uv); + uv.x += texelSize; + vec4 tr = texture2D(envMap, uv); + uv.y += texelSize; + vec4 br = texture2D(envMap, uv); + uv.x -= texelSize; + vec4 bl = texture2D(envMap, uv); + + return TextureCubeUVData( tl, tr, br, bl, f ); +}`, [ TextureCubeUVData, getFace, getUV, cubeUV_maxMipLevel, cubeUV_minMipLevel, cubeUV_maxTileSize, cubeUV_minTileSize ] ); + bilinearCubeUV.useKeywords = false; + + // These defines must match with PMREMGenerator + + var r0 = new ConstNode( `float r0 1.0`, true ); + var v0 = new ConstNode( `float v0 0.339`, true ); + var m0 = new ConstNode( `float m0 -2.0`, true ); + var r1 = new ConstNode( `float r1 0.8`, true ); + var v1 = new ConstNode( `float v1 0.276`, true ); + var m1 = new ConstNode( `float m1 -1.0`, true ); + var r4 = new ConstNode( `float r4 0.4`, true ); + var v4 = new ConstNode( `float v4 0.046`, true ); + var m4 = new ConstNode( `float m4 2.0`, true ); + var r5 = new ConstNode( `float r5 0.305`, true ); + var v5 = new ConstNode( `float v5 0.016`, true ); + var m5 = new ConstNode( `float m5 3.0`, true ); + var r6 = new ConstNode( `float r6 0.21`, true ); + var v6 = new ConstNode( `float v6 0.0038`, true ); + var m6 = new ConstNode( `float m6 4.0`, true ); + + var defines = [ r0, v0, m0, r1, v1, m1, r4, v4, m4, r5, v5, m5, r6, v6, m6 ]; + + var roughnessToMip = new FunctionNode( +`float roughnessToMip(float roughness) { + float mip = 0.0; + if (roughness >= r1) { + mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0; + } else if (roughness >= r4) { + mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1; + } else if (roughness >= r5) { + mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4; + } else if (roughness >= r6) { + mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5; + } else { + mip = -2.0 * log2(1.16 * roughness);// 1.16 = 1.79^0.25 + } + return mip; +}`, defines ); return { - TextureCubeUVData: TextureCubeUVData, - textureCubeUV: textureCubeUV + bilinearCubeUV: bilinearCubeUV, + roughnessToMip: roughnessToMip, + m0: m0, + cubeUV_maxMipLevel: cubeUV_maxMipLevel }; } )(); @@ -165,17 +167,92 @@ TextureCubeUVNode.prototype = Object.create( TempNode.prototype ); TextureCubeUVNode.prototype.constructor = TextureCubeUVNode; TextureCubeUVNode.prototype.nodeType = "TextureCubeUV"; +TextureCubeUVNode.prototype.bilinearCubeUV = function ( builder, texture, uv, mipInt ) { + + var bilinearCubeUV = new FunctionCallNode( TextureCubeUVNode.Nodes.bilinearCubeUV, [ texture, uv, mipInt ] ); + + this.colorSpaceTL = this.colorSpaceTL || new ColorSpaceNode( new ExpressionNode( '', 'v4' ) ); + this.colorSpaceTL.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); + this.colorSpaceTL.input.parse( bilinearCubeUV.build( builder ) + '.tl' ); + + this.colorSpaceTR = this.colorSpaceTR || new ColorSpaceNode( new ExpressionNode( '', 'v4' ) ); + this.colorSpaceTR.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); + this.colorSpaceTR.input.parse( bilinearCubeUV.build( builder ) + '.tr' ); + + this.colorSpaceBL = this.colorSpaceBL || new ColorSpaceNode( new ExpressionNode( '', 'v4' ) ); + this.colorSpaceBL.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); + this.colorSpaceBL.input.parse( bilinearCubeUV.build( builder ) + '.bl' ); + + this.colorSpaceBR = this.colorSpaceBR || new ColorSpaceNode( new ExpressionNode( '', 'v4' ) ); + this.colorSpaceBR.fromDecoding( builder.getTextureEncodingFromMap( this.value.value ) ); + this.colorSpaceBR.input.parse( bilinearCubeUV.build( builder ) + '.br' ); + + var f = bilinearCubeUV.build( builder ) + '.f'; + + // add a custom context for fix incompatibility with the core + // include ColorSpace function only for vertex shader (in fragment shader color space functions is added automatically by core) + // this should be removed in the future + // context.include =: is used to include or not functions if used FunctionNode + // context.ignoreCache =: not create temp variables nodeT0..9 to optimize the code + var context = { include: builder.isShader( 'vertex' ), ignoreCache: true }; + + builder.addContext( context ); + + this.colorSpaceTLExp = new ExpressionNode( this.colorSpaceTL.build( builder, 'v4' ), 'v4' ); + this.colorSpaceTRExp = new ExpressionNode( this.colorSpaceTR.build( builder, 'v4' ), 'v4' ); + this.colorSpaceBLExp = new ExpressionNode( this.colorSpaceBL.build( builder, 'v4' ), 'v4' ); + this.colorSpaceBRExp = new ExpressionNode( this.colorSpaceBR.build( builder, 'v4' ), 'v4' ); + + // end custom context + + builder.removeContext(); + + // -- + + var output = new ExpressionNode(`mix( mix( cubeUV_TL, cubeUV_TR, cubeUV.f.x ), mix( cubeUV_BL, cubeUV_BR, cubeUV.f.x ), cubeUV.f.y )`, 'v4' ); + output.keywords['cubeUV_TL'] = this.colorSpaceTLExp; + output.keywords['cubeUV_TR'] = this.colorSpaceTRExp; + output.keywords['cubeUV_BL'] = this.colorSpaceBLExp; + output.keywords['cubeUV_BR'] = this.colorSpaceBRExp; + output.keywords['cubeUV'] = bilinearCubeUV; + + return output; + +}; + TextureCubeUVNode.prototype.generate = function ( builder, output ) { if ( builder.isShader( 'fragment' ) ) { - var textureCubeUV = builder.include( TextureCubeUVNode.Nodes.textureCubeUV ); + var uv = this.uv; + var bias = this.bias || builder.context.roughness; + + var mipV = new FunctionCallNode( TextureCubeUVNode.Nodes.roughnessToMip, [ bias ] ); + var mip = new MathNode( mipV, TextureCubeUVNode.Nodes.m0, TextureCubeUVNode.Nodes.cubeUV_maxMipLevel, MathNode.CLAMP ); + var mipInt = new MathNode( mip, MathNode.FLOOR ); + var mipF = new MathNode( mip, MathNode.FRACT ); + + var color0 = this.bilinearCubeUV( builder, this.value, uv, mipInt ); + var color1 = this.bilinearCubeUV( builder, this.value, uv, new OperatorNode( + mipInt, + new FloatNode( 1 ).setReadonly( true ), + OperatorNode.ADD + ) ); + + var color1Mix = new MathNode( color0, color1, mipF, MathNode.MIX ); - var biasNode = this.bias || builder.context.roughness; +/* + // TODO: Optimize this in the future + var cond = new CondNode( + mipF, + new FloatNode( 0 ).setReadonly( true ), + CondNode.EQUAL, + color0, // if + color1Mix // else + ); +*/ - return builder.format( textureCubeUV + '( ' + this.uv.build( builder, 'v3' ) + ', ' + - biasNode.build( builder, 'f' ) + ', ' + - this.textureSize.build( builder, 'f' ) + ' )', this.getType( builder ), output ); + return builder.format( color1Mix.build( builder ), 'v4', output ); } else { @@ -195,9 +272,9 @@ TextureCubeUVNode.prototype.toJSON = function ( meta ) { data = this.createJSONNode( meta ); + data.value = this.value.toJSON( meta ).uuid; data.uv = this.uv.toJSON( meta ).uuid; - data.textureSize = this.textureSize.toJSON( meta ).uuid; - data.blinnExponentToRoughness = this.blinnExponentToRoughness.toJSON( meta ).uuid; + data.bias = this.bias.toJSON( meta ).uuid; } diff --git a/examples/webgl_materials_envmaps_hdr_nodes.html b/examples/webgl_materials_envmaps_hdr_nodes.html index 0639f73429aed20dfdd8f28e6b36f5fc1ee0575a..5fa1c0cb65bef3689f1a05197ad074617400b07f 100644 --- a/examples/webgl_materials_envmaps_hdr_nodes.html +++ b/examples/webgl_materials_envmaps_hdr_nodes.html @@ -1,35 +1,18 @@ - threejs webgl - node material - hdr environment mapping + threejs webgl - materials - hdr environment mapping - +
-
threejs - High dynamic range (RGBE) Image-based Lighting (IBL)
using run-time generated pre-filtered roughness mipmaps (PMREM)
- Created by Prashant Sharma and Ben Houston.
+
+ threejs - High dynamic range (RGBE) Image-based Lighting (IBL)
using run-time generated pre-filtered roughness mipmaps (PMREM)
+ Created by Prashant Sharma and Ben Houston. +