我今天发现, webgl_shaders_ocean的当前dev
版本不适用于Firefox 55.0.2和Ubuntu 16.04 LTS。 水没有出现,我在浏览器控制台中看到一些错误消息。
0:102(109): error: sampler arrays indexed with non-constant expressions are forbidden in GLSL 1.30 and later
和
Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation with -1 vertices. Try reducing the number of vertices.
Drawing without vertex attrib 0 array enabled forces the browser to do expensive emulation work when running on desktop OpenGL platforms, for example on Mac. It is preferable to always draw with vertex attrib 0 array enabled, by using bindAttribLocation to bind some always-used attribute to location 0.
Chromium不会发生此问题。 此外, webgl_shaders_ocean
的实时版本也有效。 因此,自THREE.Water
的最新更改以来,可能存在此错误,请参阅#12167。 如果我还原PR,则不会出现错误。
/ ping @阿斯特拉克
我刚刚在FF 52.4和FF 58.0的Debian 9.1上的当前dev
分支中运行了示例,这没有发生。
PR中的几何形状变化不大,片段着色器仅包含调用getShadowMask()
所需的块。
错误消息是否记录0:102(109)
?
不幸的是没有。 记录的片段着色器在第27行之后被切断:
如果我删除片段着色器( THREE.Water
)中的着色器块并调用getShadowMask()
,则错误消失。
不幸的是没有。 记录的片段着色器在第27行之后被截断
对此问题表示歉意,但是在着色器日志的末尾是否有_ [...] _被截断了?
@moraxy感谢您的建议! 当我单击_ [...] _时,我可以看到整个程序。
这是整个片段着色器:
THREE.WebGLShader: Shader couldn't compile.
THREE.WebGLShader: gl.getShaderInfoLog() fragment 0:2(12): warning: extension `GL_ARB_gpu_shader5' unsupported in fragment shader
0:102(109): error: sampler arrays indexed with non-constant expressions are forbidden in GLSL 1.30 and later
1: precision highp float;
2: precision highp int;
3: #define SHADER_NAME ShaderMaterial
4: #define GAMMA_FACTOR 2
5: #define USE_FOG
6: #define FOG_EXP2
7: #define NUM_CLIPPING_PLANES 0
8: #define UNION_CLIPPING_PLANES 0
9: #define USE_SHADOWMAP
10: #define SHADOWMAP_TYPE_PCF
11: uniform mat4 viewMatrix;
12: uniform vec3 cameraPosition;
13: #define TONE_MAPPING
14: #define saturate(a) clamp( a, 0.0, 1.0 )
15: uniform float toneMappingExposure;
16: uniform float toneMappingWhitePoint;
17: vec3 LinearToneMapping( vec3 color ) {
18: return toneMappingExposure * color;
19: }
20: vec3 ReinhardToneMapping( vec3 color ) {
21: color *= toneMappingExposure;
22: return saturate( color / ( vec3( 1.0 ) + color ) );
23: }
24: #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 ) )
25: vec3 Uncharted2ToneMapping( vec3 color ) {
26: color *= toneMappingExposure;
27: return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );
28: }
29: vec3 OptimizedCineonToneMapping( vec3 color ) {
30: color *= toneMappingExposure;
31: color = max( vec3( 0.0 ), color - 0.004 );
32: return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );
33: }
34:
35: vec3 toneMapping( vec3 color ) { return LinearToneMapping( color ); }
36:
37: vec4 LinearToLinear( in vec4 value ) {
38: return value;
39: }
40: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
41: return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );
42: }
43: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
44: return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );
45: }
46: vec4 sRGBToLinear( in vec4 value ) {
47: 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.w );
48: }
49: vec4 LinearTosRGB( in vec4 value ) {
50: 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.w );
51: }
52: vec4 RGBEToLinear( in vec4 value ) {
53: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
54: }
55: vec4 LinearToRGBE( in vec4 value ) {
56: float maxComponent = max( max( value.r, value.g ), value.b );
57: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
58: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
59: }
60: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
61: return vec4( value.xyz * value.w * maxRange, 1.0 );
62: }
63: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
64: float maxRGB = max( value.x, max( value.g, value.b ) );
65: float M = clamp( maxRGB / maxRange, 0.0, 1.0 );
66: M = ceil( M * 255.0 ) / 255.0;
67: return vec4( value.rgb / ( M * maxRange ), M );
68: }
69: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
70: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
71: }
72: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
73: float maxRGB = max( value.x, max( value.g, value.b ) );
74: float D = max( maxRange / maxRGB, 1.0 );
75: D = min( floor( D ) / 255.0, 1.0 );
76: return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
77: }
78: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
79: vec4 LinearToLogLuv( in vec4 value ) {
80: vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;
81: Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));
82: vec4 vResult;
83: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
84: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
85: vResult.w = fract(Le);
86: vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;
87: return vResult;
88: }
89: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
90: vec4 LogLuvToLinear( in vec4 value ) {
91: float Le = value.z * 255.0 + value.w;
92: vec3 Xp_Y_XYZp;
93: Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);
94: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
95: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
96: vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;
97: return vec4( max(vRGB, 0.0), 1.0 );
98: }
99:
100: vec4 mapTexelToLinear( vec4 value ) { return LinearToLinear( value ); }
101: vec4 envMapTexelToLinear( vec4 value ) { return LinearToLinear( value ); }
102: vec4 emissiveMapTexelToLinear( vec4 value ) { return LinearToLinear( value ); }
103: vec4 linearToOutputTexel( vec4 value ) { return LinearToLinear( value ); }
104:
105: uniform sampler2D mirrorSampler;
106: uniform float alpha;
107: uniform float time;
108: uniform float size;
109: uniform float distortionScale;
110: uniform sampler2D normalSampler;
111: uniform vec3 sunColor;
112: uniform vec3 sunDirection;
113: uniform vec3 eye;
114: uniform vec3 waterColor;
115: varying vec4 mirrorCoord;
116: varying vec4 worldPosition;
117: vec4 getNoise( vec2 uv ) {
118: vec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0, time / 29.0);
119: vec2 uv1 = uv / 107.0-vec2( time / -19.0, time / 31.0 );
120: vec2 uv2 = uv / vec2( 8907.0, 9803.0 ) + vec2( time / 101.0, time / 97.0 );
121: vec2 uv3 = uv / vec2( 1091.0, 1027.0 ) - vec2( time / 109.0, time / -113.0 );
122: vec4 noise = texture2D( normalSampler, uv0 ) +
123: texture2D( normalSampler, uv1 ) +
124: texture2D( normalSampler, uv2 ) +
125: texture2D( normalSampler, uv3 );
126: return noise * 0.5 - 1.0;
127: }
128: void sunLight( const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor ) {
129: vec3 reflection = normalize( reflect( -sunDirection, surfaceNormal ) );
130: float direction = max( 0.0, dot( eyeDirection, reflection ) );
131: specularColor += pow( direction, shiny ) * sunColor * spec;
132: diffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;
133: }
134: #define PI 3.14159265359
135: #define PI2 6.28318530718
136: #define PI_HALF 1.5707963267949
137: #define RECIPROCAL_PI 0.31830988618
138: #define RECIPROCAL_PI2 0.15915494
139: #define LOG2 1.442695
140: #define EPSILON 1e-6
141: #define saturate(a) clamp( a, 0.0, 1.0 )
142: #define whiteCompliment(a) ( 1.0 - saturate( a ) )
143: float pow2( const in float x ) { return x*x; }
144: float pow3( const in float x ) { return x*x*x; }
145: float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
146: float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
147: highp float rand( const in vec2 uv ) {
148: const highp float a = 12.9898, b = 78.233, c = 43758.5453;
149: highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
150: return fract(sin(sn) * c);
151: }
152: struct IncidentLight {
153: vec3 color;
154: vec3 direction;
155: bool visible;
156: };
157: struct ReflectedLight {
158: vec3 directDiffuse;
159: vec3 directSpecular;
160: vec3 indirectDiffuse;
161: vec3 indirectSpecular;
162: };
163: struct GeometricContext {
164: vec3 position;
165: vec3 normal;
166: vec3 viewDir;
167: };
168: vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
169: return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
170: }
171: vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
172: return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
173: }
174: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
175: float distance = dot( planeNormal, point - pointOnPlane );
176: return - distance * planeNormal + point;
177: }
178: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
179: return sign( dot( point - pointOnPlane, planeNormal ) );
180: }
181: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
182: return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
183: }
184: mat3 transposeMat3( const in mat3 m ) {
185: mat3 tmp;
186: tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );
187: tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );
188: tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );
189: return tmp;
190: }
191: float linearToRelativeLuminance( const in vec3 color ) {
192: vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );
193: return dot( weights, color.rgb );
194: }
195:
196: vec3 packNormalToRGB( const in vec3 normal ) {
197: return normalize( normal ) * 0.5 + 0.5;
198: }
199: vec3 unpackRGBToNormal( const in vec3 rgb ) {
200: return 2.0 * rgb.xyz - 1.0;
201: }
202: const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;
203: const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );
204: const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
205: const float ShiftRight8 = 1. / 256.;
206: vec4 packDepthToRGBA( const in float v ) {
207: vec4 r = vec4( fract( v * PackFactors ), v );
208: r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale;
209: }
210: float unpackRGBAToDepth( const in vec4 v ) {
211: return dot( v, UnpackFactors );
212: }
213: float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {
214: return ( viewZ + near ) / ( near - far );
215: }
216: float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {
217: return linearClipZ * ( near - far ) - near;
218: }
219: float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {
220: return (( near + viewZ ) * far ) / (( far - near ) * viewZ );
221: }
222: float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {
223: return ( near * far ) / ( ( far - near ) * invClipZ - far );
224: }
225:
226: float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
227: if( decayExponent > 0.0 ) {
228: #if defined ( PHYSICALLY_CORRECT_LIGHTS )
229: float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );
230: float maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );
231: return distanceFalloff * maxDistanceCutoffFactor;
232: #else
233: return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );
234: #endif
235: }
236: return 1.0;
237: }
238: vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {
239: return RECIPROCAL_PI * diffuseColor;
240: }
241: vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {
242: float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );
243: return ( 1.0 - specularColor ) * fresnel + specularColor;
244: }
245: float G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {
246: float a2 = pow2( alpha );
247: float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );
248: float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );
249: return 1.0 / ( gl * gv );
250: }
251: float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {
252: float a2 = pow2( alpha );
253: float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );
254: float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );
255: return 0.5 / max( gv + gl, EPSILON );
256: }
257: float D_GGX( const in float alpha, const in float dotNH ) {
258: float a2 = pow2( alpha );
259: float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;
260: return RECIPROCAL_PI * a2 / pow2( denom );
261: }
262: vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {
263: float alpha = pow2( roughness );
264: vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );
265: float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );
266: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
267: float dotNH = saturate( dot( geometry.normal, halfDir ) );
268: float dotLH = saturate( dot( incidentLight.direction, halfDir ) );
269: vec3 F = F_Schlick( specularColor, dotLH );
270: float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );
271: float D = D_GGX( alpha, dotNH );
272: return F * ( G * D );
273: }
274: vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {
275: const float LUT_SIZE = 64.0;
276: const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;
277: const float LUT_BIAS = 0.5 / LUT_SIZE;
278: float theta = acos( dot( N, V ) );
279: vec2 uv = vec2(
280: sqrt( saturate( roughness ) ),
281: saturate( theta / ( 0.5 * PI ) ) );
282: uv = uv * LUT_SCALE + LUT_BIAS;
283: return uv;
284: }
285: float LTC_ClippedSphereFormFactor( const in vec3 f ) {
286: float l = length( f );
287: return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );
288: }
289: vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {
290: float x = dot( v1, v2 );
291: float y = abs( x );
292: float a = 0.86267 + (0.49788 + 0.01436 * y ) * y;
293: float b = 3.45068 + (4.18814 + y) * y;
294: float v = a / b;
295: float theta_sintheta = (x > 0.0) ? v : 0.5 * inversesqrt( 1.0 - x * x ) - v;
296: return cross( v1, v2 ) * theta_sintheta;
297: }
298: vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {
299: vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];
300: vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];
301: vec3 lightNormal = cross( v1, v2 );
302: if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );
303: vec3 T1, T2;
304: T1 = normalize( V - N * dot( V, N ) );
305: T2 = - cross( N, T1 );
306: mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );
307: vec3 coords[ 4 ];
308: coords[ 0 ] = mat * ( rectCoords[ 0 ] - P );
309: coords[ 1 ] = mat * ( rectCoords[ 1 ] - P );
310: coords[ 2 ] = mat * ( rectCoords[ 2 ] - P );
311: coords[ 3 ] = mat * ( rectCoords[ 3 ] - P );
312: coords[ 0 ] = normalize( coords[ 0 ] );
313: coords[ 1 ] = normalize( coords[ 1 ] );
314: coords[ 2 ] = normalize( coords[ 2 ] );
315: coords[ 3 ] = normalize( coords[ 3 ] );
316: vec3 vectorFormFactor = vec3( 0.0 );
317: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );
318: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );
319: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );
320: vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );
321: vec3 result = vec3( LTC_ClippedSphereFormFactor( vectorFormFactor ) );
322: return result;
323: }
324: vec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {
325: float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
326: const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );
327: const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );
328: vec4 r = roughness * c0 + c1;
329: float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;
330: vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
331: return specularColor * AB.x + AB.y;
332: }
333: float G_BlinnPhong_Implicit( ) {
334: return 0.25;
335: }
336: float D_BlinnPhong( const in float shininess, const in float dotNH ) {
337: return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );
338: }
339: vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {
340: vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );
341: float dotNH = saturate( dot( geometry.normal, halfDir ) );
342: float dotLH = saturate( dot( incidentLight.direction, halfDir ) );
343: vec3 F = F_Schlick( specularColor, dotLH );
344: float G = G_BlinnPhong_Implicit( );
345: float D = D_BlinnPhong( shininess, dotNH );
346: return F * ( G * D );
347: }
348: float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {
349: return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );
350: }
351: float BlinnExponentToGGXRoughness( const in float blinnExponent ) {
352: return sqrt( 2.0 / ( blinnExponent + 2.0 ) );
353: }
354:
355: #ifdef USE_FOG
356: uniform vec3 fogColor;
357: varying float fogDepth;
358: #ifdef FOG_EXP2
359: uniform float fogDensity;
360: #else
361: uniform float fogNear;
362: uniform float fogFar;
363: #endif
364: #endif
365:
366: uniform vec3 ambientLightColor;
367: vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
368: vec3 irradiance = ambientLightColor;
369: #ifndef PHYSICALLY_CORRECT_LIGHTS
370: irradiance *= PI;
371: #endif
372: return irradiance;
373: }
374: #if 1 > 0
375: struct DirectionalLight {
376: vec3 direction;
377: vec3 color;
378: int shadow;
379: float shadowBias;
380: float shadowRadius;
381: vec2 shadowMapSize;
382: };
383: uniform DirectionalLight directionalLights[ 1 ];
384: void getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {
385: directLight.color = directionalLight.color;
386: directLight.direction = directionalLight.direction;
387: directLight.visible = true;
388: }
389: #endif
390: #if 0 > 0
391: struct PointLight {
392: vec3 position;
393: vec3 color;
394: float distance;
395: float decay;
396: int shadow;
397: float shadowBias;
398: float shadowRadius;
399: vec2 shadowMapSize;
400: float shadowCameraNear;
401: float shadowCameraFar;
402: };
403: uniform PointLight pointLights[ 0 ];
404: void getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {
405: vec3 lVector = pointLight.position - geometry.position;
406: directLight.direction = normalize( lVector );
407: float lightDistance = length( lVector );
408: directLight.color = pointLight.color;
409: directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );
410: directLight.visible = ( directLight.color != vec3( 0.0 ) );
411: }
412: #endif
413: #if 0 > 0
414: struct SpotLight {
415: vec3 position;
416: vec3 direction;
417: vec3 color;
418: float distance;
419: float decay;
420: float coneCos;
421: float penumbraCos;
422: int shadow;
423: float shadowBias;
424: float shadowRadius;
425: vec2 shadowMapSize;
426: };
427: uniform SpotLight spotLights[ 0 ];
428: void getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {
429: vec3 lVector = spotLight.position - geometry.position;
430: directLight.direction = normalize( lVector );
431: float lightDistance = length( lVector );
432: float angleCos = dot( directLight.direction, spotLight.direction );
433: if ( angleCos > spotLight.coneCos ) {
434: float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );
435: directLight.color = spotLight.color;
436: directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );
437: directLight.visible = true;
438: } else {
439: directLight.color = vec3( 0.0 );
440: directLight.visible = false;
441: }
442: }
443: #endif
444: #if 0 > 0
445: struct RectAreaLight {
446: vec3 color;
447: vec3 position;
448: vec3 halfWidth;
449: vec3 halfHeight;
450: };
451: uniform sampler2D ltcMat; uniform sampler2D ltcMag;
452: uniform RectAreaLight rectAreaLights[ 0 ];
453: #endif
454: #if 0 > 0
455: struct HemisphereLight {
456: vec3 direction;
457: vec3 skyColor;
458: vec3 groundColor;
459: };
460: uniform HemisphereLight hemisphereLights[ 0 ];
461: vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {
462: float dotNL = dot( geometry.normal, hemiLight.direction );
463: float hemiDiffuseWeight = 0.5 * dotNL + 0.5;
464: vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );
465: #ifndef PHYSICALLY_CORRECT_LIGHTS
466: irradiance *= PI;
467: #endif
468: return irradiance;
469: }
470: #endif
471: #if defined( USE_ENVMAP ) && defined( PHYSICAL )
472: vec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {
473: vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );
474: #ifdef ENVMAP_TYPE_CUBE
475: vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );
476: #ifdef TEXTURE_LOD_EXT
477: vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );
478: #else
479: vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );
480: #endif
481: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
482: #elif defined( ENVMAP_TYPE_CUBE_UV )
483: vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );
484: vec4 envMapColor = textureCubeUV( queryVec, 1.0 );
485: #else
486: vec4 envMapColor = vec4( 0.0 );
487: #endif
488: return PI * envMapColor.rgb * envMapIntensity;
489: }
490: float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {
491: float maxMIPLevelScalar = float( maxMIPLevel );
492: float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );
493: return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );
494: }
495: vec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {
496: #ifdef ENVMAP_MODE_REFLECTION
497: vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );
498: #else
499: vec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );
500: #endif
501: reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
502: float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );
503: #ifdef ENVMAP_TYPE_CUBE
504: vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );
505: #ifdef TEXTURE_LOD_EXT
506: vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );
507: #else
508: vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );
509: #endif
510: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
511: #elif defined( ENVMAP_TYPE_CUBE_UV )
512: vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );
513: vec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));
514: #elif defined( ENVMAP_TYPE_EQUIREC )
515: vec2 sampleUV;
516: sampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
517: sampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;
518: #ifdef TEXTURE_LOD_EXT
519: vec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );
520: #else
521: vec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );
522: #endif
523: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
524: #elif defined( ENVMAP_TYPE_SPHERE )
525: vec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );
526: #ifdef TEXTURE_LOD_EXT
527: vec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );
528: #else
529: vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );
530: #endif
531: envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
532: #endif
533: return envMapColor.rgb * envMapIntensity;
534: }
535: #endif
536:
537: #ifdef USE_SHADOWMAP
538: #if 1 > 0
539: uniform sampler2D directionalShadowMap[ 1 ];
540: varying vec4 vDirectionalShadowCoord[ 1 ];
541: #endif
542: #if 0 > 0
543: uniform sampler2D spotShadowMap[ 0 ];
544: varying vec4 vSpotShadowCoord[ 0 ];
545: #endif
546: #if 0 > 0
547: uniform sampler2D pointShadowMap[ 0 ];
548: varying vec4 vPointShadowCoord[ 0 ];
549: #endif
550: float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {
551: return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );
552: }
553: float texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {
554: const vec2 offset = vec2( 0.0, 1.0 );
555: vec2 texelSize = vec2( 1.0 ) / size;
556: vec2 centroidUV = floor( uv * size + 0.5 ) / size;
557: float lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );
558: float lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );
559: float rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );
560: float rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );
561: vec2 f = fract( uv * size + 0.5 );
562: float a = mix( lb, lt, f.y );
563: float b = mix( rb, rt, f.y );
564: float c = mix( a, b, f.x );
565: return c;
566: }
567: float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
568: float shadow = 1.0;
569: shadowCoord.xyz /= shadowCoord.w;
570: shadowCoord.z += shadowBias;
571: bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );
572: bool inFrustum = all( inFrustumVec );
573: bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );
574: bool frustumTest = all( frustumTestVec );
575: if ( frustumTest ) {
576: #if defined( SHADOWMAP_TYPE_PCF )
577: vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
578: float dx0 = - texelSize.x * shadowRadius;
579: float dy0 = - texelSize.y * shadowRadius;
580: float dx1 = + texelSize.x * shadowRadius;
581: float dy1 = + texelSize.y * shadowRadius;
582: shadow = (
583: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
584: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
585: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
586: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +
587: texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +
588: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +
589: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +
590: texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +
591: texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
592: ) * ( 1.0 / 9.0 );
593: #elif defined( SHADOWMAP_TYPE_PCF_SOFT )
594: vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
595: float dx0 = - texelSize.x * shadowRadius;
596: float dy0 = - texelSize.y * shadowRadius;
597: float dx1 = + texelSize.x * shadowRadius;
598: float dy1 = + texelSize.y * shadowRadius;
599: shadow = (
600: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
601: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
602: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
603: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +
604: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +
605: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +
606: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +
607: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +
608: texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
609: ) * ( 1.0 / 9.0 );
610: #else
611: shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );
612: #endif
613: }
614: return shadow;
615: }
616: vec2 cubeToUV( vec3 v, float texelSizeY ) {
617: vec3 absV = abs( v );
618: float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );
619: absV *= scaleToCube;
620: v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );
621: vec2 planar = v.xy;
622: float almostATexel = 1.5 * texelSizeY;
623: float almostOne = 1.0 - almostATexel;
624: if ( absV.z >= almostOne ) {
625: if ( v.z > 0.0 )
626: planar.x = 4.0 - v.x;
627: } else if ( absV.x >= almostOne ) {
628: float signX = sign( v.x );
629: planar.x = v.z * signX + 2.0 * signX;
630: } else if ( absV.y >= almostOne ) {
631: float signY = sign( v.y );
632: planar.x = v.x + 2.0 * signY + 2.0;
633: planar.y = v.z * signY - 2.0;
634: }
635: return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );
636: }
637: float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {
638: vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );
639: vec3 lightToPosition = shadowCoord.xyz;
640: float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); dp += shadowBias;
641: vec3 bd3D = normalize( lightToPosition );
642: #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )
643: vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;
644: return (
645: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +
646: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +
647: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +
648: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +
649: texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +
650: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +
651: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +
652: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +
653: texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )
654: ) * ( 1.0 / 9.0 );
655: #else
656: return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );
657: #endif
658: }
659: #endif
660:
661: float getShadowMask() {
662: float shadow = 1.0;
663: #ifdef USE_SHADOWMAP
664: #if 1 > 0
665: DirectionalLight directionalLight;
666: for ( int i = 0; i < 1; i ++ ) {
667: directionalLight = directionalLights[ i ];
668: shadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
669: }
670: #endif
671: #if 0 > 0
672: SpotLight spotLight;
673: for ( int i = 0; i < 0; i ++ ) {
674: spotLight = spotLights[ i ];
675: shadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
676: }
677: #endif
678: #if 0 > 0
679: PointLight pointLight;
680: for ( int i = 0; i < 0; i ++ ) {
681: pointLight = pointLights[ i ];
682: shadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
683: }
684: #endif
685: #endif
686: return shadow;
687: }
688:
689: void main() {
690: vec4 noise = getNoise( worldPosition.xz * size );
691: vec3 surfaceNormal = normalize( noise.xzy * vec3( 1.5, 1.0, 1.5 ) );
692: vec3 diffuseLight = vec3(0.0);
693: vec3 specularLight = vec3(0.0);
694: vec3 worldToEye = eye-worldPosition.xyz;
695: vec3 eyeDirection = normalize( worldToEye );
696: sunLight( surfaceNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight );
697: float distance = length(worldToEye);
698: vec2 distortion = surfaceNormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;
699: vec3 reflectionSample = vec3( texture2D( mirrorSampler, mirrorCoord.xy / mirrorCoord.z + distortion ) );
700: float theta = max( dot( eyeDirection, surfaceNormal ), 0.0 );
701: float rf0 = 0.3;
702: float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );
703: vec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;
704: vec3 albedo = mix( ( sunColor * diffuseLight * 0.3 + scatter ) * getShadowMask(), ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance);
705: vec3 outgoingLight = albedo;
706: gl_FragColor = vec4( outgoingLight, alpha );
707: #if defined( TONE_MAPPING )
708: gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );
709: #endif
710:
711: #ifdef USE_FOG
712: #ifdef FOG_EXP2
713: float fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );
714: #else
715: float fogFactor = smoothstep( fogNear, fogFar, fogDepth );
716: #endif
717: gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );
718: #endif
719:
720: }
唯一使用非恒定表达式建立索引的采样器似乎是directionalShadowMap
668行中的0:102(109)
。
668: shadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
其他阴影贴图示例也可以工作。 它必须使用THREE.Water
特定片段着色器来做某事...
相同的结论。 它还会在第2行报告一个en扩展名的警告,该警告不可见,因此它可能是指所记录的内容是不同的代码?
顺便说一句与https://github.com/mrdoob/three.js/issues/6115中的问题
正如@moraxy指出的那样,这个问题表明,它可能链接到阴影,因为那里只有一个带有非const表达式的采样器数组:如果在示例中删除water.receiveShadow = true
怎么办?
我正在挖掘该着色器,以防同时有任何想法...
如果在示例中删除water.receiveShadow = true怎么办?
那解决了问题。
@ Mugen87样条曲线编辑器示例中的阴影对您有用吗? (我复制了ShadowMaterial的大块以在水着色器中获得阴影)
是的, webgl_geometry_spline_editor
有效。
为什么在这两个示例中相同的shadowmask_pars_fragment
块输出两个不同的getShadowMask
函数? 在水着色器中,它在采样器数组中具有这种非恒定使用的for循环,在样条线编辑器示例的ShadowMaterial程序中没有:
循环展开? 每个循环中应该有一个标志或指令或强制启用/禁用它的东西
渲染器是否使用内置材料中的此块(在Shadow和Lambert材料中使用)而不是ShaderMaterial在内部实现循环展开?
我们该如何处理?
好问题。 我记得有一个用户的功能请求,该用户要求提供一个示例,该示例演示如何在自定义着色器材质上应用光照+阴影(不幸的是,我现在找不到问题)。 但是,在实现这一点时,我们会遇到相同的错误。
我不确定如何解决此问题。 让我们等待@mrdoob和@WestLangley如何评估该问题。
作为用户自己,这是一个大问题,因为在GPGPU情况下,我们可以在ShaderMaterial中使用巨大的for
循环,而另一方面,如果我们要设计特殊的材料,我们应该可以使用这种块。与ShaderMaterial。
保持和删除此条件似乎都在某处引起问题。 @moraxy提到使用一个标志,它看起来像是唯一的出口门...? 但这是一项特殊的政策。
我猜这也是自定义着色器的普遍问题,所有的SO问题都在发生...我喜欢onBeforeCompile
但是通过在ShadowMaterial上使用它来创建水着色器...这看起来很棘手...并且不会解决其他相关问题。
我让你解决这个问题:innocent:
我想我们可以尝试将unrollLoops
属性添加到ShaderMaterial
吗?
if ( material.isShaderMaterial === undefined || material.unrollLoops === true ) {
听起来不错!
@阿斯特拉克
您发布了此屏幕快照的此着色器检查器是什么?
@pailhead这是WebGL Inspector ,可作为Chrome和Firefox的扩展。
现在,此错误已通过#13140修复。 好极了! 🙌
最有用的评论
现在,此错误已通过#13140修复。 好极了! 🙌