Three.js: Примеры: проблема с webgl_shaders_ocean

Созданный на 1 окт. 2017  ·  24Комментарии  ·  Источник: mrdoob/three.js

Описание проблемы

Сегодня я обнаружил, что текущая dev версия webgl_shaders_ocean не работает с 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 @Astrak

Версия Three.js
  • [X] Dev
  • [] r87
  • [] ...
Браузер
  • [] Все они
  • [] Chrome
  • [X] Firefox
  • [] Internet Explorer
Операционные системы
  • [] Все они
  • [] Windows
  • [] macOS
  • [X] Linux
  • [] Android
  • [] iOS
Требования к оборудованию (видеокарта, устройство VR, ...)

Самый полезный комментарий

Эта ошибка теперь исправлена ​​через # 13140. Ура! 🎉 🙌

Все 24 Комментарий

Я только что запустил пример в текущей ветке dev в Debian 9.1 с FF 52.4 и FF 58.0, этого не произошло.

Геометрия не сильно изменилась в PR, фрагментный шейдер просто включает необходимые фрагменты для вызова getShadowMask() .

Регистрирует ли сообщение об ошибке, что находится в 0:102(109) ?

К сожалению нет. Зарегистрированный шейдер фрагмента обрезается после строки 27: unamused:

Если я удалю фрагменты шейдера во фрагментном шейдере ( 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 ...

Тот же вывод. Он также сообщает о предупреждении для расширения en в строке 2, которое не отображается, так что это может относиться к другому коду, отличному от того, что регистрируется?

Та же проблема, что и в https://github.com/mrdoob/three.js/issues/6115 , кстати

Как заявил @moraxy, и проблема предполагает, что он может быть связан с тенями, поскольку существует единственный массив сэмплера с неконстантным выражением: что, если вы удалите water.receiveShadow = true в примере?

Я копаю этот шейдер на случай, если у меня возникнут какие-то идеи ...

что, если вы удалите water.receiveShadow = true в примере?

Это решает проблему.

@ Mugen87 работают ли тени в примере редактора сплайнов ? (Я скопировал куски ShadowMaterial, чтобы получить тени в шейдере воды)

Да, webgl_geometry_spline_editor работает.

Почему один и тот же блок shadowmask_pars_fragment выводит две разные getShadowMask функции в этих двух примерах? В шейдере воды у него есть циклы for с этим непостоянным использованием в массивах сэмплеров, в программе ShadowMaterial примера редактора сплайнов его нет:getShadowMask

Петля разворачивается? Должен быть флаг или директива или что-то еще, чтобы принудительно включить / отключить его для каждого цикла

Достигает ли рендерер внутреннего развертывания цикла с помощью этого фрагмента встроенных материалов (он используется в материалах Shadow и Lambert), а не с помощью ShaderMaterial?

Как мы с этим справляемся?

Хороший вопрос. Я помню, что был запрос функции от пользователя, который попросил пример, который показывает, как применить освещение + тени к пользовательскому материалу шейдера (к сожалению, я не могу найти проблему прямо сейчас). Но при реализации этого мы столкнемся с той же ошибкой.

Я не знаю, как решить эту проблему. Подождем, как @mrdoob и @WestLangley оценит проблему.

Для меня как пользователя это большой вопрос, потому что в случаях GPGPU мы можем использовать огромные циклы for с ShaderMaterial, в то время как с другой стороны мы должны иметь возможность использовать этот тип блока, если мы хотим разработать специальные материалы с помощью ShaderMaterial.

И сохранение, и удаление этого условия, кажется, где-то вызывает проблемы. @moraxy упомянул об использовании флага, который тогда выглядел бы как единственная выходная дверь ...? Но тогда это особая политика.

Это также общая проблема настройки шейдеров, я думаю, со всеми возникающими вопросами и проблемами SO ... Мне нравится onBeforeCompile но создание шейдера воды с использованием его на ShadowMaterial ... это может показаться сложным ... и не решит другие связанные вопросы.

Я позволю тебе решить эту проблему: innocent:

Думаю, мы могли бы попробовать добавить свойство unrollLoops к ShaderMaterial ?

if ( material.isShaderMaterial === undefined || material.unrollLoops === true ) {

Звучит неплохо!

@Astrak

Что это за инспектор шейдеров, скриншот которого вы разместили?

@pailhead Это WebGL Inspector , доступный как расширение для Chrome и Firefox.

Эта ошибка теперь исправлена ​​через # 13140. Ура! 🎉 🙌

Была ли эта страница полезной?
0 / 5 - 0 рейтинги