| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 | 
							- 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 { FloatNode } from '../inputs/FloatNode.js';
 
- import { OperatorNode } from '../math/OperatorNode.js';
 
- import { MathNode } from '../math/MathNode.js';
 
- import { ColorSpaceNode } from '../utils/ColorSpaceNode.js';
 
- class TextureCubeUVNode extends TempNode {
 
- 	constructor( value, uv, bias ) {
 
- 		super( 'v4' );
 
- 		this.value = value,
 
- 		this.uv = uv;
 
- 		this.bias = bias;
 
- 	}
 
- 	bilinearCubeUV( builder, texture, uv, mipInt ) {
 
- 		const 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' );
 
- 		// 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
 
- 		const 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();
 
- 		// --
 
- 		const 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;
 
- 	}
 
- 	generate( builder, output ) {
 
- 		if ( builder.isShader( 'fragment' ) ) {
 
- 			const uv = this.uv;
 
- 			const bias = this.bias || builder.context.roughness;
 
- 			const mipV = new FunctionCallNode( TextureCubeUVNode.Nodes.roughnessToMip, [ bias ] );
 
- 			const mip = new MathNode( mipV, TextureCubeUVNode.Nodes.m0, TextureCubeUVNode.Nodes.cubeUV_maxMipLevel, MathNode.CLAMP );
 
- 			const mipInt	= new MathNode( mip, MathNode.FLOOR );
 
- 			const mipF	= new MathNode( mip, MathNode.FRACT );
 
- 			const color0 = this.bilinearCubeUV( builder, this.value, uv, mipInt );
 
- 			const color1 = this.bilinearCubeUV( builder, this.value, uv, new OperatorNode(
 
- 				mipInt,
 
- 				new FloatNode( 1 ).setReadonly( true ),
 
- 				OperatorNode.ADD
 
- 			) );
 
- 			const color1Mix = new MathNode( color0, color1, mipF, MathNode.MIX );
 
- 			/*
 
- 			// TODO: Optimize this in the future
 
- 			let cond = new CondNode(
 
- 				mipF,
 
- 				new FloatNode( 0 ).setReadonly( true ),
 
- 				CondNode.EQUAL,
 
- 				color0, // if
 
- 				color1Mix	// else
 
- 			);
 
- 			*/
 
- 			return builder.format( color1Mix.build( builder ), 'v4', output );
 
- 		} else {
 
- 			console.warn( 'THREE.TextureCubeUVNode is not compatible with ' + builder.shader + ' shader.' );
 
- 			return builder.format( 'vec4( 0.0 )', this.getType( builder ), output );
 
- 		}
 
- 	}
 
- 	toJSON( meta ) {
 
- 		let data = this.getJSONNode( meta );
 
- 		if ( ! data ) {
 
- 			data = this.createJSONNode( meta );
 
- 			data.value = this.value.toJSON( meta ).uuid;
 
- 			data.uv = this.uv.toJSON( meta ).uuid;
 
- 			data.bias = this.bias.toJSON( meta ).uuid;
 
- 		}
 
- 		return data;
 
- 	}
 
- }
 
- TextureCubeUVNode.Nodes = ( function () {
 
- 	const TextureCubeUVData = new StructNode(
 
- 		`struct TextureCubeUVData {
 
- 			vec4 tl;
 
- 			vec4 tr;
 
- 			vec4 br;
 
- 			vec4 bl;
 
- 			vec2 f;
 
- 		}` );
 
- 	const cubeUV_maxMipLevel = new ConstNode( 'float cubeUV_maxMipLevel 8.0', true );
 
- 	const cubeUV_minMipLevel = new ConstNode( 'float cubeUV_minMipLevel 4.0', true );
 
- 	const cubeUV_maxTileSize = new ConstNode( 'float cubeUV_maxTileSize 256.0', true );
 
- 	const 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).
 
- 	const 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;
 
- 	const getUV = new FunctionNode(
 
- 		`vec2 getUV(vec3 direction, float face) {
 
- 				vec2 uv;
 
- 				if (face == 0.0) {
 
- 					uv = vec2(direction.z, direction.y) / abs(direction.x); // pos x
 
- 				} else if (face == 1.0) {
 
- 					uv = vec2(-direction.x, -direction.z) / abs(direction.y); // pos y
 
- 				} else if (face == 2.0) {
 
- 					uv = vec2(-direction.x, direction.y) / abs(direction.z); // pos z
 
- 				} else if (face == 3.0) {
 
- 					uv = vec2(-direction.z, direction.y) / abs(direction.x); // neg x
 
- 				} else if (face == 4.0) {
 
- 					uv = vec2(-direction.x, direction.z) / abs(direction.y); // neg y
 
- 				} else {
 
- 					uv = vec2(direction.x, direction.y) / abs(direction.z); // neg z
 
- 				}
 
- 				return 0.5 * (uv + 1.0);
 
- 		}` );
 
- 	getUV.useKeywords = false;
 
- 	const 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
 
- 	const r0 = new ConstNode( 'float r0 1.0', true );
 
- 	const v0 = new ConstNode( 'float v0 0.339', true );
 
- 	const m0 = new ConstNode( 'float m0 -2.0', true );
 
- 	const r1 = new ConstNode( 'float r1 0.8', true );
 
- 	const v1 = new ConstNode( 'float v1 0.276', true );
 
- 	const m1 = new ConstNode( 'float m1 -1.0', true );
 
- 	const r4 = new ConstNode( 'float r4 0.4', true );
 
- 	const v4 = new ConstNode( 'float v4 0.046', true );
 
- 	const m4 = new ConstNode( 'float m4 2.0', true );
 
- 	const r5 = new ConstNode( 'float r5 0.305', true );
 
- 	const v5 = new ConstNode( 'float v5 0.016', true );
 
- 	const m5 = new ConstNode( 'float m5 3.0', true );
 
- 	const r6 = new ConstNode( 'float r6 0.21', true );
 
- 	const v6 = new ConstNode( 'float v6 0.0038', true );
 
- 	const m6 = new ConstNode( 'float m6 4.0', true );
 
- 	const defines = [ r0, v0, m0, r1, v1, m1, r4, v4, m4, r5, v5, m5, r6, v6, m6 ];
 
- 	const 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 {
 
- 		bilinearCubeUV: bilinearCubeUV,
 
- 		roughnessToMip: roughnessToMip,
 
- 		m0: m0,
 
- 		cubeUV_maxMipLevel: cubeUV_maxMipLevel
 
- 	};
 
- } )();
 
- TextureCubeUVNode.prototype.nodeType = 'TextureCubeUV';
 
- export { TextureCubeUVNode };
 
 
  |