Sorry, maybe I didn’t explain properly. I need the full output to the JavaScript console. So I just picked a random project where it defines a custom shader and I removed a semi-colon from the end of one of the lines. This generates the following output:
playcanvas-stable.dbg.js:345 Powered by PlayCanvas 0.216.5 b31e1ce
messenger.js:80 messenger connected
launch.js:7208 ERROR: Failed to compile fragment shader:
1: #version 300 es
2: #define varying in
3: out highp vec4 pc_fragColor;
4: #define gl_FragColor pc_fragColor
5: #define texture2D texture
6: #define textureCube texture
7: #define texture2DProj textureProj
8: #define texture2DLodEXT textureLod
9: #define texture2DProjLodEXT textureProjLod
10: #define textureCubeLodEXT textureLod
11: #define texture2DGradEXT textureGrad
12: #define texture2DProjGradEXT textureProjGrad
13: #define textureCubeGradEXT textureGrad
14: #define GL2
15: precision highp float;
16: #ifdef GL2
17: precision highp sampler2DShadow;
18: #endif
19: varying vec3 vPositionW;
20: varying vec3 vNormalW;
21: varying vec3 vTangentW;
22: varying vec3 vBinormalW;
23: varying vec2 vUV0_1;
24:
25: uniform vec3 view_position;
26: uniform vec3 light_globalAmbient;
27: float square(float x) {
28: return x*x;
29: }
30: float saturate(float x) {
31: return clamp(x, 0.0, 1.0);
32: }
33: vec3 saturate(vec3 x) {
34: return clamp(x, vec3(0.0), vec3(1.0));
35: }
36: vec4 dReflection;
37: mat3 dTBN;
38: vec3 dAlbedo;
39: vec3 dNormalW;
40: vec3 dViewDirW;
41: vec3 dReflDirW;
42: vec3 dDiffuseLight;
43: vec3 dSpecularLight;
44: vec3 dNormalMap;
45: vec3 dSpecularity;
46: float dGlossiness;
47: float dAlpha;
48:
49: vec3 unpackNormal(vec4 nmap) {
50: return nmap.xyz * 2.0 - 1.0;
51: }
52: uniform sampler2D texture_normalMap;
53: uniform float material_bumpiness;
54:
55: uniform vec2 layer1_offset;
56: uniform vec2 layer2_offset;
57:
58: void getNormal() {
59: vec3 normalMap = unpackNormal(texture2D(texture_normalMap, vUV0_1 + layer1_offset));
60: vec3 normalMap2 = unpackNormal(texture2D(texture_normalMap, vUV0_1 * 4.0 + layer2_offset));
61: vec3 normalMap3 = unpackNormal(texture2D(texture_normalMap, vUV0_1 * 0.25));
62:
63: normalMap = normalize(vec3(normalMap3.xy + normalMap.xy, normalMap3.z * normalMap.z));
64: normalMap = normalize(vec3(normalMap.xy + normalMap2.xy, normalMap.z * normalMap2.z));
65:
66: dNormalMap = normalMap;
67: dNormalW = dTBN * normalMap
68: }
69: void getTBN() {
70: dTBN = mat3(normalize(vTangentW), normalize(vBinormalW), normalize(vNormalW));
71: }
72: vec3 gammaCorrectInput(vec3 color) {
73: return pow(color, vec3(2.2));
74: }
75: float gammaCorrectInput(float color) {
76: return pow(color, 2.2);
77: }
78: vec4 gammaCorrectInput(vec4 color) {
79: return vec4(pow(color.rgb, vec3(2.2)), color.a);
80: }
81: vec4 texture2DSRGB(sampler2D tex, vec2 uv) {
82: vec4 rgba = texture2D(tex, uv);
83: rgba.rgb = gammaCorrectInput(rgba.rgb);
84: return rgba;
85: }
86: vec4 textureCubeSRGB(samplerCube tex, vec3 uvw) {
87: vec4 rgba = textureCube(tex, uvw);
88: rgba.rgb = gammaCorrectInput(rgba.rgb);
89: return rgba;
90: }
91: vec3 gammaCorrectOutput(vec3 color) {
92: #ifdef HDR
93: return color;
94: #else
95: color += vec3(0.0000001);
96: return pow(color, vec3(0.45));
97: #endif
98: }
99: const float A = 0.15;
100: const float B = 0.50;
101: const float C = 0.10;
102: const float D = 0.20;
103: const float E = 0.02;
104: const float F = 0.30;
105: const float W = 11.2;
106: uniform float exposure;
107: vec3 uncharted2Tonemap(vec3 x) {
108: return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
109: }
110: vec3 toneMap(vec3 color) {
111: color = uncharted2Tonemap(color * exposure);
112: vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W,W,W));
113: color = color * whiteScale;
114: return color;
115: }
116: vec3 addFog(vec3 color) {
117: return color;
118: }
119: vec3 decodeRGBM(vec4 rgbm) {
120: vec3 color = (8.0 * rgbm.a) * rgbm.rgb;
121: return color * color;
122: }
123: vec3 texture2DRGBM(sampler2D tex, vec2 uv) {
124: return decodeRGBM(texture2D(tex, uv));
125: }
126: vec3 textureCubeRGBM(samplerCube tex, vec3 uvw) {
127: return decodeRGBM(textureCube(tex, uvw));
128: }
129: vec3 fixSeams(vec3 vec, float mipmapIndex) {
130: float scale = 1.0 - exp2(mipmapIndex) / 128.0;
131: float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));
132: if (abs(vec.x) != M) vec.x *= scale;
133: if (abs(vec.y) != M) vec.y *= scale;
134: if (abs(vec.z) != M) vec.z *= scale;
135: return vec;
136: }
137: vec3 fixSeams(vec3 vec) {
138: float scale = 1.0 - 1.0 / 128.0;
139: float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));
140: if (abs(vec.x) != M) vec.x *= scale;
141: if (abs(vec.y) != M) vec.y *= scale;
142: if (abs(vec.z) != M) vec.z *= scale;
143: return vec;
144: }
145: vec3 fixSeamsStatic(vec3 vec, float invRecMipSize) {
146: float scale = invRecMipSize;
147: float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));
148: if (abs(vec.x) != M) vec.x *= scale;
149: if (abs(vec.y) != M) vec.y *= scale;
150: if (abs(vec.z) != M) vec.z *= scale;
151: return vec;
152: }
153: vec3 cubeMapProject(vec3 dir) {
154: return dir;
155: }
156: vec3 processEnvironment(vec3 color) {
157: return color;
158: }
159: uniform vec3 material_diffuse;
160: void getAlbedo() {
161: dAlbedo = material_diffuse.rgb;
162: }
163: uniform vec3 material_emissive;
164: vec3 getEmission() {
165: return material_emissive;
166: }
167: float antiAliasGlossiness(float power) {
168: float rlen = 1.0 / saturate(length(dNormalMap));
169: float toksvig = 1.0 / (1.0 + power * (rlen - 1.0));
170: return power * mix(1.0, toksvig, material_bumpiness);
171: }
172: uniform vec3 material_specular;
173: void getSpecularity() {
174: dSpecularity = material_specular;
175: }
176: uniform float material_shininess;
177: void getGlossiness() {
178: dGlossiness = material_shininess + 0.0000001;
179: }
180: // Schlick's approximation
181: uniform float material_fresnelFactor; // unused
182: void getFresnel() {
183: float fresnel = 1.0 - max(dot(dNormalW, dViewDirW), 0.0);
184: float fresnel2 = fresnel * fresnel;
185: fresnel *= fresnel2 * fresnel2;
186: fresnel *= dGlossiness * dGlossiness;
187: dSpecularity = dSpecularity + (1.0 - dSpecularity) * fresnel;
188: }
189: uniform samplerCube texture_prefilteredCubeMap128;
190: uniform samplerCube texture_prefilteredCubeMap64;
191: uniform samplerCube texture_prefilteredCubeMap32;
192: uniform samplerCube texture_prefilteredCubeMap16;
193: uniform samplerCube texture_prefilteredCubeMap8;
194: uniform samplerCube texture_prefilteredCubeMap4;
195: uniform float material_reflectivity;
196: void addReflection() {
197: // Unfortunately, WebGL doesn't allow us using textureCubeLod. Therefore bunch of nasty workarounds is required.
198: // We fix mip0 to 128x128, so code is rather static.
199: // Mips smaller than 4x4 aren't great even for diffuse. Don't forget that we don't have bilinear filtering between different faces.
200: float bias = saturate(1.0 - dGlossiness) * 5.0; // multiply by max mip level
201: int index1 = int(bias);
202: int index2 = int(min(bias + 1.0, 7.0));
203: vec3 fixedReflDir = fixSeams(cubeMapProject(dReflDirW), bias);
204: fixedReflDir.x *= -1.0;
205: vec4 cubes[6];
206: cubes[0] = textureCube(texture_prefilteredCubeMap128, fixedReflDir);
207: cubes[1] = textureCube(texture_prefilteredCubeMap64, fixedReflDir);
208: cubes[2] = textureCube(texture_prefilteredCubeMap32, fixedReflDir);
209: cubes[3] = textureCube(texture_prefilteredCubeMap16, fixedReflDir);
210: cubes[4] = textureCube(texture_prefilteredCubeMap8, fixedReflDir);
211: cubes[5] = textureCube(texture_prefilteredCubeMap4, fixedReflDir);
212: // Also we don't have dynamic indexing in PS, so...
213: vec4 cube[2];
214: for(int i = 0; i < 6; i++) {
215: if (i == index1) {
216: cube[0] = cubes[i];
217: }
218: if (i == index2) {
219: cube[1] = cubes[i];
220: }
221: }
222: // another variant
223: /*if (index1==0){ cube[0]=cubes[0];
224: }else if (index1==1){ cube[0]=cubes[1];
225: }else if (index1==2){ cube[0]=cubes[2];
226: }else if (index1==3){ cube[0]=cubes[3];
227: }else if (index1==4){ cube[0]=cubes[4];
228: }else if (index1==5){ cube[0]=cubes[5];}
229: if (index2==0){ cube[1]=cubes[0];
230: }else if (index2==1){ cube[1]=cubes[1];
231: }else if (index2==2){ cube[1]=cubes[2];
232: }else if (index2==3){ cube[1]=cubes[3];
233: }else if (index2==4){ cube[1]=cubes[4];
234: }else if (index2==5){ cube[1]=cubes[5];}*/
235: vec4 cubeFinal = mix(cube[0], cube[1], fract(bias));
236: vec3 refl = processEnvironment(decodeRGBM(cubeFinal).rgb);
237: dReflection += vec4(refl, material_reflectivity);
238: }
239: vec3 combineColor() {
240: return mix(dAlbedo * dDiffuseLight, dSpecularLight + dReflection.rgb * dReflection.a, dSpecularity);
241: }
242: void addAmbient() {
243: vec3 fixedReflDir = fixSeamsStatic(dNormalW, 1.0 - 1.0 / 4.0);
244: fixedReflDir.x *= -1.0;
245: dDiffuseLight += processEnvironment(decodeRGBM(textureCube(texture_prefilteredCubeMap4, fixedReflDir)).rgb);
246: }
247: void getViewDir() {
248: dViewDirW = normalize(view_position - vPositionW);
249: }
250: void getReflDir() {
251: dReflDirW = normalize(-reflect(dViewDirW, dNormalW));
252: }
253:
254: void main(void) {
255: dDiffuseLight = vec3(0);
256: dSpecularLight = vec3(0);
257: dReflection = vec4(0);
258: dSpecularity = vec3(0);
259: dAlpha = 1.0;
260: getViewDir();
261: getTBN();
262: getNormal();
263: getReflDir();
264: getAlbedo();
265: getSpecularity();
266: getGlossiness();
267: getFresnel();
268: addAmbient();
269: addReflection();
270:
271: gl_FragColor.rgb = combineColor();
272: gl_FragColor.rgb += getEmission();
273: gl_FragColor.rgb = addFog(gl_FragColor.rgb);
274: #ifndef HDR
275: gl_FragColor.rgb = toneMap(gl_FragColor.rgb);
276: gl_FragColor.rgb = gammaCorrectOutput(gl_FragColor.rgb);
277: #endif
278: gl_FragColor.a = 1.0;
279:
280: }
281:
ERROR: 0:68: '}' : syntax error
ERROR: Failed to link shader program. Error: invalid shaders
Error in material "Water" with flags 65548
The important line is:
ERROR: 0:68: '}' : syntax error
This is telling me there’s a problem at line 68 and indeed if I look at the previous line, there’s a missing semi-colon. Normally, the shader compilation error is shown after the GLSL code listing. Do you not have that?