THREE.WebGLShader: gl.getShaderInfoLog() fragment WARNING: 0:219: Overflow in implicit constant conversion, minimum range for lowp float is (-2,2) 1: #extension GL_OES_standard_derivatives : enable 2: precision highp float; 3: precision highp int; 4: #define SHADER_NAME MeshStandardMaterial 5: #define STANDARD 6: #define GAMMA_FACTOR 2 7: #define USE_MAP 8: #define USE_AOMAP 9: #define USE_NORMALMAP 10: #define USE_ROUGHNESSMAP 11: #define USE_METALNESSMAP 12: uniform mat4 viewMatrix; 13: uniform vec3 cameraPosition; 14: #define TONE_MAPPING 15: #ifndef saturate 16: #define saturate(a) clamp( a, 0.0, 1.0 ) 17: #endif 18: uniform float toneMappingExposure; 19: uniform float toneMappingWhitePoint; 20: vec3 LinearToneMapping( vec3 color ) { 21: return toneMappingExposure * color; 22: } 23: vec3 ReinhardToneMapping( vec3 color ) { 24: color *= toneMappingExposure; 25: return saturate( color / ( vec3( 1.0 ) + color ) ); 26: } 27: #define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) ) 28: vec3 Uncharted2ToneMapping( vec3 color ) { 29: color *= toneMappingExposure; 30: return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) ); 31: } 32: vec3 OptimizedCineonToneMapping( vec3 color ) { 33: color *= toneMappingExposure; 34: color = max( vec3( 0.0 ), color - 0.004 ); 35: return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) ); 36: } 37: vec3 ACESFilmicToneMapping( vec3 color ) { 38: color *= toneMappingExposure; 39: return saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) ); 40: } 41: vec3 toneMapping( vec3 color ) { return LinearToneMapping( color ); } 42: 43: vec4 LinearToLinear( in vec4 value ) { 44: return value; 45: } 46: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) { 47: return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a ); 48: } 49: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) { 50: return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a ); 51: } 52: vec4 sRGBToLinear( in vec4 value ) { 53: return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a ); 54: } 55: vec4 LinearTosRGB( in vec4 value ) { 56: return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); 57: } 58: vec4 RGBEToLinear( in vec4 value ) { 59: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 ); 60: } 61: vec4 LinearToRGBE( in vec4 value ) { 62: float maxComponent = max( max( value.r, value.g ), value.b ); 63: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 ); 64: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 ); 65: } 66: vec4 RGBMToLinear( in vec4 value, in float maxRange ) { 67: return vec4( value.rgb * value.a * maxRange, 1.0 ); 68: } 69: vec4 LinearToRGBM( in vec4 value, in float maxRange ) { 70: float maxRGB = max( value.r, max( value.g, value.b ) ); 71: float M = clamp( maxRGB / maxRange, 0.0, 1.0 ); 72: M = ceil( M * 255.0 ) / 255.0; 73: return vec4( value.rgb / ( M * maxRange ), M ); 74: } 75: vec4 RGBDToLinear( in vec4 value, in float maxRange ) { 76: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 ); 77: } 78: vec4 LinearToRGBD( in vec4 value, in float maxRange ) { 79: float maxRGB = max( value.r, max( value.g, value.b ) ); 80: float D = max( maxRange / maxRGB, 1.0 ); 81: D = min( floor( D ) / 255.0, 1.0 ); 82: return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D ); 83: } 84: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 ); 85: vec4 LinearToLogLuv( in vec4 value ) { 86: vec3 Xp_Y_XYZp = value.rgb * cLogLuvM; 87: Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) ); 88: vec4 vResult; 89: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z; 90: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0; 91: vResult.w = fract( Le ); 92: vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0; 93: return vResult; 94: } 95: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 ); 96: vec4 LogLuvToLinear( in vec4 value ) { 97: float Le = value.z * 255.0 + value.w; 98: vec3 Xp_Y_XYZp; 99: Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 ); 100: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y; 101: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z; 102: vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM; 103: return vec4( max( vRGB, 0.0 ), 1.0 ); 104: } 105: vec4 mapTexelToLinear( vec4 value ) { return sRGBToLinear( value ); } 106: vec4 matcapTexelToLinear( vec4 value ) { return GammaToLinear( value, float( GAMMA_FACTOR ) ); } 107: vec4 envMapTexelToLinear( vec4 value ) { return GammaToLinear( value, float( GAMMA_FACTOR ) ); } 108: vec4 emissiveMapTexelToLinear( vec4 value ) { return GammaToLinear( value, float( GAMMA_FACTOR ) ); } 109: vec4 linearToOutputTexel( vec4 value ) { return LinearToGamma( value, float( GAMMA_FACTOR ) ); } 110: 111: #define PHYSICAL 112: uniform vec3 diffuse; 113: uniform vec3 emissive; 114: uniform float roughness; 115: uniform float metalness; 116: uniform float opacity; 117: #ifndef STANDARD 118: uniform float clearCoat; 119: uniform float clearCoatRoughness; 120: #endif 121: varying vec3 vViewPosition; 122: #ifndef FLAT_SHADED 123: varying vec3 vNormal; 124: #endif 125: #define PI 3.14159265359 126: #define PI2 6.28318530718 127: #define PI_HALF 1.5707963267949 128: #define RECIPROCAL_PI 0.31830988618 129: #define RECIPROCAL_PI2 0.15915494 130: #define LOG2 1.442695 131: #define EPSILON 1e-6 132: #define saturate(a) clamp( a, 0.0, 1.0 ) 133: #define whiteCompliment(a) ( 1.0 - saturate( a ) ) 134: float pow2( const in float x ) { return x*x; } 135: float pow3( const in float x ) { return x*x*x; } 136: float pow4( const in float x ) { float x2 = x*x; return x2*x2; } 137: float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); } 138: highp float rand( const in vec2 uv ) { 139: const highp float a = 12.9898, b = 78.233, c = 43758.5453; 140: highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI ); 141: return fract(sin(sn) * c); 142: } 143: struct IncidentLight { 144: vec3 color; 145: vec3 direction; 146: bool visible; 147: }; 148: struct ReflectedLight { 149: vec3 directDiffuse; 150: vec3 directSpecular; 151: vec3 indirectDiffuse; 152: vec3 indirectSpecular; 153: }; 154: struct GeometricContext { 155: vec3 position; 156: vec3 normal; 157: vec3 viewDir; 158: }; 159: vec3 transformDirection( in vec3 dir, in mat4 matrix ) { 160: return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); 161: } 162: vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) { 163: return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); 164: } 165: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { 166: float distance = dot( planeNormal, point - pointOnPlane ); 167: return - distance * planeNormal + point; 168: } 169: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { 170: return sign( dot( point - pointOnPlane, planeNormal ) ); 171: } 172: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { 173: return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine; 174: } 175: mat3 transposeMat3( const in mat3 m ) { 176: mat3 tmp; 177: tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x ); 178: tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y ); 179: tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z ); 180: return tmp; 181: } 182: float linearToRelativeLuminance( const in vec3 color ) { 183: vec3 weights = vec3( 0.2126, 0.7152, 0.0722 ); 184: return dot( weights, color.rgb ); 185: } 186: vec3 packNormalToRGB( const in vec3 normal ) { 187: return normalize( normal ) * 0.5 + 0.5; 188: } 189: vec3 unpackRGBToNormal( const in vec3 rgb ) { 190: return 2.0 * rgb.xyz - 1.0; 191: } 192: const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.; 193: const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. ); 194: const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. ); 195: const float ShiftRight8 = 1. / 256.; 196: vec4 packDepthToRGBA( const in float v ) { 197: vec4 r = vec4( fract( v * PackFactors ), v ); 198: r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale; 199: } 200: float unpackRGBAToDepth( const in vec4 v ) { 201: return dot( v, UnpackFactors ); 202: } 203: float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) { 204: return ( viewZ + near ) / ( near - far ); 205: } 206: float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) { 207: return linearClipZ * ( near - far ) - near; 208: } 209: float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) { 210: return (( near + viewZ ) * far ) / (( far - near ) * viewZ ); 211: } 212: float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) { 213: return ( near * far ) / ( ( far - near ) * invClipZ - far ); 214: } 215: #if defined( DITHERING ) 216: vec3 dithering( vec3 color ) { 217: float grid_position = rand( gl_FragCoord.xy ); 218: vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 ); 219: dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position ); 220: return color + dither_shift_RGB; 221: } 222: #endif 223: #ifdef USE_COLOR 224: varying vec3 vColor; 225: #endif 226: #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP ) 227: varying vec2 vUv; 228: #endif 229: #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) 230: varying vec2 vUv2; 231: #endif 232: #ifdef USE_MAP 233: uniform sampler2D map; 234: #endif 235: #ifdef USE_ALPHAMAP 236: uniform sampler2D alphaMap; 237: #endif 238: #ifdef USE_AOMAP 239: uniform sampler2D aoMap; 240: uniform float aoMapIntensity; 241: #endif 242: #ifdef USE_LIGHTMAP 243: uniform sampler2D lightMap; 244: uniform float lightMapIntensity; 245: #endif 246: #ifdef USE_EMISSIVEMAP 247: uniform sampler2D emissiveMap; 248: #endif 249: float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) { 250: #if defined ( PHYSICALLY_CORRECT_LIGHTS ) 251: float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 ); 252: if( cutoffDistance > 0.0 ) { 253: distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) ); 254: } 255: return distanceFalloff; 256: #else 257: if( cutoffDistance > 0.0 && decayExponent > 0.0 ) { 258: return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent ); 259: } 260: return 1.0; 261: #endif 262: } 263: vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) { 264: return RECIPROCAL_PI * diffuseColor; 265: } 266: vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) { 267: float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH ); 268: return ( 1.0 - specularColor ) * fresnel + specularColor; 269: } 270: float G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) { 271: float a2 = pow2( alpha ); 272: float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); 273: float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); 274: return 1.0 / ( gl * gv ); 275: } 276: float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) { 277: float a2 = pow2( alpha ); 278: float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); 279: float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); 280: return 0.5 / max( gv + gl, EPSILON ); 281: } 282: float D_GGX( const in float alpha, const in float dotNH ) { 283: float a2 = pow2( alpha ); 284: float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; 285: return RECIPROCAL_PI * a2 / pow2( denom ); 286: } 287: vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) { 288: float alpha = pow2( roughness ); 289: vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); 290: float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); 291: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 292: float dotNH = saturate( dot( geometry.normal, halfDir ) ); 293: float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); 294: vec3 F = F_Schlick( specularColor, dotLH ); 295: float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV ); 296: float D = D_GGX( alpha, dotNH ); 297: return F * ( G * D ); 298: } 299: vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) { 300: const float LUT_SIZE = 64.0; 301: const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE; 302: const float LUT_BIAS = 0.5 / LUT_SIZE; 303: float dotNV = saturate( dot( N, V ) ); 304: vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) ); 305: uv = uv * LUT_SCALE + LUT_BIAS; 306: return uv; 307: } 308: float LTC_ClippedSphereFormFactor( const in vec3 f ) { 309: float l = length( f ); 310: return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 ); 311: } 312: vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) { 313: float x = dot( v1, v2 ); 314: float y = abs( x ); 315: float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y; 316: float b = 3.4175940 + ( 4.1616724 + y ) * y; 317: float v = a / b; 318: float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v; 319: return cross( v1, v2 ) * theta_sintheta; 320: } 321: vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) { 322: vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ]; 323: vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ]; 324: vec3 lightNormal = cross( v1, v2 ); 325: if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 ); 326: vec3 T1, T2; 327: T1 = normalize( V - N * dot( V, N ) ); 328: T2 = - cross( N, T1 ); 329: mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) ); 330: vec3 coords[ 4 ]; 331: coords[ 0 ] = mat * ( rectCoords[ 0 ] - P ); 332: coords[ 1 ] = mat * ( rectCoords[ 1 ] - P ); 333: coords[ 2 ] = mat * ( rectCoords[ 2 ] - P ); 334: coords[ 3 ] = mat * ( rectCoords[ 3 ] - P ); 335: coords[ 0 ] = normalize( coords[ 0 ] ); 336: coords[ 1 ] = normalize( coords[ 1 ] ); 337: coords[ 2 ] = normalize( coords[ 2 ] ); 338: coords[ 3 ] = normalize( coords[ 3 ] ); 339: vec3 vectorFormFactor = vec3( 0.0 ); 340: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] ); 341: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] ); 342: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] ); 343: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] ); 344: float result = LTC_ClippedSphereFormFactor( vectorFormFactor ); 345: return vec3( result ); 346: } 347: vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) { 348: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 349: const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); 350: const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); 351: vec4 r = roughness * c0 + c1; 352: float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; 353: vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; 354: return specularColor * AB.x + AB.y; 355: } 356: float G_BlinnPhong_Implicit( ) { 357: return 0.25; 358: } 359: float D_BlinnPhong( const in float shininess, const in float dotNH ) { 360: return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); 361: } 362: vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) { 363: vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); 364: float dotNH = saturate( dot( geometry.normal, halfDir ) ); 365: float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); 366: vec3 F = F_Schlick( specularColor, dotLH ); 367: float G = G_BlinnPhong_Implicit( ); 368: float D = D_BlinnPhong( shininess, dotNH ); 369: return F * ( G * D ); 370: } 371: float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) { 372: return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 ); 373: } 374: float BlinnExponentToGGXRoughness( const in float blinnExponent ) { 375: return sqrt( 2.0 / ( blinnExponent + 2.0 ) ); 376: } 377: #ifdef ENVMAP_TYPE_CUBE_UV 378: #define cubeUV_textureSize (1024.0) 379: int getFaceFromDirection(vec3 direction) { 380: vec3 absDirection = abs(direction); 381: int face = -1; 382: if( absDirection.x > absDirection.z ) { 383: if(absDirection.x > absDirection.y ) 384: face = direction.x > 0.0 ? 0 : 3; 385: else 386: face = direction.y > 0.0 ? 1 : 4; 387: } 388: else { 389: if(absDirection.z > absDirection.y ) 390: face = direction.z > 0.0 ? 2 : 5; 391: else 392: face = direction.y > 0.0 ? 1 : 4; 393: } 394: return face; 395: } 396: #define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0) 397: #define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0)) 398: vec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) { 399: float scale = exp2(cubeUV_maxLods1 - roughnessLevel); 400: float dxRoughness = dFdx(roughness); 401: float dyRoughness = dFdy(roughness); 402: vec3 dx = dFdx( vec * scale * dxRoughness ); 403: vec3 dy = dFdy( vec * scale * dyRoughness ); 404: float d = max( dot( dx, dx ), dot( dy, dy ) ); 405: d = clamp(d, 1.0, cubeUV_rangeClamp); 406: float mipLevel = 0.5 * log2(d); 407: return vec2(floor(mipLevel), fract(mipLevel)); 408: } 409: #define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0) 410: #define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize) 411: vec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) { 412: mipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel; 413: float a = 16.0 * cubeUV_rcpTextureSize; 414: vec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) ); 415: vec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed; 416: float powScale = exp2_packed.x * exp2_packed.y; 417: float scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25; 418: float mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x; 419: bool bRes = mipLevel == 0.0; 420: scale = bRes && (scale < a) ? a : scale; 421: vec3 r; 422: vec2 offset; 423: int face = getFaceFromDirection(direction); 424: float rcpPowScale = 1.0 / powScale; 425: if( face == 0) { 426: r = vec3(direction.x, -direction.z, direction.y); 427: offset = vec2(0.0+mipOffset,0.75 * rcpPowScale); 428: offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y; 429: } 430: else if( face == 1) { 431: r = vec3(direction.y, direction.x, direction.z); 432: offset = vec2(scale+mipOffset, 0.75 * rcpPowScale); 433: offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y; 434: } 435: else if( face == 2) { 436: r = vec3(direction.z, direction.x, direction.y); 437: offset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale); 438: offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y; 439: } 440: else if( face == 3) { 441: r = vec3(direction.x, direction.z, direction.y); 442: offset = vec2(0.0+mipOffset,0.5 * rcpPowScale); 443: offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y; 444: } 445: else if( face == 4) { 446: r = vec3(direction.y, direction.x, -direction.z); 447: offset = vec2(scale+mipOffset, 0.5 * rcpPowScale); 448: offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y; 449: } 450: else { 451: r = vec3(direction.z, -direction.x, direction.y); 452: offset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale); 453: offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y; 454: } 455: r = normalize(r); 456: float texelOffset = 0.5 * cubeUV_rcpTextureSize; 457: vec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5; 458: vec2 base = offset + vec2( texelOffset ); 459: return base + s * ( scale - 2.0 * texelOffset ); 460: } 461: #define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0) 462: vec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) { 463: float roughnessVal = roughness* cubeUV_maxLods3; 464: float r1 = floor(roughnessVal); 465: float r2 = r1 + 1.0; 466: float t = fract(roughnessVal); 467: vec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness); 468: float s = mipInfo.y; 469: float level0 = mipInfo.x; 470: float level1 = level0 + 1.0; 471: level1 = level1 > 5.0 ? 5.0 : level1; 472: level0 += min( floor( s + 0.5 ), 5.0 ); 473: vec2 uv_10 = getCubeUV(reflectedDirection, r1, level0); 474: vec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10)); 475: vec2 uv_20 = getCubeUV(reflectedDirection, r2, level0); 476: vec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20)); 477: vec4 result = mix(color10, color20, t); 478: return vec4(result.rgb, 1.0); 479: } 480: #endif 481: #if defined( USE_ENVMAP ) || defined( PHYSICAL ) 482: uniform float reflectivity; 483: uniform float envMapIntensity; 484: #endif 485: #ifdef USE_ENVMAP 486: #if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) ) 487: varying vec3 vWorldPosition; 488: #endif 489: #ifdef ENVMAP_TYPE_CUBE 490: uniform samplerCube envMap; 491: #else 492: uniform sampler2D envMap; 493: #endif 494: uniform float flipEnvMap; 495: uniform int maxMipLevel; 496: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL ) 497: uniform float refractionRatio; 498: #else 499: varying vec3 vReflect; 500: #endif 501: #endif 502: #if defined( USE_ENVMAP ) && defined( PHYSICAL ) 503: vec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) { 504: vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix ); 505: #ifdef ENVMAP_TYPE_CUBE 506: vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz ); 507: #ifdef TEXTURE_LOD_EXT 508: vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) ); 509: #else 510: vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) ); 511: #endif 512: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 513: #elif defined( ENVMAP_TYPE_CUBE_UV ) 514: vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz ); 515: vec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 ); 516: #else 517: vec4 envMapColor = vec4( 0.0 ); 518: #endif 519: return PI * envMapColor.rgb * envMapIntensity; 520: } 521: float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) { 522: float maxMIPLevelScalar = float( maxMIPLevel ); 523: float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 ); 524: return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar ); 525: } 526: vec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) { 527: #ifdef ENVMAP_MODE_REFLECTION 528: vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal ); 529: #else 530: vec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio ); 531: #endif 532: reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); 533: float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel ); 534: #ifdef ENVMAP_TYPE_CUBE 535: vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz ); 536: #ifdef TEXTURE_LOD_EXT 537: vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel ); 538: #else 539: vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel ); 540: #endif 541: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 542: #elif defined( ENVMAP_TYPE_CUBE_UV ) 543: vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz ); 544: vec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent )); 545: #elif defined( ENVMAP_TYPE_EQUIREC ) 546: vec2 sampleUV; 547: sampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; 548: sampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5; 549: #ifdef TEXTURE_LOD_EXT 550: vec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel ); 551: #else 552: vec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel ); 553: #endif 554: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 555: #elif defined( ENVMAP_TYPE_SPHERE ) 556: vec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) ); 557: #ifdef TEXTURE_LOD_EXT 558: vec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel ); 559: #else 560: vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel ); 561: #endif 562: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 563: #endif 564: return envMapColor.rgb * envMapIntensity; 565: } 566: #endif 567: #ifdef USE_FOG 568: uniform vec3 fogColor; 569: varying float fogDepth; 570: #ifdef FOG_EXP2 571: uniform float fogDensity; 572: #else 573: uniform float fogNear; 574: uniform float fogFar; 575: #endif 576: #endif 577: uniform vec3 ambientLightColor; 578: vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { 579: vec3 irradiance = ambientLightColor; 580: #ifndef PHYSICALLY_CORRECT_LIGHTS 581: irradiance *= PI; 582: #endif 583: return irradiance; 584: } 585: #if 1 > 0 586: struct DirectionalLight { 587: vec3 direction; 588: vec3 color; 589: int shadow; 590: float shadowBias; 591: float shadowRadius; 592: vec2 shadowMapSize; 593: }; 594: uniform DirectionalLight directionalLights[ 1 ]; 595: void getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) { 596: directLight.color = directionalLight.color; 597: directLight.direction = directionalLight.direction; 598: directLight.visible = true; 599: } 600: #endif 601: #if 4 > 0 602: struct PointLight { 603: vec3 position; 604: vec3 color; 605: float distance; 606: float decay; 607: int shadow; 608: float shadowBias; 609: float shadowRadius; 610: vec2 shadowMapSize; 611: float shadowCameraNear; 612: float shadowCameraFar; 613: }; 614: uniform PointLight pointLights[ 4 ]; 615: void getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) { 616: vec3 lVector = pointLight.position - geometry.position; 617: directLight.direction = normalize( lVector ); 618: float lightDistance = length( lVector ); 619: directLight.color = pointLight.color; 620: directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay ); 621: directLight.visible = ( directLight.color != vec3( 0.0 ) ); 622: } 623: #endif 624: #if 1 > 0 625: struct SpotLight { 626: vec3 position; 627: vec3 direction; 628: vec3 color; 629: float distance; 630: float decay; 631: float coneCos; 632: float penumbraCos; 633: int shadow; 634: float shadowBias; 635: float shadowRadius; 636: vec2 shadowMapSize; 637: }; 638: uniform SpotLight spotLights[ 1 ]; 639: void getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) { 640: vec3 lVector = spotLight.position - geometry.position; 641: directLight.direction = normalize( lVector ); 642: float lightDistance = length( lVector ); 643: float angleCos = dot( directLight.direction, spotLight.direction ); 644: if ( angleCos > spotLight.coneCos ) { 645: float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos ); 646: directLight.color = spotLight.color; 647: directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay ); 648: directLight.visible = true; 649: } else { 650: directLight.color = vec3( 0.0 ); 651: directLight.visible = false; 652: } 653: } 654: #endif 655: #if 0 > 0 656: struct RectAreaLight { 657: vec3 color; 658: vec3 position; 659: vec3 halfWidth; 660: vec3 halfHeight; 661: }; 662: uniform sampler2D ltc_1; uniform sampler2D ltc_2; 663: uniform RectAreaLight rectAreaLights[ 0 ]; 664: #endif 665: #if 1 > 0 666: struct HemisphereLight { 667: vec3 direction; 668: vec3 skyColor; 669: vec3 groundColor; 670: }; 671: uniform HemisphereLight hemisphereLights[ 1 ]; 672: vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { 673: float dotNL = dot( geometry.normal, hemiLight.direction ); 674: float hemiDiffuseWeight = 0.5 * dotNL + 0.5; 675: vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); 676: #ifndef PHYSICALLY_CORRECT_LIGHTS 677: irradiance *= PI; 678: #endif 679: return irradiance; 680: } 681: #endif 682: struct PhysicalMaterial { 683: vec3 diffuseColor; 684: float specularRoughness; 685: vec3 specularColor; 686: #ifndef STANDARD 687: float clearCoat; 688: float clearCoatRoughness; 689: #endif 690: }; 691: #define MAXIMUM_SPECULAR_COEFFICIENT 0.16 692: #define DEFAULT_SPECULAR_COEFFICIENT 0.04 693: float clearCoatDHRApprox( const in float roughness, const in float dotNL ) { 694: return DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) ); 695: } 696: #if 0 > 0 697: void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 698: vec3 normal = geometry.normal; 699: vec3 viewDir = geometry.viewDir; 700: vec3 position = geometry.position; 701: vec3 lightPos = rectAreaLight.position; 702: vec3 halfWidth = rectAreaLight.halfWidth; 703: vec3 halfHeight = rectAreaLight.halfHeight; 704: vec3 lightColor = rectAreaLight.color; 705: float roughness = material.specularRoughness; 706: vec3 rectCoords[ 4 ]; 707: rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; rectCoords[ 1 ] = lightPos - halfWidth - halfHeight; 708: rectCoords[ 2 ] = lightPos - halfWidth + halfHeight; 709: rectCoords[ 3 ] = lightPos + halfWidth + halfHeight; 710: vec2 uv = LTC_Uv( normal, viewDir, roughness ); 711: vec4 t1 = texture2D( ltc_1, uv ); 712: vec4 t2 = texture2D( ltc_2, uv ); 713: mat3 mInv = mat3( 714: vec3( t1.x, 0, t1.y ), 715: vec3( 0, 1, 0 ), 716: vec3( t1.z, 0, t1.w ) 717: ); 718: vec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y ); 719: reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords ); 720: reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords ); 721: } 722: #endif 723: void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 724: float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); 725: vec3 irradiance = dotNL * directLight.color; 726: #ifndef PHYSICALLY_CORRECT_LIGHTS 727: irradiance *= PI; 728: #endif 729: #ifndef STANDARD 730: float clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL ); 731: #else 732: float clearCoatDHR = 0.0; 733: #endif 734: reflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); 735: reflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); 736: #ifndef STANDARD 737: reflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness ); 738: #endif 739: } 740: void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 741: reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); 742: } 743: void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 744: #ifndef STANDARD 745: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 746: float dotNL = dotNV; 747: float clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL ); 748: #else 749: float clearCoatDHR = 0.0; 750: #endif 751: reflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness ); 752: #ifndef STANDARD 753: reflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness ); 754: #endif 755: } 756: #define RE_Direct RE_Direct_Physical 757: #define RE_Direct_RectArea RE_Direct_RectArea_Physical 758: #define RE_IndirectDiffuse RE_IndirectDiffuse_Physical 759: #define RE_IndirectSpecular RE_IndirectSpecular_Physical 760: #define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness ) 761: #define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness ) 762: float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) { 763: return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); 764: } 765: #ifdef USE_SHADOWMAP 766: #if 1 > 0 767: uniform sampler2D directionalShadowMap[ 1 ]; 768: varying vec4 vDirectionalShadowCoord[ 1 ]; 769: #endif 770: #if 1 > 0 771: uniform sampler2D spotShadowMap[ 1 ]; 772: varying vec4 vSpotShadowCoord[ 1 ]; 773: #endif 774: #if 4 > 0 775: uniform sampler2D pointShadowMap[ 4 ]; 776: varying vec4 vPointShadowCoord[ 4 ]; 777: #endif 778: float texture2DCompare( sampler2D depths, vec2 uv, float compare ) { 779: return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) ); 780: } 781: float texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) { 782: const vec2 offset = vec2( 0.0, 1.0 ); 783: vec2 texelSize = vec2( 1.0 ) / size; 784: vec2 centroidUV = floor( uv * size + 0.5 ) / size; 785: float lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare ); 786: float lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare ); 787: float rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare ); 788: float rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare ); 789: vec2 f = fract( uv * size + 0.5 ); 790: float a = mix( lb, lt, f.y ); 791: float b = mix( rb, rt, f.y ); 792: float c = mix( a, b, f.x ); 793: return c; 794: } 795: float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) { 796: float shadow = 1.0; 797: shadowCoord.xyz /= shadowCoord.w; 798: shadowCoord.z += shadowBias; 799: bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 ); 800: bool inFrustum = all( inFrustumVec ); 801: bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 ); 802: bool frustumTest = all( frustumTestVec ); 803: if ( frustumTest ) { 804: #if defined( SHADOWMAP_TYPE_PCF ) 805: vec2 texelSize = vec2( 1.0 ) / shadowMapSize; 806: float dx0 = - texelSize.x * shadowRadius; 807: float dy0 = - texelSize.y * shadowRadius; 808: float dx1 = + texelSize.x * shadowRadius; 809: float dy1 = + texelSize.y * shadowRadius; 810: shadow = ( 811: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) + 812: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) + 813: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) + 814: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) + 815: texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) + 816: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) + 817: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) + 818: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) + 819: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z ) 820: ) * ( 1.0 / 9.0 ); 821: #elif defined( SHADOWMAP_TYPE_PCF_SOFT ) 822: vec2 texelSize = vec2( 1.0 ) / shadowMapSize; 823: float dx0 = - texelSize.x * shadowRadius; 824: float dy0 = - texelSize.y * shadowRadius; 825: float dx1 = + texelSize.x * shadowRadius; 826: float dy1 = + texelSize.y * shadowRadius; 827: shadow = ( 828: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) + 829: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) + 830: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) + 831: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) + 832: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) + 833: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) + 834: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) + 835: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) + 836: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z ) 837: ) * ( 1.0 / 9.0 ); 838: #else 839: shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ); 840: #endif 841: } 842: return shadow; 843: } 844: vec2 cubeToUV( vec3 v, float texelSizeY ) { 845: vec3 absV = abs( v ); 846: float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) ); 847: absV *= scaleToCube; 848: v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY ); 849: vec2 planar = v.xy; 850: float almostATexel = 1.5 * texelSizeY; 851: float almostOne = 1.0 - almostATexel; 852: if ( absV.z >= almostOne ) { 853: if ( v.z > 0.0 ) 854: planar.x = 4.0 - v.x; 855: } else if ( absV.x >= almostOne ) { 856: float signX = sign( v.x ); 857: planar.x = v.z * signX + 2.0 * signX; 858: } else if ( absV.y >= almostOne ) { 859: float signY = sign( v.y ); 860: planar.x = v.x + 2.0 * signY + 2.0; 861: planar.y = v.z * signY - 2.0; 862: } 863: return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 ); 864: } 865: float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) { 866: vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) ); 867: vec3 lightToPosition = shadowCoord.xyz; 868: float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); dp += shadowBias; 869: vec3 bd3D = normalize( lightToPosition ); 870: #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) 871: vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y; 872: return ( 873: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) + 874: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) + 875: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) + 876: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) + 877: texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) + 878: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) + 879: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) + 880: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) + 881: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp ) 882: ) * ( 1.0 / 9.0 ); 883: #else 884: return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ); 885: #endif 886: } 887: #endif 888: #ifdef USE_BUMPMAP 889: uniform sampler2D bumpMap; 890: uniform float bumpScale; 891: vec2 dHdxy_fwd() { 892: vec2 dSTdx = dFdx( vUv ); 893: vec2 dSTdy = dFdy( vUv ); 894: float Hll = bumpScale * texture2D( bumpMap, vUv ).x; 895: float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll; 896: float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll; 897: return vec2( dBx, dBy ); 898: } 899: vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) { 900: vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) ); 901: vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) ); 902: vec3 vN = surf_norm; 903: vec3 R1 = cross( vSigmaY, vN ); 904: vec3 R2 = cross( vN, vSigmaX ); 905: float fDet = dot( vSigmaX, R1 ); 906: fDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 907: vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 ); 908: return normalize( abs( fDet ) * surf_norm - vGrad ); 909: } 910: #endif 911: #ifdef USE_NORMALMAP 912: uniform sampler2D normalMap; 913: uniform vec2 normalScale; 914: #ifdef OBJECTSPACE_NORMALMAP 915: uniform mat3 normalMatrix; 916: #else 917: vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { 918: vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) ); 919: vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) ); 920: vec2 st0 = dFdx( vUv.st ); 921: vec2 st1 = dFdy( vUv.st ); 922: float scale = sign( st1.t * st0.s - st0.t * st1.s ); 923: vec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale ); 924: vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale ); 925: vec3 N = normalize( surf_norm ); 926: mat3 tsn = mat3( S, T, N ); 927: vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; 928: mapN.xy *= normalScale; 929: mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 930: return normalize( tsn * mapN ); 931: } 932: #endif 933: #endif 934: #ifdef USE_ROUGHNESSMAP 935: uniform sampler2D roughnessMap; 936: #endif 937: #ifdef USE_METALNESSMAP 938: uniform sampler2D metalnessMap; 939: #endif 940: #if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT ) 941: uniform float logDepthBufFC; 942: varying float vFragDepth; 943: #endif 944: #if 0 > 0 945: #if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP ) 946: varying vec3 vViewPosition; 947: #endif 948: uniform vec4 clippingPlanes[ 0 ]; 949: #endif 950: void main() { 951: #if 0 > 0 952: vec4 plane; 953: 954: #if 0 < 0 955: bool clipped = true; 956: 957: if ( clipped ) discard; 958: #endif 959: #endif 960: vec4 diffuseColor = vec4( diffuse, opacity ); 961: ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); 962: vec3 totalEmissiveRadiance = emissive; 963: #if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT ) 964: gl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5; 965: #endif 966: #ifdef USE_MAP 967: vec4 texelColor = texture2D( map, vUv ); 968: texelColor = mapTexelToLinear( texelColor ); 969: diffuseColor *= texelColor; 970: #endif 971: #ifdef USE_COLOR 972: diffuseColor.rgb *= vColor; 973: #endif 974: #ifdef USE_ALPHAMAP 975: diffuseColor.a *= texture2D( alphaMap, vUv ).g; 976: #endif 977: #ifdef ALPHATEST 978: if ( diffuseColor.a < ALPHATEST ) discard; 979: #endif 980: float roughnessFactor = roughness; 981: #ifdef USE_ROUGHNESSMAP 982: vec4 texelRoughness = texture2D( roughnessMap, vUv ); 983: roughnessFactor *= texelRoughness.g; 984: #endif 985: float metalnessFactor = metalness; 986: #ifdef USE_METALNESSMAP 987: vec4 texelMetalness = texture2D( metalnessMap, vUv ); 988: metalnessFactor *= texelMetalness.b; 989: #endif 990: #ifdef FLAT_SHADED 991: vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) ); 992: vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) ); 993: vec3 normal = normalize( cross( fdx, fdy ) ); 994: #else 995: vec3 normal = normalize( vNormal ); 996: #ifdef DOUBLE_SIDED 997: normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 998: #endif 999: #endif 1000: #ifdef USE_NORMALMAP 1001: #ifdef OBJECTSPACE_NORMALMAP 1002: normal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; 1003: #ifdef FLIP_SIDED 1004: normal = - normal; 1005: #endif 1006: #ifdef DOUBLE_SIDED 1007: normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 1008: #endif 1009: normal = normalize( normalMatrix * normal ); 1010: #else 1011: normal = perturbNormal2Arb( -vViewPosition, normal ); 1012: #endif 1013: #elif defined( USE_BUMPMAP ) 1014: normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() ); 1015: #endif 1016: #ifdef USE_EMISSIVEMAP 1017: vec4 emissiveColor = texture2D( emissiveMap, vUv ); 1018: emissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb; 1019: totalEmissiveRadiance *= emissiveColor.rgb; 1020: #endif 1021: PhysicalMaterial material; 1022: material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); 1023: material.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 ); 1024: #ifdef STANDARD 1025: material.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor ); 1026: #else 1027: material.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor ); 1028: material.clearCoat = saturate( clearCoat ); material.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 ); 1029: #endif 1030: 1031: GeometricContext geometry; 1032: geometry.position = - vViewPosition; 1033: geometry.normal = normal; 1034: geometry.viewDir = normalize( vViewPosition ); 1035: IncidentLight directLight; 1036: #if ( 4 > 0 ) && defined( RE_Direct ) 1037: PointLight pointLight; 1038: 1039: pointLight = pointLights[ 0 ]; 1040: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1041: #ifdef USE_SHADOWMAP 1042: directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ 0 ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ 0 ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; 1043: #endif 1044: RE_Direct( directLight, geometry, material, reflectedLight ); 1045: 1046: pointLight = pointLights[ 1 ]; 1047: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1048: #ifdef USE_SHADOWMAP 1049: directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ 1 ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ 1 ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; 1050: #endif 1051: RE_Direct( directLight, geometry, material, reflectedLight ); 1052: 1053: pointLight = pointLights[ 2 ]; 1054: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1055: #ifdef USE_SHADOWMAP 1056: directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ 2 ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ 2 ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; 1057: #endif 1058: RE_Direct( directLight, geometry, material, reflectedLight ); 1059: 1060: pointLight = pointLights[ 3 ]; 1061: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1062: #ifdef USE_SHADOWMAP 1063: directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ 3 ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ 3 ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; 1064: #endif 1065: RE_Direct( directLight, geometry, material, reflectedLight ); 1066: 1067: #endif 1068: #if ( 1 > 0 ) && defined( RE_Direct ) 1069: SpotLight spotLight; 1070: 1071: spotLight = spotLights[ 0 ]; 1072: getSpotDirectLightIrradiance( spotLight, geometry, directLight ); 1073: #ifdef USE_SHADOWMAP 1074: directLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ 0 ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ 0 ] ) : 1.0; 1075: #endif 1076: RE_Direct( directLight, geometry, material, reflectedLight ); 1077: 1078: #endif 1079: #if ( 1 > 0 ) && defined( RE_Direct ) 1080: DirectionalLight directionalLight; 1081: 1082: directionalLight = directionalLights[ 0 ]; 1083: getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight ); 1084: #ifdef USE_SHADOWMAP 1085: directLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ 0 ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ 0 ] ) : 1.0; 1086: #endif 1087: RE_Direct( directLight, geometry, material, reflectedLight ); 1088: 1089: #endif 1090: #if ( 0 > 0 ) && defined( RE_Direct_RectArea ) 1091: RectAreaLight rectAreaLight; 1092: 1093: #endif 1094: #if defined( RE_IndirectDiffuse ) 1095: vec3 irradiance = getAmbientLightIrradiance( ambientLightColor ); 1096: #if ( 1 > 0 ) 1097: 1098: irradiance += getHemisphereLightIrradiance( hemisphereLights[ 0 ], geometry ); 1099: 1100: #endif 1101: #endif 1102: #if defined( RE_IndirectSpecular ) 1103: vec3 radiance = vec3( 0.0 ); 1104: vec3 clearCoatRadiance = vec3( 0.0 ); 1105: #endif 1106: #if defined( RE_IndirectDiffuse ) 1107: #ifdef USE_LIGHTMAP 1108: vec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; 1109: #ifndef PHYSICALLY_CORRECT_LIGHTS 1110: lightMapIrradiance *= PI; 1111: #endif 1112: irradiance += lightMapIrradiance; 1113: #endif 1114: #if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV ) 1115: irradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel ); 1116: #endif 1117: #endif 1118: #if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular ) 1119: radiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel ); 1120: #ifndef STANDARD 1121: clearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel ); 1122: #endif 1123: #endif 1124: #if defined( RE_IndirectDiffuse ) 1125: RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight ); 1126: #endif 1127: #if defined( RE_IndirectSpecular ) 1128: RE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight ); 1129: #endif 1130: #ifdef USE_AOMAP 1131: float ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0; 1132: reflectedLight.indirectDiffuse *= ambientOcclusion; 1133: #if defined( USE_ENVMAP ) && defined( PHYSICAL ) 1134: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 1135: reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness ); 1136: #endif 1137: #endif 1138: vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; 1139: gl_FragColor = vec4( outgoingLight, diffuseColor.a ); 1140: #if defined( TONE_MAPPING ) 1141: gl_FragColor.rgb = toneMapping( gl_FragColor.rgb ); 1142: #endif 1143: gl_FragColor = linearToOutputTexel( gl_FragColor ); 1144: #ifdef USE_FOG 1145: #ifdef FOG_EXP2 1146: float fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) ); 1147: #else 1148: float fogFactor = smoothstep( fogNear, fogFar, fogDepth ); 1149: #endif 1150: gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor ); 1151: #endif 1152: #ifdef PREMULTIPLIED_ALPHA 1153: gl_FragColor.rgb *= gl_FragColor.a; 1154: #endif 1155: #if defined( DITHERING ) 1156: gl_FragColor.rgb = dithering( gl_FragColor.rgb ); 1157: #endif 1158: } three.min.js?v=100:53 THREE.WebGLShader: gl.getShaderInfoLog() fragment WARNING: 0:340: Overflow in implicit constant conversion, minimum range for lowp float is (-2,2) 1: #extension GL_OES_standard_derivatives : enable 2: #extension GL_EXT_shader_texture_lod : enable 3: precision highp float; 4: precision highp int; 5: #define SHADER_NAME MeshStandardMaterial 6: #define STANDARD 7: #define GAMMA_FACTOR 2 8: #define USE_MAP 9: #define USE_ENVMAP 10: #define ENVMAP_TYPE_CUBE 11: #define ENVMAP_MODE_REFLECTION 12: #define ENVMAP_BLENDING_MULTIPLY 13: #define USE_AOMAP 14: #define USE_NORMALMAP 15: #define USE_ROUGHNESSMAP 16: #define USE_METALNESSMAP 17: #define USE_SHADOWMAP 18: #define SHADOWMAP_TYPE_PCF_SOFT 19: #define TEXTURE_LOD_EXT 20: uniform mat4 viewMatrix; 21: uniform vec3 cameraPosition; 22: #define TONE_MAPPING 23: #ifndef saturate 24: #define saturate(a) clamp( a, 0.0, 1.0 ) 25: #endif 26: uniform float toneMappingExposure; 27: uniform float toneMappingWhitePoint; 28: vec3 LinearToneMapping( vec3 color ) { 29: return toneMappingExposure * color; 30: } 31: vec3 ReinhardToneMapping( vec3 color ) { 32: color *= toneMappingExposure; 33: return saturate( color / ( vec3( 1.0 ) + color ) ); 34: } 35: #define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) ) 36: vec3 Uncharted2ToneMapping( vec3 color ) { 37: color *= toneMappingExposure; 38: return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) ); 39: } 40: vec3 OptimizedCineonToneMapping( vec3 color ) { 41: color *= toneMappingExposure; 42: color = max( vec3( 0.0 ), color - 0.004 ); 43: return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) ); 44: } 45: vec3 ACESFilmicToneMapping( vec3 color ) { 46: color *= toneMappingExposure; 47: return saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) ); 48: } 49: vec3 toneMapping( vec3 color ) { return LinearToneMapping( color ); } 50: 51: vec4 LinearToLinear( in vec4 value ) { 52: return value; 53: } 54: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) { 55: return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a ); 56: } 57: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) { 58: return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a ); 59: } 60: vec4 sRGBToLinear( in vec4 value ) { 61: return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a ); 62: } 63: vec4 LinearTosRGB( in vec4 value ) { 64: return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); 65: } 66: vec4 RGBEToLinear( in vec4 value ) { 67: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 ); 68: } 69: vec4 LinearToRGBE( in vec4 value ) { 70: float maxComponent = max( max( value.r, value.g ), value.b ); 71: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 ); 72: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 ); 73: } 74: vec4 RGBMToLinear( in vec4 value, in float maxRange ) { 75: return vec4( value.rgb * value.a * maxRange, 1.0 ); 76: } 77: vec4 LinearToRGBM( in vec4 value, in float maxRange ) { 78: float maxRGB = max( value.r, max( value.g, value.b ) ); 79: float M = clamp( maxRGB / maxRange, 0.0, 1.0 ); 80: M = ceil( M * 255.0 ) / 255.0; 81: return vec4( value.rgb / ( M * maxRange ), M ); 82: } 83: vec4 RGBDToLinear( in vec4 value, in float maxRange ) { 84: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 ); 85: } 86: vec4 LinearToRGBD( in vec4 value, in float maxRange ) { 87: float maxRGB = max( value.r, max( value.g, value.b ) ); 88: float D = max( maxRange / maxRGB, 1.0 ); 89: D = min( floor( D ) / 255.0, 1.0 ); 90: return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D ); 91: } 92: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 ); 93: vec4 LinearToLogLuv( in vec4 value ) { 94: vec3 Xp_Y_XYZp = value.rgb * cLogLuvM; 95: Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) ); 96: vec4 vResult; 97: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z; 98: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0; 99: vResult.w = fract( Le ); 100: vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0; 101: return vResult; 102: } 103: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 ); 104: vec4 LogLuvToLinear( in vec4 value ) { 105: float Le = value.z * 255.0 + value.w; 106: vec3 Xp_Y_XYZp; 107: Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 ); 108: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y; 109: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z; 110: vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM; 111: return vec4( max( vRGB, 0.0 ), 1.0 ); 112: } 113: vec4 mapTexelToLinear( vec4 value ) { return sRGBToLinear( value ); } 114: vec4 matcapTexelToLinear( vec4 value ) { return GammaToLinear( value, float( GAMMA_FACTOR ) ); } 115: vec4 envMapTexelToLinear( vec4 value ) { return GammaToLinear( value, float( GAMMA_FACTOR ) ); } 116: vec4 emissiveMapTexelToLinear( vec4 value ) { return GammaToLinear( value, float( GAMMA_FACTOR ) ); } 117: vec4 linearToOutputTexel( vec4 value ) { return LinearToGamma( value, float( GAMMA_FACTOR ) ); } 118: 119: #define PHYSICAL 120: uniform vec3 diffuse; 121: uniform vec3 emissive; 122: uniform float roughness; 123: uniform float metalness; 124: uniform float opacity; 125: #ifndef STANDARD 126: uniform float clearCoat; 127: uniform float clearCoatRoughness; 128: #endif 129: varying vec3 vViewPosition; 130: #ifndef FLAT_SHADED 131: varying vec3 vNormal; 132: #endif 133: #define PI 3.14159265359 134: #define PI2 6.28318530718 135: #define PI_HALF 1.5707963267949 136: #define RECIPROCAL_PI 0.31830988618 137: #define RECIPROCAL_PI2 0.15915494 138: #define LOG2 1.442695 139: #define EPSILON 1e-6 140: #define saturate(a) clamp( a, 0.0, 1.0 ) 141: #define whiteCompliment(a) ( 1.0 - saturate( a ) ) 142: float pow2( const in float x ) { return x*x; } 143: float pow3( const in float x ) { return x*x*x; } 144: float pow4( const in float x ) { float x2 = x*x; return x2*x2; } 145: float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); } 146: highp float rand( const in vec2 uv ) { 147: const highp float a = 12.9898, b = 78.233, c = 43758.5453; 148: highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI ); 149: return fract(sin(sn) * c); 150: } 151: struct IncidentLight { 152: vec3 color; 153: vec3 direction; 154: bool visible; 155: }; 156: struct ReflectedLight { 157: vec3 directDiffuse; 158: vec3 directSpecular; 159: vec3 indirectDiffuse; 160: vec3 indirectSpecular; 161: }; 162: struct GeometricContext { 163: vec3 position; 164: vec3 normal; 165: vec3 viewDir; 166: }; 167: vec3 transformDirection( in vec3 dir, in mat4 matrix ) { 168: return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); 169: } 170: vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) { 171: return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); 172: } 173: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { 174: float distance = dot( planeNormal, point - pointOnPlane ); 175: return - distance * planeNormal + point; 176: } 177: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { 178: return sign( dot( point - pointOnPlane, planeNormal ) ); 179: } 180: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { 181: return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine; 182: } 183: mat3 transposeMat3( const in mat3 m ) { 184: mat3 tmp; 185: tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x ); 186: tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y ); 187: tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z ); 188: return tmp; 189: } 190: float linearToRelativeLuminance( const in vec3 color ) { 191: vec3 weights = vec3( 0.2126, 0.7152, 0.0722 ); 192: return dot( weights, color.rgb ); 193: } 194: vec3 packNormalToRGB( const in vec3 normal ) { 195: return normalize( normal ) * 0.5 + 0.5; 196: } 197: vec3 unpackRGBToNormal( const in vec3 rgb ) { 198: return 2.0 * rgb.xyz - 1.0; 199: } 200: const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.; 201: const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. ); 202: const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. ); 203: const float ShiftRight8 = 1. / 256.; 204: vec4 packDepthToRGBA( const in float v ) { 205: vec4 r = vec4( fract( v * PackFactors ), v ); 206: r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale; 207: } 208: float unpackRGBAToDepth( const in vec4 v ) { 209: return dot( v, UnpackFactors ); 210: } 211: float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) { 212: return ( viewZ + near ) / ( near - far ); 213: } 214: float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) { 215: return linearClipZ * ( near - far ) - near; 216: } 217: float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) { 218: return (( near + viewZ ) * far ) / (( far - near ) * viewZ ); 219: } 220: float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) { 221: return ( near * far ) / ( ( far - near ) * invClipZ - far ); 222: } 223: #if defined( DITHERING ) 224: vec3 dithering( vec3 color ) { 225: float grid_position = rand( gl_FragCoord.xy ); 226: vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 ); 227: dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position ); 228: return color + dither_shift_RGB; 229: } 230: #endif 231: #ifdef USE_COLOR 232: varying vec3 vColor; 233: #endif 234: #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP ) 235: varying vec2 vUv; 236: #endif 237: #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) 238: varying vec2 vUv2; 239: #endif 240: #ifdef USE_MAP 241: uniform sampler2D map; 242: #endif 243: #ifdef USE_ALPHAMAP 244: uniform sampler2D alphaMap; 245: #endif 246: #ifdef USE_AOMAP 247: uniform sampler2D aoMap; 248: uniform float aoMapIntensity; 249: #endif 250: #ifdef USE_LIGHTMAP 251: uniform sampler2D lightMap; 252: uniform float lightMapIntensity; 253: #endif 254: #ifdef USE_EMISSIVEMAP 255: uniform sampler2D emissiveMap; 256: #endif 257: float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) { 258: #if defined ( PHYSICALLY_CORRECT_LIGHTS ) 259: float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 ); 260: if( cutoffDistance > 0.0 ) { 261: distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) ); 262: } 263: return distanceFalloff; 264: #else 265: if( cutoffDistance > 0.0 && decayExponent > 0.0 ) { 266: return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent ); 267: } 268: return 1.0; 269: #endif 270: } 271: vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) { 272: return RECIPROCAL_PI * diffuseColor; 273: } 274: vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) { 275: float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH ); 276: return ( 1.0 - specularColor ) * fresnel + specularColor; 277: } 278: float G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) { 279: float a2 = pow2( alpha ); 280: float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); 281: float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); 282: return 1.0 / ( gl * gv ); 283: } 284: float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) { 285: float a2 = pow2( alpha ); 286: float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); 287: float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); 288: return 0.5 / max( gv + gl, EPSILON ); 289: } 290: float D_GGX( const in float alpha, const in float dotNH ) { 291: float a2 = pow2( alpha ); 292: float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; 293: return RECIPROCAL_PI * a2 / pow2( denom ); 294: } 295: vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) { 296: float alpha = pow2( roughness ); 297: vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); 298: float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) ); 299: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 300: float dotNH = saturate( dot( geometry.normal, halfDir ) ); 301: float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); 302: vec3 F = F_Schlick( specularColor, dotLH ); 303: float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV ); 304: float D = D_GGX( alpha, dotNH ); 305: return F * ( G * D ); 306: } 307: vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) { 308: const float LUT_SIZE = 64.0; 309: const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE; 310: const float LUT_BIAS = 0.5 / LUT_SIZE; 311: float dotNV = saturate( dot( N, V ) ); 312: vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) ); 313: uv = uv * LUT_SCALE + LUT_BIAS; 314: return uv; 315: } 316: float LTC_ClippedSphereFormFactor( const in vec3 f ) { 317: float l = length( f ); 318: return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 ); 319: } 320: vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) { 321: float x = dot( v1, v2 ); 322: float y = abs( x ); 323: float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y; 324: float b = 3.4175940 + ( 4.1616724 + y ) * y; 325: float v = a / b; 326: float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v; 327: return cross( v1, v2 ) * theta_sintheta; 328: } 329: vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) { 330: vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ]; 331: vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ]; 332: vec3 lightNormal = cross( v1, v2 ); 333: if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 ); 334: vec3 T1, T2; 335: T1 = normalize( V - N * dot( V, N ) ); 336: T2 = - cross( N, T1 ); 337: mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) ); 338: vec3 coords[ 4 ]; 339: coords[ 0 ] = mat * ( rectCoords[ 0 ] - P ); 340: coords[ 1 ] = mat * ( rectCoords[ 1 ] - P ); 341: coords[ 2 ] = mat * ( rectCoords[ 2 ] - P ); 342: coords[ 3 ] = mat * ( rectCoords[ 3 ] - P ); 343: coords[ 0 ] = normalize( coords[ 0 ] ); 344: coords[ 1 ] = normalize( coords[ 1 ] ); 345: coords[ 2 ] = normalize( coords[ 2 ] ); 346: coords[ 3 ] = normalize( coords[ 3 ] ); 347: vec3 vectorFormFactor = vec3( 0.0 ); 348: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] ); 349: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] ); 350: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] ); 351: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] ); 352: float result = LTC_ClippedSphereFormFactor( vectorFormFactor ); 353: return vec3( result ); 354: } 355: vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) { 356: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 357: const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); 358: const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); 359: vec4 r = roughness * c0 + c1; 360: float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; 361: vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; 362: return specularColor * AB.x + AB.y; 363: } 364: float G_BlinnPhong_Implicit( ) { 365: return 0.25; 366: } 367: float D_BlinnPhong( const in float shininess, const in float dotNH ) { 368: return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); 369: } 370: vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) { 371: vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); 372: float dotNH = saturate( dot( geometry.normal, halfDir ) ); 373: float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); 374: vec3 F = F_Schlick( specularColor, dotLH ); 375: float G = G_BlinnPhong_Implicit( ); 376: float D = D_BlinnPhong( shininess, dotNH ); 377: return F * ( G * D ); 378: } 379: float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) { 380: return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 ); 381: } 382: float BlinnExponentToGGXRoughness( const in float blinnExponent ) { 383: return sqrt( 2.0 / ( blinnExponent + 2.0 ) ); 384: } 385: #ifdef ENVMAP_TYPE_CUBE_UV 386: #define cubeUV_textureSize (1024.0) 387: int getFaceFromDirection(vec3 direction) { 388: vec3 absDirection = abs(direction); 389: int face = -1; 390: if( absDirection.x > absDirection.z ) { 391: if(absDirection.x > absDirection.y ) 392: face = direction.x > 0.0 ? 0 : 3; 393: else 394: face = direction.y > 0.0 ? 1 : 4; 395: } 396: else { 397: if(absDirection.z > absDirection.y ) 398: face = direction.z > 0.0 ? 2 : 5; 399: else 400: face = direction.y > 0.0 ? 1 : 4; 401: } 402: return face; 403: } 404: #define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0) 405: #define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0)) 406: vec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) { 407: float scale = exp2(cubeUV_maxLods1 - roughnessLevel); 408: float dxRoughness = dFdx(roughness); 409: float dyRoughness = dFdy(roughness); 410: vec3 dx = dFdx( vec * scale * dxRoughness ); 411: vec3 dy = dFdy( vec * scale * dyRoughness ); 412: float d = max( dot( dx, dx ), dot( dy, dy ) ); 413: d = clamp(d, 1.0, cubeUV_rangeClamp); 414: float mipLevel = 0.5 * log2(d); 415: return vec2(floor(mipLevel), fract(mipLevel)); 416: } 417: #define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0) 418: #define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize) 419: vec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) { 420: mipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel; 421: float a = 16.0 * cubeUV_rcpTextureSize; 422: vec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) ); 423: vec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed; 424: float powScale = exp2_packed.x * exp2_packed.y; 425: float scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25; 426: float mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x; 427: bool bRes = mipLevel == 0.0; 428: scale = bRes && (scale < a) ? a : scale; 429: vec3 r; 430: vec2 offset; 431: int face = getFaceFromDirection(direction); 432: float rcpPowScale = 1.0 / powScale; 433: if( face == 0) { 434: r = vec3(direction.x, -direction.z, direction.y); 435: offset = vec2(0.0+mipOffset,0.75 * rcpPowScale); 436: offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y; 437: } 438: else if( face == 1) { 439: r = vec3(direction.y, direction.x, direction.z); 440: offset = vec2(scale+mipOffset, 0.75 * rcpPowScale); 441: offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y; 442: } 443: else if( face == 2) { 444: r = vec3(direction.z, direction.x, direction.y); 445: offset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale); 446: offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y; 447: } 448: else if( face == 3) { 449: r = vec3(direction.x, direction.z, direction.y); 450: offset = vec2(0.0+mipOffset,0.5 * rcpPowScale); 451: offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y; 452: } 453: else if( face == 4) { 454: r = vec3(direction.y, direction.x, -direction.z); 455: offset = vec2(scale+mipOffset, 0.5 * rcpPowScale); 456: offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y; 457: } 458: else { 459: r = vec3(direction.z, -direction.x, direction.y); 460: offset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale); 461: offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y; 462: } 463: r = normalize(r); 464: float texelOffset = 0.5 * cubeUV_rcpTextureSize; 465: vec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5; 466: vec2 base = offset + vec2( texelOffset ); 467: return base + s * ( scale - 2.0 * texelOffset ); 468: } 469: #define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0) 470: vec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) { 471: float roughnessVal = roughness* cubeUV_maxLods3; 472: float r1 = floor(roughnessVal); 473: float r2 = r1 + 1.0; 474: float t = fract(roughnessVal); 475: vec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness); 476: float s = mipInfo.y; 477: float level0 = mipInfo.x; 478: float level1 = level0 + 1.0; 479: level1 = level1 > 5.0 ? 5.0 : level1; 480: level0 += min( floor( s + 0.5 ), 5.0 ); 481: vec2 uv_10 = getCubeUV(reflectedDirection, r1, level0); 482: vec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10)); 483: vec2 uv_20 = getCubeUV(reflectedDirection, r2, level0); 484: vec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20)); 485: vec4 result = mix(color10, color20, t); 486: return vec4(result.rgb, 1.0); 487: } 488: #endif 489: #if defined( USE_ENVMAP ) || defined( PHYSICAL ) 490: uniform float reflectivity; 491: uniform float envMapIntensity; 492: #endif 493: #ifdef USE_ENVMAP 494: #if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) ) 495: varying vec3 vWorldPosition; 496: #endif 497: #ifdef ENVMAP_TYPE_CUBE 498: uniform samplerCube envMap; 499: #else 500: uniform sampler2D envMap; 501: #endif 502: uniform float flipEnvMap; 503: uniform int maxMipLevel; 504: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL ) 505: uniform float refractionRatio; 506: #else 507: varying vec3 vReflect; 508: #endif 509: #endif 510: #if defined( USE_ENVMAP ) && defined( PHYSICAL ) 511: vec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) { 512: vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix ); 513: #ifdef ENVMAP_TYPE_CUBE 514: vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz ); 515: #ifdef TEXTURE_LOD_EXT 516: vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) ); 517: #else 518: vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) ); 519: #endif 520: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 521: #elif defined( ENVMAP_TYPE_CUBE_UV ) 522: vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz ); 523: vec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 ); 524: #else 525: vec4 envMapColor = vec4( 0.0 ); 526: #endif 527: return PI * envMapColor.rgb * envMapIntensity; 528: } 529: float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) { 530: float maxMIPLevelScalar = float( maxMIPLevel ); 531: float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 ); 532: return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar ); 533: } 534: vec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) { 535: #ifdef ENVMAP_MODE_REFLECTION 536: vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal ); 537: #else 538: vec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio ); 539: #endif 540: reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); 541: float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel ); 542: #ifdef ENVMAP_TYPE_CUBE 543: vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz ); 544: #ifdef TEXTURE_LOD_EXT 545: vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel ); 546: #else 547: vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel ); 548: #endif 549: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 550: #elif defined( ENVMAP_TYPE_CUBE_UV ) 551: vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz ); 552: vec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent )); 553: #elif defined( ENVMAP_TYPE_EQUIREC ) 554: vec2 sampleUV; 555: sampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; 556: sampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5; 557: #ifdef TEXTURE_LOD_EXT 558: vec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel ); 559: #else 560: vec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel ); 561: #endif 562: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 563: #elif defined( ENVMAP_TYPE_SPHERE ) 564: vec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) ); 565: #ifdef TEXTURE_LOD_EXT 566: vec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel ); 567: #else 568: vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel ); 569: #endif 570: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 571: #endif 572: return envMapColor.rgb * envMapIntensity; 573: } 574: #endif 575: #ifdef USE_FOG 576: uniform vec3 fogColor; 577: varying float fogDepth; 578: #ifdef FOG_EXP2 579: uniform float fogDensity; 580: #else 581: uniform float fogNear; 582: uniform float fogFar; 583: #endif 584: #endif 585: uniform vec3 ambientLightColor; 586: vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { 587: vec3 irradiance = ambientLightColor; 588: #ifndef PHYSICALLY_CORRECT_LIGHTS 589: irradiance *= PI; 590: #endif 591: return irradiance; 592: } 593: #if 1 > 0 594: struct DirectionalLight { 595: vec3 direction; 596: vec3 color; 597: int shadow; 598: float shadowBias; 599: float shadowRadius; 600: vec2 shadowMapSize; 601: }; 602: uniform DirectionalLight directionalLights[ 1 ]; 603: void getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) { 604: directLight.color = directionalLight.color; 605: directLight.direction = directionalLight.direction; 606: directLight.visible = true; 607: } 608: #endif 609: #if 4 > 0 610: struct PointLight { 611: vec3 position; 612: vec3 color; 613: float distance; 614: float decay; 615: int shadow; 616: float shadowBias; 617: float shadowRadius; 618: vec2 shadowMapSize; 619: float shadowCameraNear; 620: float shadowCameraFar; 621: }; 622: uniform PointLight pointLights[ 4 ]; 623: void getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) { 624: vec3 lVector = pointLight.position - geometry.position; 625: directLight.direction = normalize( lVector ); 626: float lightDistance = length( lVector ); 627: directLight.color = pointLight.color; 628: directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay ); 629: directLight.visible = ( directLight.color != vec3( 0.0 ) ); 630: } 631: #endif 632: #if 1 > 0 633: struct SpotLight { 634: vec3 position; 635: vec3 direction; 636: vec3 color; 637: float distance; 638: float decay; 639: float coneCos; 640: float penumbraCos; 641: int shadow; 642: float shadowBias; 643: float shadowRadius; 644: vec2 shadowMapSize; 645: }; 646: uniform SpotLight spotLights[ 1 ]; 647: void getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) { 648: vec3 lVector = spotLight.position - geometry.position; 649: directLight.direction = normalize( lVector ); 650: float lightDistance = length( lVector ); 651: float angleCos = dot( directLight.direction, spotLight.direction ); 652: if ( angleCos > spotLight.coneCos ) { 653: float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos ); 654: directLight.color = spotLight.color; 655: directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay ); 656: directLight.visible = true; 657: } else { 658: directLight.color = vec3( 0.0 ); 659: directLight.visible = false; 660: } 661: } 662: #endif 663: #if 0 > 0 664: struct RectAreaLight { 665: vec3 color; 666: vec3 position; 667: vec3 halfWidth; 668: vec3 halfHeight; 669: }; 670: uniform sampler2D ltc_1; uniform sampler2D ltc_2; 671: uniform RectAreaLight rectAreaLights[ 0 ]; 672: #endif 673: #if 1 > 0 674: struct HemisphereLight { 675: vec3 direction; 676: vec3 skyColor; 677: vec3 groundColor; 678: }; 679: uniform HemisphereLight hemisphereLights[ 1 ]; 680: vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { 681: float dotNL = dot( geometry.normal, hemiLight.direction ); 682: float hemiDiffuseWeight = 0.5 * dotNL + 0.5; 683: vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); 684: #ifndef PHYSICALLY_CORRECT_LIGHTS 685: irradiance *= PI; 686: #endif 687: return irradiance; 688: } 689: #endif 690: struct PhysicalMaterial { 691: vec3 diffuseColor; 692: float specularRoughness; 693: vec3 specularColor; 694: #ifndef STANDARD 695: float clearCoat; 696: float clearCoatRoughness; 697: #endif 698: }; 699: #define MAXIMUM_SPECULAR_COEFFICIENT 0.16 700: #define DEFAULT_SPECULAR_COEFFICIENT 0.04 701: float clearCoatDHRApprox( const in float roughness, const in float dotNL ) { 702: return DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) ); 703: } 704: #if 0 > 0 705: void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 706: vec3 normal = geometry.normal; 707: vec3 viewDir = geometry.viewDir; 708: vec3 position = geometry.position; 709: vec3 lightPos = rectAreaLight.position; 710: vec3 halfWidth = rectAreaLight.halfWidth; 711: vec3 halfHeight = rectAreaLight.halfHeight; 712: vec3 lightColor = rectAreaLight.color; 713: float roughness = material.specularRoughness; 714: vec3 rectCoords[ 4 ]; 715: rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; rectCoords[ 1 ] = lightPos - halfWidth - halfHeight; 716: rectCoords[ 2 ] = lightPos - halfWidth + halfHeight; 717: rectCoords[ 3 ] = lightPos + halfWidth + halfHeight; 718: vec2 uv = LTC_Uv( normal, viewDir, roughness ); 719: vec4 t1 = texture2D( ltc_1, uv ); 720: vec4 t2 = texture2D( ltc_2, uv ); 721: mat3 mInv = mat3( 722: vec3( t1.x, 0, t1.y ), 723: vec3( 0, 1, 0 ), 724: vec3( t1.z, 0, t1.w ) 725: ); 726: vec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y ); 727: reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords ); 728: reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords ); 729: } 730: #endif 731: void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 732: float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); 733: vec3 irradiance = dotNL * directLight.color; 734: #ifndef PHYSICALLY_CORRECT_LIGHTS 735: irradiance *= PI; 736: #endif 737: #ifndef STANDARD 738: float clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL ); 739: #else 740: float clearCoatDHR = 0.0; 741: #endif 742: reflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness ); 743: reflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); 744: #ifndef STANDARD 745: reflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness ); 746: #endif 747: } 748: void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 749: reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); 750: } 751: void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 752: #ifndef STANDARD 753: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 754: float dotNL = dotNV; 755: float clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL ); 756: #else 757: float clearCoatDHR = 0.0; 758: #endif 759: reflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness ); 760: #ifndef STANDARD 761: reflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness ); 762: #endif 763: } 764: #define RE_Direct RE_Direct_Physical 765: #define RE_Direct_RectArea RE_Direct_RectArea_Physical 766: #define RE_IndirectDiffuse RE_IndirectDiffuse_Physical 767: #define RE_IndirectSpecular RE_IndirectSpecular_Physical 768: #define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness ) 769: #define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness ) 770: float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) { 771: return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); 772: } 773: #ifdef USE_SHADOWMAP 774: #if 1 > 0 775: uniform sampler2D directionalShadowMap[ 1 ]; 776: varying vec4 vDirectionalShadowCoord[ 1 ]; 777: #endif 778: #if 1 > 0 779: uniform sampler2D spotShadowMap[ 1 ]; 780: varying vec4 vSpotShadowCoord[ 1 ]; 781: #endif 782: #if 4 > 0 783: uniform sampler2D pointShadowMap[ 4 ]; 784: varying vec4 vPointShadowCoord[ 4 ]; 785: #endif 786: float texture2DCompare( sampler2D depths, vec2 uv, float compare ) { 787: return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) ); 788: } 789: float texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) { 790: const vec2 offset = vec2( 0.0, 1.0 ); 791: vec2 texelSize = vec2( 1.0 ) / size; 792: vec2 centroidUV = floor( uv * size + 0.5 ) / size; 793: float lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare ); 794: float lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare ); 795: float rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare ); 796: float rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare ); 797: vec2 f = fract( uv * size + 0.5 ); 798: float a = mix( lb, lt, f.y ); 799: float b = mix( rb, rt, f.y ); 800: float c = mix( a, b, f.x ); 801: return c; 802: } 803: float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) { 804: float shadow = 1.0; 805: shadowCoord.xyz /= shadowCoord.w; 806: shadowCoord.z += shadowBias; 807: bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 ); 808: bool inFrustum = all( inFrustumVec ); 809: bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 ); 810: bool frustumTest = all( frustumTestVec ); 811: if ( frustumTest ) { 812: #if defined( SHADOWMAP_TYPE_PCF ) 813: vec2 texelSize = vec2( 1.0 ) / shadowMapSize; 814: float dx0 = - texelSize.x * shadowRadius; 815: float dy0 = - texelSize.y * shadowRadius; 816: float dx1 = + texelSize.x * shadowRadius; 817: float dy1 = + texelSize.y * shadowRadius; 818: shadow = ( 819: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) + 820: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) + 821: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) + 822: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) + 823: texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) + 824: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) + 825: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) + 826: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) + 827: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z ) 828: ) * ( 1.0 / 9.0 ); 829: #elif defined( SHADOWMAP_TYPE_PCF_SOFT ) 830: vec2 texelSize = vec2( 1.0 ) / shadowMapSize; 831: float dx0 = - texelSize.x * shadowRadius; 832: float dy0 = - texelSize.y * shadowRadius; 833: float dx1 = + texelSize.x * shadowRadius; 834: float dy1 = + texelSize.y * shadowRadius; 835: shadow = ( 836: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) + 837: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) + 838: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) + 839: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) + 840: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) + 841: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) + 842: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) + 843: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) + 844: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z ) 845: ) * ( 1.0 / 9.0 ); 846: #else 847: shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ); 848: #endif 849: } 850: return shadow; 851: } 852: vec2 cubeToUV( vec3 v, float texelSizeY ) { 853: vec3 absV = abs( v ); 854: float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) ); 855: absV *= scaleToCube; 856: v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY ); 857: vec2 planar = v.xy; 858: float almostATexel = 1.5 * texelSizeY; 859: float almostOne = 1.0 - almostATexel; 860: if ( absV.z >= almostOne ) { 861: if ( v.z > 0.0 ) 862: planar.x = 4.0 - v.x; 863: } else if ( absV.x >= almostOne ) { 864: float signX = sign( v.x ); 865: planar.x = v.z * signX + 2.0 * signX; 866: } else if ( absV.y >= almostOne ) { 867: float signY = sign( v.y ); 868: planar.x = v.x + 2.0 * signY + 2.0; 869: planar.y = v.z * signY - 2.0; 870: } 871: return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 ); 872: } 873: float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) { 874: vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) ); 875: vec3 lightToPosition = shadowCoord.xyz; 876: float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); dp += shadowBias; 877: vec3 bd3D = normalize( lightToPosition ); 878: #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) 879: vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y; 880: return ( 881: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) + 882: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) + 883: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) + 884: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) + 885: texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) + 886: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) + 887: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) + 888: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) + 889: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp ) 890: ) * ( 1.0 / 9.0 ); 891: #else 892: return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ); 893: #endif 894: } 895: #endif 896: #ifdef USE_BUMPMAP 897: uniform sampler2D bumpMap; 898: uniform float bumpScale; 899: vec2 dHdxy_fwd() { 900: vec2 dSTdx = dFdx( vUv ); 901: vec2 dSTdy = dFdy( vUv ); 902: float Hll = bumpScale * texture2D( bumpMap, vUv ).x; 903: float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll; 904: float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll; 905: return vec2( dBx, dBy ); 906: } 907: vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) { 908: vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) ); 909: vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) ); 910: vec3 vN = surf_norm; 911: vec3 R1 = cross( vSigmaY, vN ); 912: vec3 R2 = cross( vN, vSigmaX ); 913: float fDet = dot( vSigmaX, R1 ); 914: fDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 915: vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 ); 916: return normalize( abs( fDet ) * surf_norm - vGrad ); 917: } 918: #endif 919: #ifdef USE_NORMALMAP 920: uniform sampler2D normalMap; 921: uniform vec2 normalScale; 922: #ifdef OBJECTSPACE_NORMALMAP 923: uniform mat3 normalMatrix; 924: #else 925: vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { 926: vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) ); 927: vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) ); 928: vec2 st0 = dFdx( vUv.st ); 929: vec2 st1 = dFdy( vUv.st ); 930: float scale = sign( st1.t * st0.s - st0.t * st1.s ); 931: vec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale ); 932: vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale ); 933: vec3 N = normalize( surf_norm ); 934: mat3 tsn = mat3( S, T, N ); 935: vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; 936: mapN.xy *= normalScale; 937: mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 938: return normalize( tsn * mapN ); 939: } 940: #endif 941: #endif 942: #ifdef USE_ROUGHNESSMAP 943: uniform sampler2D roughnessMap; 944: #endif 945: #ifdef USE_METALNESSMAP 946: uniform sampler2D metalnessMap; 947: #endif 948: #if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT ) 949: uniform float logDepthBufFC; 950: varying float vFragDepth; 951: #endif 952: #if 0 > 0 953: #if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP ) 954: varying vec3 vViewPosition; 955: #endif 956: uniform vec4 clippingPlanes[ 0 ]; 957: #endif 958: void main() { 959: #if 0 > 0 960: vec4 plane; 961: 962: #if 0 < 0 963: bool clipped = true; 964: 965: if ( clipped ) discard; 966: #endif 967: #endif 968: vec4 diffuseColor = vec4( diffuse, opacity ); 969: ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); 970: vec3 totalEmissiveRadiance = emissive; 971: #if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT ) 972: gl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5; 973: #endif 974: #ifdef USE_MAP 975: vec4 texelColor = texture2D( map, vUv ); 976: texelColor = mapTexelToLinear( texelColor ); 977: diffuseColor *= texelColor; 978: #endif 979: #ifdef USE_COLOR 980: diffuseColor.rgb *= vColor; 981: #endif 982: #ifdef USE_ALPHAMAP 983: diffuseColor.a *= texture2D( alphaMap, vUv ).g; 984: #endif 985: #ifdef ALPHATEST 986: if ( diffuseColor.a < ALPHATEST ) discard; 987: #endif 988: float roughnessFactor = roughness; 989: #ifdef USE_ROUGHNESSMAP 990: vec4 texelRoughness = texture2D( roughnessMap, vUv ); 991: roughnessFactor *= texelRoughness.g; 992: #endif 993: float metalnessFactor = metalness; 994: #ifdef USE_METALNESSMAP 995: vec4 texelMetalness = texture2D( metalnessMap, vUv ); 996: metalnessFactor *= texelMetalness.b; 997: #endif 998: #ifdef FLAT_SHADED 999: vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) ); 1000: vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) ); 1001: vec3 normal = normalize( cross( fdx, fdy ) ); 1002: #else 1003: vec3 normal = normalize( vNormal ); 1004: #ifdef DOUBLE_SIDED 1005: normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 1006: #endif 1007: #endif 1008: #ifdef USE_NORMALMAP 1009: #ifdef OBJECTSPACE_NORMALMAP 1010: normal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; 1011: #ifdef FLIP_SIDED 1012: normal = - normal; 1013: #endif 1014: #ifdef DOUBLE_SIDED 1015: normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 1016: #endif 1017: normal = normalize( normalMatrix * normal ); 1018: #else 1019: normal = perturbNormal2Arb( -vViewPosition, normal ); 1020: #endif 1021: #elif defined( USE_BUMPMAP ) 1022: normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() ); 1023: #endif 1024: #ifdef USE_EMISSIVEMAP 1025: vec4 emissiveColor = texture2D( emissiveMap, vUv ); 1026: emissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb; 1027: totalEmissiveRadiance *= emissiveColor.rgb; 1028: #endif 1029: PhysicalMaterial material; 1030: material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); 1031: material.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 ); 1032: #ifdef STANDARD 1033: material.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor ); 1034: #else 1035: material.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor ); 1036: material.clearCoat = saturate( clearCoat ); material.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 ); 1037: #endif 1038: 1039: GeometricContext geometry; 1040: geometry.position = - vViewPosition; 1041: geometry.normal = normal; 1042: geometry.viewDir = normalize( vViewPosition ); 1043: IncidentLight directLight; 1044: #if ( 4 > 0 ) && defined( RE_Direct ) 1045: PointLight pointLight; 1046: 1047: pointLight = pointLights[ 0 ]; 1048: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1049: #ifdef USE_SHADOWMAP 1050: directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ 0 ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ 0 ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; 1051: #endif 1052: RE_Direct( directLight, geometry, material, reflectedLight ); 1053: 1054: pointLight = pointLights[ 1 ]; 1055: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1056: #ifdef USE_SHADOWMAP 1057: directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ 1 ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ 1 ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; 1058: #endif 1059: RE_Direct( directLight, geometry, material, reflectedLight ); 1060: 1061: pointLight = pointLights[ 2 ]; 1062: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1063: #ifdef USE_SHADOWMAP 1064: directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ 2 ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ 2 ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; 1065: #endif 1066: RE_Direct( directLight, geometry, material, reflectedLight ); 1067: 1068: pointLight = pointLights[ 3 ]; 1069: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1070: #ifdef USE_SHADOWMAP 1071: directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ 3 ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ 3 ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; 1072: #endif 1073: RE_Direct( directLight, geometry, material, reflectedLight ); 1074: 1075: #endif 1076: #if ( 1 > 0 ) && defined( RE_Direct ) 1077: SpotLight spotLight; 1078: 1079: spotLight = spotLights[ 0 ]; 1080: getSpotDirectLightIrradiance( spotLight, geometry, directLight ); 1081: #ifdef USE_SHADOWMAP 1082: directLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ 0 ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ 0 ] ) : 1.0; 1083: #endif 1084: RE_Direct( directLight, geometry, material, reflectedLight ); 1085: 1086: #endif 1087: #if ( 1 > 0 ) && defined( RE_Direct ) 1088: DirectionalLight directionalLight; 1089: 1090: directionalLight = directionalLights[ 0 ]; 1091: getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight ); 1092: #ifdef USE_SHADOWMAP 1093: directLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ 0 ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ 0 ] ) : 1.0; 1094: #endif 1095: RE_Direct( directLight, geometry, material, reflectedLight ); 1096: 1097: #endif 1098: #if ( 0 > 0 ) && defined( RE_Direct_RectArea ) 1099: RectAreaLight rectAreaLight; 1100: 1101: #endif 1102: #if defined( RE_IndirectDiffuse ) 1103: vec3 irradiance = getAmbientLightIrradiance( ambientLightColor ); 1104: #if ( 1 > 0 ) 1105: 1106: irradiance += getHemisphereLightIrradiance( hemisphereLights[ 0 ], geometry ); 1107: 1108: #endif 1109: #endif 1110: #if defined( RE_IndirectSpecular ) 1111: vec3 radiance = vec3( 0.0 ); 1112: vec3 clearCoatRadiance = vec3( 0.0 ); 1113: #endif 1114: #if defined( RE_IndirectDiffuse ) 1115: #ifdef USE_LIGHTMAP 1116: vec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; 1117: #ifndef PHYSICALLY_CORRECT_LIGHTS 1118: lightMapIrradiance *= PI; 1119: #endif 1120: irradiance += lightMapIrradiance; 1121: #endif 1122: #if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV ) 1123: irradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel ); 1124: #endif 1125: #endif 1126: #if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular ) 1127: radiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel ); 1128: #ifndef STANDARD 1129: clearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel ); 1130: #endif 1131: #endif 1132: #if defined( RE_IndirectDiffuse ) 1133: RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight ); 1134: #endif 1135: #if defined( RE_IndirectSpecular ) 1136: RE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight ); 1137: #endif 1138: #ifdef USE_AOMAP 1139: float ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0; 1140: reflectedLight.indirectDiffuse *= ambientOcclusion; 1141: #if defined( USE_ENVMAP ) && defined( PHYSICAL ) 1142: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 1143: reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness ); 1144: #endif 1145: #endif 1146: vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; 1147: gl_FragColor = vec4( outgoingLight, diffuseColor.a ); 1148: #if defined( TONE_MAPPING ) 1149: gl_FragColor.rgb = toneMapping( gl_FragColor.rgb ); 1150: #endif 1151: gl_FragColor = linearToOutputTexel( gl_FragColor ); 1152: #ifdef USE_FOG 1153: #ifdef FOG_EXP2 1154: float fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) ); 1155: #else 1156: float fogFactor = smoothstep( fogNear, fogFar, fogDepth ); 1157: #endif 1158: gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor ); 1159: #endif 1160: #ifdef PREMULTIPLIED_ALPHA 1161: gl_FragColor.rgb *= gl_FragColor.a; 1162: #endif 1163: #if defined( DITHERING ) 1164: gl_FragColor.rgb = dithering( gl_FragColor.rgb ); 1165: #endif 1166: }