pmndrs / drei

🥉 useful helpers for react-three-fiber
https://docs.pmnd.rs/drei
MIT License
8.22k stars 672 forks source link

THREE.WebGLShader ERROR when input specific number to softShadows #240

Closed SiegeSailor closed 3 years ago

SiegeSailor commented 3 years ago

Problem Description:

I ran into the following error when I implement softShadows with specific numbers. All the imported models would be gone and the console will report the error message with red color when it occurs.

Console Error Message THREE.WebGLShader: gl.getShaderInfoLog() fragment ERROR: 0:891: '' : array size must be a constant integer expression ERROR: 0:899: '<' : wrong operand types - no operation '<' exists that takes a left-hand operand of type 'highp int' and a right operand of type 'const float' (or there is no acceptable conversion) ERROR: 0:914: '<' : wrong operand types - no operation '<' exists that takes a left-hand operand of type 'highp int' and a right operand of type 'const float' (or there is no acceptable conversion) ERROR: 0:927: '<' : wrong operand types - no operation '<' exists that takes a left-hand operand of type 'highp int' and a right operand of type 'const float' (or there is no acceptable conversion) ERROR: 0:931: '<' : wrong operand types - no operation '<' exists that takes a left-hand operand of type 'highp int' and a right operand of type 'const float' (or there is no acceptable conversion) 1: #version 300 es 2: #define varying in 3: out highp vec4 pc_fragColor; 4: #define gl_FragColor pc_fragColor 5: #define gl_FragDepthEXT gl_FragDepth 6: #define texture2D texture 7: #define textureCube texture 8: #define texture2DProj textureProj 9: #define texture2DLodEXT textureLod 10: #define texture2DProjLodEXT textureProjLod 11: #define textureCubeLodEXT textureLod 12: #define texture2DGradEXT textureGrad 13: #define texture2DProjGradEXT textureProjGrad 14: #define textureCubeGradEXT textureGrad 15: precision highp float; 16: precision highp int; 17: #define HIGH_PRECISION 18: #define SHADER_NAME MeshStandardMaterial 19: #define STANDARD 20: #define GAMMA_FACTOR 2 21: #define USE_FOG 22: #define USE_MAP 23: #define USE_UV 24: #define USE_SHADOWMAP 25: #define SHADOWMAP_TYPE_PCF_SOFT 26: uniform mat4 viewMatrix; 27: uniform vec3 cameraPosition; 28: uniform bool isOrthographic; 29: #define TONE_MAPPING 30: #ifndef saturate 31: #define saturate(a) clamp( a, 0.0, 1.0 ) 32: #endif 33: uniform float toneMappingExposure; 34: vec3 LinearToneMapping( vec3 color ) { 35: return toneMappingExposure * color; 36: } 37: vec3 ReinhardToneMapping( vec3 color ) { 38: color *= toneMappingExposure; 39: return saturate( color / ( vec3( 1.0 ) + color ) ); 40: } 41: vec3 OptimizedCineonToneMapping( vec3 color ) { 42: color *= toneMappingExposure; 43: color = max( vec3( 0.0 ), color - 0.004 ); 44: return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) ); 45: } 46: vec3 RRTAndODTFit( vec3 v ) { 47: vec3 a = v * ( v + 0.0245786 ) - 0.000090537; 48: vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081; 49: return a / b; 50: } 51: vec3 ACESFilmicToneMapping( vec3 color ) { 52: const mat3 ACESInputMat = mat3( 53: vec3( 0.59719, 0.07600, 0.02840 ), vec3( 0.35458, 0.90834, 0.13383 ), 54: vec3( 0.04823, 0.01566, 0.83777 ) 55: ); 56: const mat3 ACESOutputMat = mat3( 57: vec3( 1.60475, -0.10208, -0.00327 ), vec3( -0.53108, 1.10813, -0.07276 ), 58: vec3( -0.07367, -0.00605, 1.07602 ) 59: ); 60: color *= toneMappingExposure / 0.6; 61: color = ACESInputMat * color; 62: color = RRTAndODTFit( color ); 63: color = ACESOutputMat * color; 64: return saturate( color ); 65: } 66: vec3 CustomToneMapping( vec3 color ) { return color; } 67: vec3 toneMapping( vec3 color ) { return ACESFilmicToneMapping( color ); } 68: 69: vec4 LinearToLinear( in vec4 value ) { 70: return value; 71: } 72: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) { 73: return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a ); 74: } 75: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) { 76: return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a ); 77: } 78: vec4 sRGBToLinear( in vec4 value ) { 79: 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 ); 80: } 81: vec4 LinearTosRGB( in vec4 value ) { 82: 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 ); 83: } 84: vec4 RGBEToLinear( in vec4 value ) { 85: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 ); 86: } 87: vec4 LinearToRGBE( in vec4 value ) { 88: float maxComponent = max( max( value.r, value.g ), value.b ); 89: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 ); 90: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 ); 91: } 92: vec4 RGBMToLinear( in vec4 value, in float maxRange ) { 93: return vec4( value.rgb * value.a * maxRange, 1.0 ); 94: } 95: vec4 LinearToRGBM( in vec4 value, in float maxRange ) { 96: float maxRGB = max( value.r, max( value.g, value.b ) ); 97: float M = clamp( maxRGB / maxRange, 0.0, 1.0 ); 98: M = ceil( M * 255.0 ) / 255.0; 99: return vec4( value.rgb / ( M * maxRange ), M ); 100: } 101: vec4 RGBDToLinear( in vec4 value, in float maxRange ) { 102: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 ); 103: } 104: vec4 LinearToRGBD( in vec4 value, in float maxRange ) { 105: float maxRGB = max( value.r, max( value.g, value.b ) ); 106: float D = max( maxRange / maxRGB, 1.0 ); 107: D = clamp( floor( D ) / 255.0, 0.0, 1.0 ); 108: return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D ); 109: } 110: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 ); 111: vec4 LinearToLogLuv( in vec4 value ) { 112: vec3 Xp_Y_XYZp = cLogLuvM * value.rgb; 113: Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) ); 114: vec4 vResult; 115: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z; 116: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0; 117: vResult.w = fract( Le ); 118: vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0; 119: return vResult; 120: } 121: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 ); 122: vec4 LogLuvToLinear( in vec4 value ) { 123: float Le = value.z * 255.0 + value.w; 124: vec3 Xp_Y_XYZp; 125: Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 ); 126: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y; 127: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z; 128: vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb; 129: return vec4( max( vRGB, 0.0 ), 1.0 ); 130: } 131: vec4 mapTexelToLinear( vec4 value ) { return sRGBToLinear( value ); } 132: vec4 linearToOutputTexel( vec4 value ) { return LinearTosRGB( value ); } 133: 134: #define STANDARD 135: #ifdef PHYSICAL 136: #define REFLECTIVITY 137: #define CLEARCOAT 138: #define TRANSMISSION 139: #endif 140: uniform vec3 diffuse; 141: uniform vec3 emissive; 142: uniform float roughness; 143: uniform float metalness; 144: uniform float opacity; 145: #ifdef TRANSMISSION 146: uniform float transmission; 147: #endif 148: #ifdef REFLECTIVITY 149: uniform float reflectivity; 150: #endif 151: #ifdef CLEARCOAT 152: uniform float clearcoat; 153: uniform float clearcoatRoughness; 154: #endif 155: #ifdef USE_SHEEN 156: uniform vec3 sheen; 157: #endif 158: varying vec3 vViewPosition; 159: #ifndef FLAT_SHADED 160: varying vec3 vNormal; 161: #ifdef USE_TANGENT 162: varying vec3 vTangent; 163: varying vec3 vBitangent; 164: #endif 165: #endif 166: #define PI 3.141592653589793 167: #define PI2 6.283185307179586 168: #define PI_HALF 1.5707963267948966 169: #define RECIPROCAL_PI 0.3183098861837907 170: #define RECIPROCAL_PI2 0.15915494309189535 171: #define EPSILON 1e-6 172: #ifndef saturate 173: #define saturate(a) clamp( a, 0.0, 1.0 ) 174: #endif 175: #define whiteComplement(a) ( 1.0 - saturate( a ) ) 176: float pow2( const in float x ) { return x*x; } 177: float pow3( const in float x ) { return x*x*x; } 178: float pow4( const in float x ) { float x2 = x*x; return x2*x2; } 179: float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); } 180: highp float rand( const in vec2 uv ) { 181: const highp float a = 12.9898, b = 78.233, c = 43758.5453; 182: highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI ); 183: return fract(sin(sn) * c); 184: } 185: #ifdef HIGH_PRECISION 186: float precisionSafeLength( vec3 v ) { return length( v ); } 187: #else 188: float max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); } 189: float precisionSafeLength( vec3 v ) { 190: float maxComponent = max3( abs( v ) ); 191: return length( v / maxComponent ) * maxComponent; 192: } 193: #endif 194: struct IncidentLight { 195: vec3 color; 196: vec3 direction; 197: bool visible; 198: }; 199: struct ReflectedLight { 200: vec3 directDiffuse; 201: vec3 directSpecular; 202: vec3 indirectDiffuse; 203: vec3 indirectSpecular; 204: }; 205: struct GeometricContext { 206: vec3 position; 207: vec3 normal; 208: vec3 viewDir; 209: #ifdef CLEARCOAT 210: vec3 clearcoatNormal; 211: #endif 212: }; 213: vec3 transformDirection( in vec3 dir, in mat4 matrix ) { 214: return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); 215: } 216: vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) { 217: return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); 218: } 219: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { 220: float distance = dot( planeNormal, point - pointOnPlane ); 221: return - distance * planeNormal + point; 222: } 223: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { 224: return sign( dot( point - pointOnPlane, planeNormal ) ); 225: } 226: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { 227: return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine; 228: } 229: mat3 transposeMat3( const in mat3 m ) { 230: mat3 tmp; 231: tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x ); 232: tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y ); 233: tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z ); 234: return tmp; 235: } 236: float linearToRelativeLuminance( const in vec3 color ) { 237: vec3 weights = vec3( 0.2126, 0.7152, 0.0722 ); 238: return dot( weights, color.rgb ); 239: } 240: bool isPerspectiveMatrix( mat4 m ) { 241: return m[ 2 ][ 3 ] == - 1.0; 242: } 243: vec2 equirectUv( in vec3 dir ) { 244: float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5; 245: float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; 246: return vec2( u, v ); 247: } 248: vec3 packNormalToRGB( const in vec3 normal ) { 249: return normalize( normal ) * 0.5 + 0.5; 250: } 251: vec3 unpackRGBToNormal( const in vec3 rgb ) { 252: return 2.0 * rgb.xyz - 1.0; 253: } 254: const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.; 255: const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. ); 256: const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. ); 257: const float ShiftRight8 = 1. / 256.; 258: vec4 packDepthToRGBA( const in float v ) { 259: vec4 r = vec4( fract( v * PackFactors ), v ); 260: r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale; 261: } 262: float unpackRGBAToDepth( const in vec4 v ) { 263: return dot( v, UnpackFactors ); 264: } 265: vec4 pack2HalfToRGBA( vec2 v ) { 266: vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 )); 267: return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w); 268: } 269: vec2 unpackRGBATo2Half( vec4 v ) { 270: return vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) ); 271: } 272: float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) { 273: return ( viewZ + near ) / ( near - far ); 274: } 275: float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) { 276: return linearClipZ * ( near - far ) - near; 277: } 278: float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) { 279: return (( near + viewZ ) * far ) / (( far - near ) * viewZ ); 280: } 281: float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) { 282: return ( near * far ) / ( ( far - near ) * invClipZ - far ); 283: } 284: #ifdef DITHERING 285: vec3 dithering( vec3 color ) { 286: float grid_position = rand( gl_FragCoord.xy ); 287: vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 ); 288: dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position ); 289: return color + dither_shift_RGB; 290: } 291: #endif 292: #ifdef USE_COLOR 293: varying vec3 vColor; 294: #endif 295: #if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) ) 296: varying vec2 vUv; 297: #endif 298: #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) 299: varying vec2 vUv2; 300: #endif 301: #ifdef USE_MAP 302: uniform sampler2D map; 303: #endif 304: #ifdef USE_ALPHAMAP 305: uniform sampler2D alphaMap; 306: #endif 307: #ifdef USE_AOMAP 308: uniform sampler2D aoMap; 309: uniform float aoMapIntensity; 310: #endif 311: #ifdef USE_LIGHTMAP 312: uniform sampler2D lightMap; 313: uniform float lightMapIntensity; 314: #endif 315: #ifdef USE_EMISSIVEMAP 316: uniform sampler2D emissiveMap; 317: #endif 318: #ifdef USE_TRANSMISSIONMAP 319: uniform sampler2D transmissionMap; 320: #endif 321: vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) { 322: const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); 323: const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); 324: vec4 r = roughness * c0 + c1; 325: float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; 326: return vec2( -1.04, 1.04 ) * a004 + r.zw; 327: } 328: float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) { 329: #if defined ( PHYSICALLY_CORRECT_LIGHTS ) 330: float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 ); 331: if( cutoffDistance > 0.0 ) { 332: distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) ); 333: } 334: return distanceFalloff; 335: #else 336: if( cutoffDistance > 0.0 && decayExponent > 0.0 ) { 337: return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent ); 338: } 339: return 1.0; 340: #endif 341: } 342: vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) { 343: return RECIPROCAL_PI * diffuseColor; 344: } 345: vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) { 346: float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH ); 347: return ( 1.0 - specularColor ) * fresnel + specularColor; 348: } 349: vec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) { 350: float fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV ); 351: vec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0; 352: return Fr * fresnel + F0; 353: } 354: float G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) { 355: float a2 = pow2( alpha ); 356: float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); 357: float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); 358: return 1.0 / ( gl * gv ); 359: } 360: float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) { 361: float a2 = pow2( alpha ); 362: float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); 363: float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); 364: return 0.5 / max( gv + gl, EPSILON ); 365: } 366: float D_GGX( const in float alpha, const in float dotNH ) { 367: float a2 = pow2( alpha ); 368: float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; 369: return RECIPROCAL_PI * a2 / pow2( denom ); 370: } 371: vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) { 372: float alpha = pow2( roughness ); 373: vec3 halfDir = normalize( incidentLight.direction + viewDir ); 374: float dotNL = saturate( dot( normal, incidentLight.direction ) ); 375: float dotNV = saturate( dot( normal, viewDir ) ); 376: float dotNH = saturate( dot( normal, halfDir ) ); 377: float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); 378: vec3 F = F_Schlick( specularColor, dotLH ); 379: float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV ); 380: float D = D_GGX( alpha, dotNH ); 381: return F * ( G * D ); 382: } 383: vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) { 384: const float LUT_SIZE = 64.0; 385: const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE; 386: const float LUT_BIAS = 0.5 / LUT_SIZE; 387: float dotNV = saturate( dot( N, V ) ); 388: vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) ); 389: uv = uv * LUT_SCALE + LUT_BIAS; 390: return uv; 391: } 392: float LTC_ClippedSphereFormFactor( const in vec3 f ) { 393: float l = length( f ); 394: return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 ); 395: } 396: vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) { 397: float x = dot( v1, v2 ); 398: float y = abs( x ); 399: float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y; 400: float b = 3.4175940 + ( 4.1616724 + y ) * y; 401: float v = a / b; 402: float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v; 403: return cross( v1, v2 ) * theta_sintheta; 404: } 405: vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) { 406: vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ]; 407: vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ]; 408: vec3 lightNormal = cross( v1, v2 ); 409: if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 ); 410: vec3 T1, T2; 411: T1 = normalize( V - N * dot( V, N ) ); 412: T2 = - cross( N, T1 ); 413: mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) ); 414: vec3 coords[ 4 ]; 415: coords[ 0 ] = mat * ( rectCoords[ 0 ] - P ); 416: coords[ 1 ] = mat * ( rectCoords[ 1 ] - P ); 417: coords[ 2 ] = mat * ( rectCoords[ 2 ] - P ); 418: coords[ 3 ] = mat * ( rectCoords[ 3 ] - P ); 419: coords[ 0 ] = normalize( coords[ 0 ] ); 420: coords[ 1 ] = normalize( coords[ 1 ] ); 421: coords[ 2 ] = normalize( coords[ 2 ] ); 422: coords[ 3 ] = normalize( coords[ 3 ] ); 423: vec3 vectorFormFactor = vec3( 0.0 ); 424: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] ); 425: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] ); 426: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] ); 427: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] ); 428: float result = LTC_ClippedSphereFormFactor( vectorFormFactor ); 429: return vec3( result ); 430: } 431: vec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) { 432: float dotNV = saturate( dot( normal, viewDir ) ); 433: vec2 brdf = integrateSpecularBRDF( dotNV, roughness ); 434: return specularColor * brdf.x + brdf.y; 435: } 436: void BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) { 437: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 438: vec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness ); 439: vec2 brdf = integrateSpecularBRDF( dotNV, roughness ); 440: vec3 FssEss = F * brdf.x + brdf.y; 441: float Ess = brdf.x + brdf.y; 442: float Ems = 1.0 - Ess; 443: vec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg ); 444: singleScatter += FssEss; 445: multiScatter += Fms * Ems; 446: } 447: float G_BlinnPhong_Implicit( ) { 448: return 0.25; 449: } 450: float D_BlinnPhong( const in float shininess, const in float dotNH ) { 451: return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); 452: } 453: vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) { 454: vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir ); 455: float dotNH = saturate( dot( geometry.normal, halfDir ) ); 456: float dotLH = saturate( dot( incidentLight.direction, halfDir ) ); 457: vec3 F = F_Schlick( specularColor, dotLH ); 458: float G = G_BlinnPhong_Implicit( ); 459: float D = D_BlinnPhong( shininess, dotNH ); 460: return F * ( G * D ); 461: } 462: float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) { 463: return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 ); 464: } 465: float BlinnExponentToGGXRoughness( const in float blinnExponent ) { 466: return sqrt( 2.0 / ( blinnExponent + 2.0 ) ); 467: } 468: #if defined( USE_SHEEN ) 469: float D_Charlie(float roughness, float NoH) { 470: float invAlpha = 1.0 / roughness; 471: float cos2h = NoH * NoH; 472: float sin2h = max(1.0 - cos2h, 0.0078125); return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI); 473: } 474: float V_Neubelt(float NoV, float NoL) { 475: return saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV))); 476: } 477: vec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) { 478: vec3 N = geometry.normal; 479: vec3 V = geometry.viewDir; 480: vec3 H = normalize( V + L ); 481: float dotNH = saturate( dot( N, H ) ); 482: return specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) ); 483: } 484: #endif 485: #ifdef ENVMAP_TYPE_CUBE_UV 486: #define cubeUV_maxMipLevel 8.0 487: #define cubeUV_minMipLevel 4.0 488: #define cubeUV_maxTileSize 256.0 489: #define cubeUV_minTileSize 16.0 490: float getFace( vec3 direction ) { 491: vec3 absDirection = abs( direction ); 492: float face = - 1.0; 493: if ( absDirection.x > absDirection.z ) { 494: if ( absDirection.x > absDirection.y ) 495: face = direction.x > 0.0 ? 0.0 : 3.0; 496: else 497: face = direction.y > 0.0 ? 1.0 : 4.0; 498: } else { 499: if ( absDirection.z > absDirection.y ) 500: face = direction.z > 0.0 ? 2.0 : 5.0; 501: else 502: face = direction.y > 0.0 ? 1.0 : 4.0; 503: } 504: return face; 505: } 506: vec2 getUV( vec3 direction, float face ) { 507: vec2 uv; 508: if ( face == 0.0 ) { 509: uv = vec2( direction.z, direction.y ) / abs( direction.x ); 510: } else if ( face == 1.0 ) { 511: uv = vec2( - direction.x, - direction.z ) / abs( direction.y ); 512: } else if ( face == 2.0 ) { 513: uv = vec2( - direction.x, direction.y ) / abs( direction.z ); 514: } else if ( face == 3.0 ) { 515: uv = vec2( - direction.z, direction.y ) / abs( direction.x ); 516: } else if ( face == 4.0 ) { 517: uv = vec2( - direction.x, direction.z ) / abs( direction.y ); 518: } else { 519: uv = vec2( direction.x, direction.y ) / abs( direction.z ); 520: } 521: return 0.5 * ( uv + 1.0 ); 522: } 523: vec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) { 524: float face = getFace( direction ); 525: float filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 ); 526: mipInt = max( mipInt, cubeUV_minMipLevel ); 527: float faceSize = exp2( mipInt ); 528: float texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize ); 529: vec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ); 530: vec2 f = fract( uv ); 531: uv += 0.5 - f; 532: if ( face > 2.0 ) { 533: uv.y += faceSize; 534: face -= 3.0; 535: } 536: uv.x += face * faceSize; 537: if ( mipInt < cubeUV_maxMipLevel ) { 538: uv.y += 2.0 * cubeUV_maxTileSize; 539: } 540: uv.y += filterInt * 2.0 * cubeUV_minTileSize; 541: uv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize ); 542: uv *= texelSize; 543: vec3 tl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; 544: uv.x += texelSize; 545: vec3 tr = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; 546: uv.y += texelSize; 547: vec3 br = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; 548: uv.x -= texelSize; 549: vec3 bl = envMapTexelToLinear( texture2D( envMap, uv ) ).rgb; 550: vec3 tm = mix( tl, tr, f.x ); 551: vec3 bm = mix( bl, br, f.x ); 552: return mix( tm, bm, f.y ); 553: } 554: #define r0 1.0 555: #define v0 0.339 556: #define m0 - 2.0 557: #define r1 0.8 558: #define v1 0.276 559: #define m1 - 1.0 560: #define r4 0.4 561: #define v4 0.046 562: #define m4 2.0 563: #define r5 0.305 564: #define v5 0.016 565: #define m5 3.0 566: #define r6 0.21 567: #define v6 0.0038 568: #define m6 4.0 569: float roughnessToMip( float roughness ) { 570: float mip = 0.0; 571: if ( roughness >= r1 ) { 572: mip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0; 573: } else if ( roughness >= r4 ) { 574: mip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1; 575: } else if ( roughness >= r5 ) { 576: mip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4; 577: } else if ( roughness >= r6 ) { 578: mip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5; 579: } else { 580: mip = - 2.0 * log2( 1.16 * roughness ); } 581: return mip; 582: } 583: vec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) { 584: float mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel ); 585: float mipF = fract( mip ); 586: float mipInt = floor( mip ); 587: vec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt ); 588: if ( mipF == 0.0 ) { 589: return vec4( color0, 1.0 ); 590: } else { 591: vec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 ); 592: return vec4( mix( color0, color1, mipF ), 1.0 ); 593: } 594: } 595: #endif 596: #ifdef USE_ENVMAP 597: uniform float envMapIntensity; 598: uniform float flipEnvMap; 599: uniform int maxMipLevel; 600: #ifdef ENVMAP_TYPE_CUBE 601: uniform samplerCube envMap; 602: #else 603: uniform sampler2D envMap; 604: #endif 605: 606: #endif 607: #if defined( USE_ENVMAP ) 608: #ifdef ENVMAP_MODE_REFRACTION 609: uniform float refractionRatio; 610: #endif 611: vec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) { 612: vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix ); 613: #ifdef ENVMAP_TYPE_CUBE 614: vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz ); 615: #ifdef TEXTURE_LOD_EXT 616: vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) ); 617: #else 618: vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) ); 619: #endif 620: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 621: #elif defined( ENVMAP_TYPE_CUBE_UV ) 622: vec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 ); 623: #else 624: vec4 envMapColor = vec4( 0.0 ); 625: #endif 626: return PI * envMapColor.rgb * envMapIntensity; 627: } 628: float getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) { 629: float maxMIPLevelScalar = float( maxMIPLevel ); 630: float sigma = PI * roughness * roughness / ( 1.0 + roughness ); 631: float desiredMIPLevel = maxMIPLevelScalar + log2( sigma ); 632: return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar ); 633: } 634: vec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) { 635: #ifdef ENVMAP_MODE_REFLECTION 636: vec3 reflectVec = reflect( -viewDir, normal ); 637: reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) ); 638: #else 639: vec3 reflectVec = refract( -viewDir, normal, refractionRatio ); 640: #endif 641: reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); 642: float specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel ); 643: #ifdef ENVMAP_TYPE_CUBE 644: vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz ); 645: #ifdef TEXTURE_LOD_EXT 646: vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel ); 647: #else 648: vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel ); 649: #endif 650: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb; 651: #elif defined( ENVMAP_TYPE_CUBE_UV ) 652: vec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness ); 653: #endif 654: return envMapColor.rgb * envMapIntensity; 655: } 656: #endif 657: #ifdef USE_FOG 658: uniform vec3 fogColor; 659: varying float fogDepth; 660: #ifdef FOG_EXP2 661: uniform float fogDensity; 662: #else 663: uniform float fogNear; 664: uniform float fogFar; 665: #endif 666: #endif 667: uniform bool receiveShadow; 668: uniform vec3 ambientLightColor; 669: uniform vec3 lightProbe[ 9 ]; 670: vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) { 671: float x = normal.x, y = normal.y, z = normal.z; 672: vec3 result = shCoefficients[ 0 ] * 0.886227; 673: result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y; 674: result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z; 675: result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x; 676: result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y; 677: result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z; 678: result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 ); 679: result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z; 680: result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y ); 681: return result; 682: } 683: vec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) { 684: vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix ); 685: vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe ); 686: return irradiance; 687: } 688: vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { 689: vec3 irradiance = ambientLightColor; 690: #ifndef PHYSICALLY_CORRECT_LIGHTS 691: irradiance *= PI; 692: #endif 693: return irradiance; 694: } 695: #if 1 > 0 696: struct DirectionalLight { 697: vec3 direction; 698: vec3 color; 699: }; 700: uniform DirectionalLight directionalLights[ 1 ]; 701: void getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) { 702: directLight.color = directionalLight.color; 703: directLight.direction = directionalLight.direction; 704: directLight.visible = true; 705: } 706: #endif 707: #if 2 > 0 708: struct PointLight { 709: vec3 position; 710: vec3 color; 711: float distance; 712: float decay; 713: }; 714: uniform PointLight pointLights[ 2 ]; 715: void getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) { 716: vec3 lVector = pointLight.position - geometry.position; 717: directLight.direction = normalize( lVector ); 718: float lightDistance = length( lVector ); 719: directLight.color = pointLight.color; 720: directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay ); 721: directLight.visible = ( directLight.color != vec3( 0.0 ) ); 722: } 723: #endif 724: #if 0 > 0 725: struct SpotLight { 726: vec3 position; 727: vec3 direction; 728: vec3 color; 729: float distance; 730: float decay; 731: float coneCos; 732: float penumbraCos; 733: }; 734: uniform SpotLight spotLights[ 0 ]; 735: void getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) { 736: vec3 lVector = spotLight.position - geometry.position; 737: directLight.direction = normalize( lVector ); 738: float lightDistance = length( lVector ); 739: float angleCos = dot( directLight.direction, spotLight.direction ); 740: if ( angleCos > spotLight.coneCos ) { 741: float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos ); 742: directLight.color = spotLight.color; 743: directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay ); 744: directLight.visible = true; 745: } else { 746: directLight.color = vec3( 0.0 ); 747: directLight.visible = false; 748: } 749: } 750: #endif 751: #if 0 > 0 752: struct RectAreaLight { 753: vec3 color; 754: vec3 position; 755: vec3 halfWidth; 756: vec3 halfHeight; 757: }; 758: uniform sampler2D ltc_1; uniform sampler2D ltc_2; 759: uniform RectAreaLight rectAreaLights[ 0 ]; 760: #endif 761: #if 0 > 0 762: struct HemisphereLight { 763: vec3 direction; 764: vec3 skyColor; 765: vec3 groundColor; 766: }; 767: uniform HemisphereLight hemisphereLights[ 0 ]; 768: vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) { 769: float dotNL = dot( geometry.normal, hemiLight.direction ); 770: float hemiDiffuseWeight = 0.5 * dotNL + 0.5; 771: vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); 772: #ifndef PHYSICALLY_CORRECT_LIGHTS 773: irradiance *= PI; 774: #endif 775: return irradiance; 776: } 777: #endif 778: struct PhysicalMaterial { 779: vec3 diffuseColor; 780: float specularRoughness; 781: vec3 specularColor; 782: #ifdef CLEARCOAT 783: float clearcoat; 784: float clearcoatRoughness; 785: #endif 786: #ifdef USE_SHEEN 787: vec3 sheenColor; 788: #endif 789: }; 790: #define MAXIMUM_SPECULAR_COEFFICIENT 0.16 791: #define DEFAULT_SPECULAR_COEFFICIENT 0.04 792: float clearcoatDHRApprox( const in float roughness, const in float dotNL ) { 793: return DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) ); 794: } 795: #if 0 > 0 796: void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 797: vec3 normal = geometry.normal; 798: vec3 viewDir = geometry.viewDir; 799: vec3 position = geometry.position; 800: vec3 lightPos = rectAreaLight.position; 801: vec3 halfWidth = rectAreaLight.halfWidth; 802: vec3 halfHeight = rectAreaLight.halfHeight; 803: vec3 lightColor = rectAreaLight.color; 804: float roughness = material.specularRoughness; 805: vec3 rectCoords[ 4 ]; 806: rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; rectCoords[ 1 ] = lightPos - halfWidth - halfHeight; 807: rectCoords[ 2 ] = lightPos - halfWidth + halfHeight; 808: rectCoords[ 3 ] = lightPos + halfWidth + halfHeight; 809: vec2 uv = LTC_Uv( normal, viewDir, roughness ); 810: vec4 t1 = texture2D( ltc_1, uv ); 811: vec4 t2 = texture2D( ltc_2, uv ); 812: mat3 mInv = mat3( 813: vec3( t1.x, 0, t1.y ), 814: vec3( 0, 1, 0 ), 815: vec3( t1.z, 0, t1.w ) 816: ); 817: vec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y ); 818: reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords ); 819: reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords ); 820: } 821: #endif 822: void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 823: float dotNL = saturate( dot( geometry.normal, directLight.direction ) ); 824: vec3 irradiance = dotNL * directLight.color; 825: #ifndef PHYSICALLY_CORRECT_LIGHTS 826: irradiance *= PI; 827: #endif 828: #ifdef CLEARCOAT 829: float ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) ); 830: vec3 ccIrradiance = ccDotNL * directLight.color; 831: #ifndef PHYSICALLY_CORRECT_LIGHTS 832: ccIrradiance *= PI; 833: #endif 834: float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL ); 835: reflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness ); 836: #else 837: float clearcoatDHR = 0.0; 838: #endif 839: #ifdef USE_SHEEN 840: reflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen( 841: material.specularRoughness, 842: directLight.direction, 843: geometry, 844: material.sheenColor 845: ); 846: #else 847: reflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness); 848: #endif 849: reflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); 850: } 851: void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { 852: reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor ); 853: } 854: void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) { 855: #ifdef CLEARCOAT 856: float ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) ); 857: reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness ); 858: float ccDotNL = ccDotNV; 859: float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL ); 860: #else 861: float clearcoatDHR = 0.0; 862: #endif 863: float clearcoatInv = 1.0 - clearcoatDHR; 864: vec3 singleScattering = vec3( 0.0 ); 865: vec3 multiScattering = vec3( 0.0 ); 866: vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI; 867: BRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering ); 868: vec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) ); 869: reflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering; 870: reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance; 871: reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance; 872: } 873: #define RE_Direct RE_Direct_Physical 874: #define RE_Direct_RectArea RE_Direct_RectArea_Physical 875: #define RE_IndirectDiffuse RE_IndirectDiffuse_Physical 876: #define RE_IndirectSpecular RE_IndirectSpecular_Physical 877: float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) { 878: return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); 879: } 880: #ifdef USE_SHADOWMAP 881: #define LIGHT_WORLD_SIZE 0.005 882: #define LIGHT_FRUSTUM_WIDTH 20.75 883: #define LIGHT_SIZE_UV (LIGHT_WORLD_SIZE / LIGHT_FRUSTUM_WIDTH) 884: #define NEAR_PLANE 10.5 885: 886: #define NUM_SAMPLES 20.1 887: #define NUM_RINGS 0.5 888: #define BLOCKER_SEARCH_NUM_SAMPLES NUM_SAMPLES 889: #define PCF_NUM_SAMPLES NUM_SAMPLES 890: 891: vec2 poissonDisk[NUM_SAMPLES]; 892: 893: void initPoissonSamples(const in vec2 randomSeed) { 894: float ANGLE_STEP = PI2 * float(NUM_RINGS) / float(NUM_SAMPLES); 895: float INV_NUM_SAMPLES = 1.0 / float(NUM_SAMPLES); 896: float angle = rand(randomSeed) * PI2; 897: float radius = INV_NUM_SAMPLES; 898: float radiusStep = radius; 899: for (int i = 0; i < NUM_SAMPLES; i++) { 900: poissonDisk[i] = vec2(cos(angle), sin(angle)) * pow(radius, 0.75); 901: radius += radiusStep; 902: angle += ANGLE_STEP; 903: } 904: } 905: 906: float penumbraSize(const in float zReceiver, const in float zBlocker) { // Parallel plane estimation 907: return (zReceiver - zBlocker) / zBlocker; 908: } 909: 910: float findBlocker(sampler2D shadowMap, const in vec2 uv, const in float zReceiver) { 911: float searchRadius = LIGHT_SIZE_UV * (zReceiver - NEAR_PLANE) / zReceiver; 912: float blockerDepthSum = 0.0; 913: int numBlockers = 0; 914: for (int i = 0; i < BLOCKER_SEARCH_NUM_SAMPLES; i++) { 915: float shadowMapDepth = unpackRGBAToDepth(texture2D(shadowMap, uv + poissonDisk[i] * searchRadius)); 916: if (shadowMapDepth < zReceiver) { 917: blockerDepthSum += shadowMapDepth; 918: numBlockers++; 919: } 920: } 921: if (numBlockers == 0) return -1.0; 922: return blockerDepthSum / float(numBlockers); 923: } 924: 925: float PCF_Filter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRadius) { 926: float sum = 0.0; 927: for (int i = 0; i < PCF_NUM_SAMPLES; i++) { 928: float depth = unpackRGBAToDepth(texture2D(shadowMap, uv + poissonDisk[ i ] * filterRadius)); 929: if (zReceiver <= depth) sum += 1.0; 930: } 931: for (int i = 0; i < PCF_NUM_SAMPLES; i++) { 932: float depth = unpackRGBAToDepth(texture2D(shadowMap, uv + -poissonDisk[ i ].yx * filterRadius)); 933: if (zReceiver <= depth) sum += 1.0; 934: } 935: return sum / (2.0 * float(PCF_NUM_SAMPLES)); 936: } 937: 938: float PCSS(sampler2D shadowMap, vec4 coords) { 939: vec2 uv = coords.xy; 940: float zReceiver = coords.z; // Assumed to be eye-space z in this code 941: initPoissonSamples(uv); 942: float avgBlockerDepth = findBlocker(shadowMap, uv, zReceiver); 943: if (avgBlockerDepth == -1.0) return 1.0; 944: float penumbraRatio = penumbraSize(zReceiver, avgBlockerDepth); 945: float filterRadius = penumbraRatio * LIGHT_SIZE_UV * NEAR_PLANE / zReceiver; 946: return PCF_Filter(shadowMap, uv, zReceiver, filterRadius); 947: } 948: #if 1 > 0 949: uniform sampler2D directionalShadowMap[ 1 ]; 950: varying vec4 vDirectionalShadowCoord[ 1 ]; 951: struct DirectionalLightShadow { 952: float shadowBias; 953: float shadowNormalBias; 954: float shadowRadius; 955: vec2 shadowMapSize; 956: }; 957: uniform DirectionalLightShadow directionalLightShadows[ 1 ]; 958: #endif 959: #if 0 > 0 960: uniform sampler2D spotShadowMap[ 0 ]; 961: varying vec4 vSpotShadowCoord[ 0 ]; 962: struct SpotLightShadow { 963: float shadowBias; 964: float shadowNormalBias; 965: float shadowRadius; 966: vec2 shadowMapSize; 967: }; 968: uniform SpotLightShadow spotLightShadows[ 0 ]; 969: #endif 970: #if 0 > 0 971: uniform sampler2D pointShadowMap[ 0 ]; 972: varying vec4 vPointShadowCoord[ 0 ]; 973: struct PointLightShadow { 974: float shadowBias; 975: float shadowNormalBias; 976: float shadowRadius; 977: vec2 shadowMapSize; 978: float shadowCameraNear; 979: float shadowCameraFar; 980: }; 981: uniform PointLightShadow pointLightShadows[ 0 ]; 982: #endif 983: float texture2DCompare( sampler2D depths, vec2 uv, float compare ) { 984: return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) ); 985: } 986: vec2 texture2DDistribution( sampler2D shadow, vec2 uv ) { 987: return unpackRGBATo2Half( texture2D( shadow, uv ) ); 988: } 989: float VSMShadow (sampler2D shadow, vec2 uv, float compare ){ 990: float occlusion = 1.0; 991: vec2 distribution = texture2DDistribution( shadow, uv ); 992: float hard_shadow = step( compare , distribution.x ); 993: if (hard_shadow != 1.0 ) { 994: float distance = compare - distribution.x ; 995: float variance = max( 0.00000, distribution.y * distribution.y ); 996: float softness_probability = variance / (variance + distance * distance ); softness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 ); occlusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 ); 997: } 998: return occlusion; 999: } 1000: float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) { 1001: float shadow = 1.0; 1002: shadowCoord.xyz /= shadowCoord.w; 1003: shadowCoord.z += shadowBias; 1004: bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 ); 1005: bool inFrustum = all( inFrustumVec ); 1006: bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 ); 1007: bool frustumTest = all( frustumTestVec ); 1008: if ( frustumTest ) { 1009: 1010: return PCSS(shadowMap, shadowCoord); 1011: #if defined( SHADOWMAP_TYPE_PCF ) 1012: vec2 texelSize = vec2( 1.0 ) / shadowMapSize; 1013: float dx0 = - texelSize.x * shadowRadius; 1014: float dy0 = - texelSize.y * shadowRadius; 1015: float dx1 = + texelSize.x * shadowRadius; 1016: float dy1 = + texelSize.y * shadowRadius; 1017: float dx2 = dx0 / 2.0; 1018: float dy2 = dy0 / 2.0; 1019: float dx3 = dx1 / 2.0; 1020: float dy3 = dy1 / 2.0; 1021: shadow = ( 1022: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) + 1023: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) + 1024: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) + 1025: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) + 1026: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) + 1027: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) + 1028: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) + 1029: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) + 1030: texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) + 1031: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) + 1032: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) + 1033: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) + 1034: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) + 1035: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) + 1036: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) + 1037: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) + 1038: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z ) 1039: ) * ( 1.0 / 17.0 ); 1040: #elif defined( SHADOWMAP_TYPE_PCF_SOFT ) 1041: vec2 texelSize = vec2( 1.0 ) / shadowMapSize; 1042: float dx = texelSize.x; 1043: float dy = texelSize.y; 1044: vec2 uv = shadowCoord.xy; 1045: vec2 f = fract( uv * shadowMapSize + 0.5 ); 1046: uv -= f * texelSize; 1047: shadow = ( 1048: texture2DCompare( shadowMap, uv, shadowCoord.z ) + 1049: texture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) + 1050: texture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) + 1051: texture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) + 1052: mix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), 1053: texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ), 1054: f.x ) + 1055: mix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), 1056: texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ), 1057: f.x ) + 1058: mix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), 1059: texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ), 1060: f.y ) + 1061: mix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), 1062: texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ), 1063: f.y ) + 1064: mix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), 1065: texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ), 1066: f.x ), 1067: mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), 1068: texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ), 1069: f.x ), 1070: f.y ) 1071: ) * ( 1.0 / 9.0 ); 1072: #elif defined( SHADOWMAP_TYPE_VSM ) 1073: shadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z ); 1074: #else 1075: shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ); 1076: #endif 1077: } 1078: return shadow; 1079: } 1080: vec2 cubeToUV( vec3 v, float texelSizeY ) { 1081: vec3 absV = abs( v ); 1082: float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) ); 1083: absV *= scaleToCube; 1084: v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY ); 1085: vec2 planar = v.xy; 1086: float almostATexel = 1.5 * texelSizeY; 1087: float almostOne = 1.0 - almostATexel; 1088: if ( absV.z >= almostOne ) { 1089: if ( v.z > 0.0 ) 1090: planar.x = 4.0 - v.x; 1091: } else if ( absV.x >= almostOne ) { 1092: float signX = sign( v.x ); 1093: planar.x = v.z * signX + 2.0 * signX; 1094: } else if ( absV.y >= almostOne ) { 1095: float signY = sign( v.y ); 1096: planar.x = v.x + 2.0 * signY + 2.0; 1097: planar.y = v.z * signY - 2.0; 1098: } 1099: return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 ); 1100: } 1101: float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) { 1102: vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) ); 1103: vec3 lightToPosition = shadowCoord.xyz; 1104: float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); dp += shadowBias; 1105: vec3 bd3D = normalize( lightToPosition ); 1106: #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM ) 1107: vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y; 1108: return ( 1109: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) + 1110: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) + 1111: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) + 1112: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) + 1113: texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) + 1114: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) + 1115: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) + 1116: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) + 1117: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp ) 1118: ) * ( 1.0 / 9.0 ); 1119: #else 1120: return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ); 1121: #endif 1122: } 1123: #endif 1124: #ifdef USE_BUMPMAP 1125: uniform sampler2D bumpMap; 1126: uniform float bumpScale; 1127: vec2 dHdxy_fwd() { 1128: vec2 dSTdx = dFdx( vUv ); 1129: vec2 dSTdy = dFdy( vUv ); 1130: float Hll = bumpScale * texture2D( bumpMap, vUv ).x; 1131: float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll; 1132: float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll; 1133: return vec2( dBx, dBy ); 1134: } 1135: vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) { 1136: vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) ); 1137: vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) ); 1138: vec3 vN = surf_norm; 1139: vec3 R1 = cross( vSigmaY, vN ); 1140: vec3 R2 = cross( vN, vSigmaX ); 1141: float fDet = dot( vSigmaX, R1 ); 1142: fDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 1143: vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 ); 1144: return normalize( abs( fDet ) * surf_norm - vGrad ); 1145: } 1146: #endif 1147: #ifdef USE_NORMALMAP 1148: uniform sampler2D normalMap; 1149: uniform vec2 normalScale; 1150: #endif 1151: #ifdef OBJECTSPACE_NORMALMAP 1152: uniform mat3 normalMatrix; 1153: #endif 1154: #if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) ) 1155: vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) { 1156: vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) ); 1157: vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) ); 1158: vec2 st0 = dFdx( vUv.st ); 1159: vec2 st1 = dFdy( vUv.st ); 1160: float scale = sign( st1.t * st0.s - st0.t * st1.s ); 1161: vec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale ); 1162: vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale ); 1163: vec3 N = normalize( surf_norm ); 1164: mat3 tsn = mat3( S, T, N ); 1165: mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 1166: return normalize( tsn * mapN ); 1167: } 1168: #endif 1169: #ifdef USE_CLEARCOATMAP 1170: uniform sampler2D clearcoatMap; 1171: #endif 1172: #ifdef USE_CLEARCOAT_ROUGHNESSMAP 1173: uniform sampler2D clearcoatRoughnessMap; 1174: #endif 1175: #ifdef USE_CLEARCOAT_NORMALMAP 1176: uniform sampler2D clearcoatNormalMap; 1177: uniform vec2 clearcoatNormalScale; 1178: #endif 1179: #ifdef USE_ROUGHNESSMAP 1180: uniform sampler2D roughnessMap; 1181: #endif 1182: #ifdef USE_METALNESSMAP 1183: uniform sampler2D metalnessMap; 1184: #endif 1185: #if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT ) 1186: uniform float logDepthBufFC; 1187: varying float vFragDepth; 1188: varying float vIsPerspective; 1189: #endif 1190: #if 0 > 0 1191: varying vec3 vClipPosition; 1192: uniform vec4 clippingPlanes[ 0 ]; 1193: #endif 1194: void main() { 1195: #if 0 > 0 1196: vec4 plane; 1197: 1198: #if 0 < 0 1199: bool clipped = true; 1200: 1201: if ( clipped ) discard; 1202: #endif 1203: #endif 1204: vec4 diffuseColor = vec4( diffuse, opacity ); 1205: ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); 1206: vec3 totalEmissiveRadiance = emissive; 1207: #ifdef TRANSMISSION 1208: float totalTransmission = transmission; 1209: #endif 1210: #if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT ) 1211: gl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5; 1212: #endif 1213: #ifdef USE_MAP 1214: vec4 texelColor = texture2D( map, vUv ); 1215: texelColor = mapTexelToLinear( texelColor ); 1216: diffuseColor *= texelColor; 1217: #endif 1218: #ifdef USE_COLOR 1219: diffuseColor.rgb *= vColor; 1220: #endif 1221: #ifdef USE_ALPHAMAP 1222: diffuseColor.a *= texture2D( alphaMap, vUv ).g; 1223: #endif 1224: #ifdef ALPHATEST 1225: if ( diffuseColor.a < ALPHATEST ) discard; 1226: #endif 1227: float roughnessFactor = roughness; 1228: #ifdef USE_ROUGHNESSMAP 1229: vec4 texelRoughness = texture2D( roughnessMap, vUv ); 1230: roughnessFactor *= texelRoughness.g; 1231: #endif 1232: float metalnessFactor = metalness; 1233: #ifdef USE_METALNESSMAP 1234: vec4 texelMetalness = texture2D( metalnessMap, vUv ); 1235: metalnessFactor *= texelMetalness.b; 1236: #endif 1237: #ifdef FLAT_SHADED 1238: vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) ); 1239: vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) ); 1240: vec3 normal = normalize( cross( fdx, fdy ) ); 1241: #else 1242: vec3 normal = normalize( vNormal ); 1243: #ifdef DOUBLE_SIDED 1244: normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 1245: #endif 1246: #ifdef USE_TANGENT 1247: vec3 tangent = normalize( vTangent ); 1248: vec3 bitangent = normalize( vBitangent ); 1249: #ifdef DOUBLE_SIDED 1250: tangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 1251: bitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 1252: #endif 1253: #if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) 1254: mat3 vTBN = mat3( tangent, bitangent, normal ); 1255: #endif 1256: #endif 1257: #endif 1258: vec3 geometryNormal = normal; 1259: #ifdef OBJECTSPACE_NORMALMAP 1260: normal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; 1261: #ifdef FLIP_SIDED 1262: normal = - normal; 1263: #endif 1264: #ifdef DOUBLE_SIDED 1265: normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 ); 1266: #endif 1267: normal = normalize( normalMatrix * normal ); 1268: #elif defined( TANGENTSPACE_NORMALMAP ) 1269: vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; 1270: mapN.xy *= normalScale; 1271: #ifdef USE_TANGENT 1272: normal = normalize( vTBN * mapN ); 1273: #else 1274: normal = perturbNormal2Arb( -vViewPosition, normal, mapN ); 1275: #endif 1276: #elif defined( USE_BUMPMAP ) 1277: normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() ); 1278: #endif 1279: #ifdef CLEARCOAT 1280: vec3 clearcoatNormal = geometryNormal; 1281: #endif 1282: #ifdef USE_CLEARCOAT_NORMALMAP 1283: vec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0; 1284: clearcoatMapN.xy *= clearcoatNormalScale; 1285: #ifdef USE_TANGENT 1286: clearcoatNormal = normalize( vTBN * clearcoatMapN ); 1287: #else 1288: clearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN ); 1289: #endif 1290: #endif 1291: #ifdef USE_EMISSIVEMAP 1292: vec4 emissiveColor = texture2D( emissiveMap, vUv ); 1293: emissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb; 1294: totalEmissiveRadiance *= emissiveColor.rgb; 1295: #endif 1296: #ifdef USE_TRANSMISSIONMAP 1297: totalTransmission *= texture2D( transmissionMap, vUv ).r; 1298: #endif 1299: PhysicalMaterial material; 1300: material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); 1301: vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) ); 1302: float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z ); 1303: material.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness; 1304: material.specularRoughness = min( material.specularRoughness, 1.0 ); 1305: #ifdef REFLECTIVITY 1306: material.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor ); 1307: #else 1308: material.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor ); 1309: #endif 1310: #ifdef CLEARCOAT 1311: material.clearcoat = clearcoat; 1312: material.clearcoatRoughness = clearcoatRoughness; 1313: #ifdef USE_CLEARCOATMAP 1314: material.clearcoat *= texture2D( clearcoatMap, vUv ).x; 1315: #endif 1316: #ifdef USE_CLEARCOAT_ROUGHNESSMAP 1317: material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y; 1318: #endif 1319: material.clearcoat = saturate( material.clearcoat ); material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 ); 1320: material.clearcoatRoughness += geometryRoughness; 1321: material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 ); 1322: #endif 1323: #ifdef USE_SHEEN 1324: material.sheenColor = sheen; 1325: #endif 1326: 1327: GeometricContext geometry; 1328: geometry.position = - vViewPosition; 1329: geometry.normal = normal; 1330: geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition ); 1331: #ifdef CLEARCOAT 1332: geometry.clearcoatNormal = clearcoatNormal; 1333: #endif 1334: IncidentLight directLight; 1335: #if ( 2 > 0 ) && defined( RE_Direct ) 1336: PointLight pointLight; 1337: #if defined( USE_SHADOWMAP ) && 0 > 0 1338: PointLightShadow pointLightShadow; 1339: #endif 1340: 1341: pointLight = pointLights[ 0 ]; 1342: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1343: #if defined( USE_SHADOWMAP ) && ( 0 < 0 ) 1344: pointLightShadow = pointLightShadows[ 0 ]; 1345: directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ 0 ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ 0 ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0; 1346: #endif 1347: RE_Direct( directLight, geometry, material, reflectedLight ); 1348: 1349: pointLight = pointLights[ 1 ]; 1350: getPointDirectLightIrradiance( pointLight, geometry, directLight ); 1351: #if defined( USE_SHADOWMAP ) && ( 1 < 0 ) 1352: pointLightShadow = pointLightShadows[ 1 ]; 1353: directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ 1 ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ 1 ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0; 1354: #endif 1355: RE_Direct( directLight, geometry, material, reflectedLight ); 1356: 1357: #endif 1358: #if ( 0 > 0 ) && defined( RE_Direct ) 1359: SpotLight spotLight; 1360: #if defined( USE_SHADOWMAP ) && 0 > 0 1361: SpotLightShadow spotLightShadow; 1362: #endif 1363: 1364: #endif 1365: #if ( 1 > 0 ) && defined( RE_Direct ) 1366: DirectionalLight directionalLight; 1367: #if defined( USE_SHADOWMAP ) && 1 > 0 1368: DirectionalLightShadow directionalLightShadow; 1369: #endif 1370: 1371: directionalLight = directionalLights[ 0 ]; 1372: getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight ); 1373: #if defined( USE_SHADOWMAP ) && ( 0 < 1 ) 1374: directionalLightShadow = directionalLightShadows[ 0 ]; 1375: directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ 0 ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ 0 ] ) : 1.0; 1376: #endif 1377: RE_Direct( directLight, geometry, material, reflectedLight ); 1378: 1379: #endif 1380: #if ( 0 > 0 ) && defined( RE_Direct_RectArea ) 1381: RectAreaLight rectAreaLight; 1382: 1383: #endif 1384: #if defined( RE_IndirectDiffuse ) 1385: vec3 iblIrradiance = vec3( 0.0 ); 1386: vec3 irradiance = getAmbientLightIrradiance( ambientLightColor ); 1387: irradiance += getLightProbeIrradiance( lightProbe, geometry ); 1388: #if ( 0 > 0 ) 1389: 1390: #endif 1391: #endif 1392: #if defined( RE_IndirectSpecular ) 1393: vec3 radiance = vec3( 0.0 ); 1394: vec3 clearcoatRadiance = vec3( 0.0 ); 1395: #endif 1396: #if defined( RE_IndirectDiffuse ) 1397: #ifdef USE_LIGHTMAP 1398: vec4 lightMapTexel= texture2D( lightMap, vUv2 ); 1399: vec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity; 1400: #ifndef PHYSICALLY_CORRECT_LIGHTS 1401: lightMapIrradiance *= PI; 1402: #endif 1403: irradiance += lightMapIrradiance; 1404: #endif 1405: #if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV ) 1406: iblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel ); 1407: #endif 1408: #endif 1409: #if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular ) 1410: radiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel ); 1411: #ifdef CLEARCOAT 1412: clearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel ); 1413: #endif 1414: #endif 1415: #if defined( RE_IndirectDiffuse ) 1416: RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight ); 1417: #endif 1418: #if defined( RE_IndirectSpecular ) 1419: RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight ); 1420: #endif 1421: #ifdef USE_AOMAP 1422: float ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0; 1423: reflectedLight.indirectDiffuse *= ambientOcclusion; 1424: #if defined( USE_ENVMAP ) && defined( STANDARD ) 1425: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) ); 1426: reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness ); 1427: #endif 1428: #endif 1429: vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; 1430: #ifdef TRANSMISSION 1431: diffuseColor.a *= mix( saturate( 1. - totalTransmission + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) ), 1.0, metalness ); 1432: #endif 1433: gl_FragColor = vec4( outgoingLight, diffuseColor.a ); 1434: #if defined( TONE_MAPPING ) 1435: gl_FragColor.rgb = toneMapping( gl_FragColor.rgb ); 1436: #endif 1437: gl_FragColor = linearToOutputTexel( gl_FragColor ); 1438: #ifdef USE_FOG 1439: #ifdef FOG_EXP2 1440: float fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth ); 1441: #else 1442: float fogFactor = smoothstep( fogNear, fogFar, fogDepth ); 1443: #endif 1444: gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor ); 1445: #endif 1446: #ifdef PREMULTIPLIED_ALPHA 1447: gl_FragColor.rgb *= gl_FragColor.a; 1448: #endif 1449: #ifdef DITHERING 1450: gl_FragColor.rgb = dithering( gl_FragColor.rgb ); 1451: #endif 1452: }

The error occurs when

  1. frustrum is an integer
  2. samples is more than 20
softShadows({ frustrum: 24, size: 0.005, near: 10.5, samples: 20.1, rings: 0.5 });

export default function Canvas(){
    ...

Suggested Solution:

A hint for input limitation or allow Three functions normally when frustrum is an integer or samples is more than 20.

joshuaellis commented 3 years ago

Hi @SiegeSailor, do you have an mwe that you can share please?

gsimone commented 3 years ago

frustum should always be float samples should always be int

Sandbox: https://codesandbox.io/s/laughing-minsky-9p93n?file=/src/index.js

joshuaellis commented 3 years ago

Whilst this isn't a bug, I have update the documentation to reflect what @gsimone has written above.

SiegeSailor commented 3 years ago

frustum should always be float samples should always be int

Thanks. I will keep this in mind.