Closed capnm closed 5 years ago
Hi @capnm, thanks for reporting this. I think https://github.com/g3n/engine/commit/973727e925428878318641974704a26dd2ac92e6 might have fixed your issue - could you get latest and try again?
Hi @danaugrs , I just tested the latest master with this fix, but still get an error once using the Material with textures:
panic: error compiling Vertex Shader: 0:56(26): error: sampler arrays indexed with non-constant expressions are forbidden in GLSL 1.30 and later
001:#version 330 core
After some research I found a "fix" which at least let my program work again with textures. I don't know if that is a valid fix?!
In shaders/sources.go:135
vec4 MIX_TEXTURE(vec4 texMixed, vec2 FragTexcoord, int i) {
vec4 texColor = texture(MatTex(0), FragTexcoord * MatTexRepeat(0) + MatTexOffset(0));
if (MatTexVisible(i)) {
if (i == 0) {
texMixed = texColor;
} else {
texMixed = mix(texMixed, texColor, texColor.a);
}
}
return texMixed;
}
Hi @breiting! Thanks for the attempt, but that's not a valid solution because it always uses the first texture (with index 0) but materials can have more than one texture.
I pushed the following fix: https://github.com/g3n/engine/commit/a6db6017ca1ef64e9b849213430ba60d0e70f896. @capnm and @breiting please let me know if it works for you! π
Well the one error got fixed, but your commits triggered another error :-)
panic: error compiling Fragment Shader: 0:242(12): warning: extension `GL_OES_standard_derivatives' unsupported in fragment shader
0:195(2): error: #extension directive is not allowed in the middle of a shader
001:#version 330 core
this introduced the problem
241: // Workaround for gl_FrontFacing
242: #extension GL_OES_standard_derivatives : enable
243: vec3 fdx = dFdx(Position.xyz);
244: vec3 fdy = dFdy(Position.xyz);
When I comment out the extension, everything works fine again.
Interesting - apparently the extension declaration isn't necessary. Fixed in https://github.com/g3n/engine/commit/643d63832dcc4ae661271d1755683a0be5204234. Thanks for the help!
Hi @danaugrs I've updated to the current master (7efde9ba89b1501e4aaff108f084b976551e7e2e) now the compiler complains about this fragment shader. Sorry, I don't have time right now to see what's going on :-/
./g3nd β texture β box
19:39:15.688350:I:G3ND:G3N Demo v0.6 starting
19:39:15.688483:I:G3ND:OpenGL version: 4.5 (Core Profile) Mesa 19.2.0-devel - padoka PPA
19:39:15.690470:I:G3ND:Using data directory:g3nd/data
panic: error compiling Fragment Shader: 0:242(12): warning: extension `GL_OES_standard_derivatives' unsupported in fragment shader
0:195(2): error: #extension directive is not allowed in the middle of a shader
001:#version 330 core
002:#define AMB_LIGHTS 1
003:#define DIR_LIGHTS 3
004:#define POINT_LIGHTS 0
005:#define SPOT_LIGHTS 0
006:#define MAT_TEXTURES 2
007:precision highp float;
008:
009:// Inputs from vertex shader
010:in vec4 Position; // Fragment position in camera coordinates
011:in vec3 Normal; // Fragment normal in camera coordinates
012:in vec2 FragTexcoord; // Fragment texture coordinates
013:
014:
015://
016:// Lights uniforms
017://
018:
019:#if AMB_LIGHTS>0
020: // Ambient lights color uniform
021: uniform vec3 AmbientLightColor[AMB_LIGHTS];
022:#endif
023:
024:#if DIR_LIGHTS>0
025: // Directional lights uniform array. Each directional light uses 2 elements
026: uniform vec3 DirLight[2*DIR_LIGHTS];
027: // Macros to access elements inside the DirectionalLight uniform array
028: #define DirLightColor(a) DirLight[2*a]
029: #define DirLightPosition(a) DirLight[2*a+1]
030:#endif
031:
032:#if POINT_LIGHTS>0
033: // Point lights uniform array. Each point light uses 3 elements
034: uniform vec3 PointLight[3*POINT_LIGHTS];
035: // Macros to access elements inside the PointLight uniform array
036: #define PointLightColor(a) PointLight[3*a]
037: #define PointLightPosition(a) PointLight[3*a+1]
038: #define PointLightLinearDecay(a) PointLight[3*a+2].x
039: #define PointLightQuadraticDecay(a) PointLight[3*a+2].y
040:#endif
041:
042:#if SPOT_LIGHTS>0
043: // Spot lights uniforms. Each spot light uses 5 elements
044: uniform vec3 SpotLight[5*SPOT_LIGHTS];
045: // Macros to access elements inside the PointLight uniform array
046: #define SpotLightColor(a) SpotLight[5*a]
047: #define SpotLightPosition(a) SpotLight[5*a+1]
048: #define SpotLightDirection(a) SpotLight[5*a+2]
049: #define SpotLightAngularDecay(a) SpotLight[5*a+3].x
050: #define SpotLightCutoffAngle(a) SpotLight[5*a+3].y
051: #define SpotLightLinearDecay(a) SpotLight[5*a+3].z
052: #define SpotLightQuadraticDecay(a) SpotLight[5*a+4].x
053:#endif
054:
055://
056:// Material properties uniform
057://
058:
059:// Material parameters uniform array
060:uniform vec3 Material[6];
061:// Macros to access elements inside the Material array
062:#define MatAmbientColor Material[0]
063:#define MatDiffuseColor Material[1]
064:#define MatSpecularColor Material[2]
065:#define MatEmissiveColor Material[3]
066:#define MatShininess Material[4].x
067:#define MatOpacity Material[4].y
068:#define MatPointSize Material[4].z
069:#define MatPointRotationZ Material[5].x
070:
071:#if MAT_TEXTURES > 0
072: // Texture unit sampler array
073: uniform sampler2D MatTexture[MAT_TEXTURES];
074: // Texture parameters (3*vec2 per texture)
075: uniform vec2 MatTexinfo[3*MAT_TEXTURES];
076: // Macros to access elements inside the MatTexinfo array
077: #define MatTexOffset(a) MatTexinfo[(3*a)]
078: #define MatTexRepeat(a) MatTexinfo[(3*a)+1]
079: #define MatTexFlipY(a) bool(MatTexinfo[(3*a)+2].x)
080: #define MatTexVisible(a) bool(MatTexinfo[(3*a)+2].y)
081: // Alpha compositing (see here: https://ciechanow.ski/alpha-compositing/)
082: vec4 Blend(vec4 texMixed, vec4 texColor) {
083: texMixed.rgb *= texMixed.a;
084: texColor.rgb *= texColor.a;
085: texMixed = texColor + texMixed * (1 - texColor.a);
086: if (texMixed.a > 0.0) {
087: texMixed.rgb /= texMixed.a;
088: }
089: return texMixed;
090: }
091:#endif
092:
093:/***
094: phong lighting model
095: Parameters:
096: position: input vertex position in camera coordinates
097: normal: input vertex normal in camera coordinates
098: camDir: input camera directions
099: matAmbient: input material ambient color
100: matDiffuse: input material diffuse color
101: ambdiff: output ambient+diffuse color
102: spec: output specular color
103: Uniforms:
104: AmbientLightColor[]
105: DiffuseLightColor[]
106: DiffuseLightPosition[]
107: PointLightColor[]
108: PointLightPosition[]
109: PointLightLinearDecay[]
110: PointLightQuadraticDecay[]
111: MatSpecularColor
112: MatShininess
113:*****/
114:void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 matDiffuse, out vec3 ambdiff, out vec3 spec) {
115:
116: vec3 ambientTotal = vec3(0.0);
117: vec3 diffuseTotal = vec3(0.0);
118: vec3 specularTotal = vec3(0.0);
119:
120: bool noLights = true;
121:
122:#if AMB_LIGHTS>0
123: noLights = false;
124: // Ambient lights
125: for (int i = 0; i < AMB_LIGHTS; ++i) {
126: ambientTotal += AmbientLightColor[i] * matAmbient;
127: }
128:#endif
129:
130:#if DIR_LIGHTS>0
131: noLights = false;
132: // Directional lights
133: for (int i = 0; i < DIR_LIGHTS; ++i) {
134: vec3 lightDirection = normalize(DirLightPosition(i)); // Vector from fragment to light source
135: float dotNormal = max(dot(lightDirection, normal), 0.0); // Dot product between light direction and fragment normal
136: if (dotNormal > 0.0) { // If the fragment is lit
137: diffuseTotal += DirLightColor(i) * matDiffuse * dotNormal;
138: specularTotal += DirLightColor(i) * MatSpecularColor * pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
139: }
140: }
141:#endif
142:
143:#if POINT_LIGHTS>0
144: noLights = false;
145: // Point lights
146: for (int i = 0; i < POINT_LIGHTS; ++i) {
147: vec3 lightDirection = PointLightPosition(i) - vec3(position); // Vector from fragment to light source
148: float lightDistance = length(lightDirection); // Distance from fragment to light source
149: lightDirection = lightDirection / lightDistance; // Normalize lightDirection
150: float dotNormal = max(dot(lightDirection, normal), 0.0); // Dot product between light direction and fragment normal
151: if (dotNormal > 0.0) { // If the fragment is lit
152: float attenuation = 1.0 / (1.0 + PointLightLinearDecay(i) * lightDistance + PointLightQuadraticDecay(i) * lightDistance * lightDistance);
153: vec3 attenuatedColor = PointLightColor(i) * attenuation;
154: diffuseTotal += attenuatedColor * matDiffuse * dotNormal;
155: specularTotal += attenuatedColor * MatSpecularColor * pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
156: }
157: }
158:#endif
159:
160:#if SPOT_LIGHTS>0
161: noLights = false;
162: for (int i = 0; i < SPOT_LIGHTS; ++i) {
163: // Calculates the direction and distance from the current vertex to this spot light.
164: vec3 lightDirection = SpotLightPosition(i) - vec3(position); // Vector from fragment to light source
165: float lightDistance = length(lightDirection); // Distance from fragment to light source
166: lightDirection = lightDirection / lightDistance; // Normalize lightDirection
167: float angleDot = dot(-lightDirection, SpotLightDirection(i));
168: float angle = acos(angleDot);
169: float cutoff = radians(clamp(SpotLightCutoffAngle(i), 0.0, 90.0));
170: if (angle < cutoff) { // Check if fragment is inside spotlight beam
171: float dotNormal = max(dot(lightDirection, normal), 0.0); // Dot product between light direction and fragment normal
172: if (dotNormal > 0.0) { // If the fragment is lit
173: float attenuation = 1.0 / (1.0 + SpotLightLinearDecay(i) * lightDistance + SpotLightQuadraticDecay(i) * lightDistance * lightDistance);
174: float spotFactor = pow(angleDot, SpotLightAngularDecay(i));
175: vec3 attenuatedColor = SpotLightColor(i) * attenuation * spotFactor;
176: diffuseTotal += attenuatedColor * matDiffuse * dotNormal;
177: specularTotal += attenuatedColor * MatSpecularColor * pow(max(dot(reflect(-lightDirection, normal), camDir), 0.0), MatShininess);
178: }
179: }
180: }
181:#endif
182: if (noLights) {
183: diffuseTotal = matDiffuse;
184: }
185: // Sets output colors
186: ambdiff = ambientTotal + MatEmissiveColor + diffuseTotal;
187: spec = specularTotal;
188:}
189:// Final fragment color
190:out vec4 FragColor;
191:
192:void main() {
193:
194: // Compute final texture color
195: vec4 texMixed = vec4(1);
196: #if MAT_TEXTURES > 0
197: bool firstTex = true;
198: if (MatTexVisible(0)) {
199: vec4 texColor = texture(MatTexture[0], FragTexcoord * MatTexRepeat(0) + MatTexOffset(0));
200: if (firstTex) {
201: texMixed = texColor;
202: firstTex = false;
203: } else {
204: texMixed = Blend(texMixed, texColor);
205: }
206: }
207: #if MAT_TEXTURES > 1
208: if (MatTexVisible(1)) {
209: vec4 texColor = texture(MatTexture[1], FragTexcoord * MatTexRepeat(1) + MatTexOffset(1));
210: if (firstTex) {
211: texMixed = texColor;
212: firstTex = false;
213: } else {
214: texMixed = Blend(texMixed, texColor);
215: }
216: }
217: #if MAT_TEXTURES > 2
218: if (MatTexVisible(2)) {
219: vec4 texColor = texture(MatTexture[2], FragTexcoord * MatTexRepeat(2) + MatTexOffset(2));
220: if (firstTex) {
221: texMixed = texColor;
222: firstTex = false;
223: } else {
224: texMixed = Blend(texMixed, texColor);
225: }
226: }
227: #endif
228: #endif
229: #endif
230:
231: // Combine material with texture colors
232: vec4 matDiffuse = vec4(MatDiffuseColor, MatOpacity) * texMixed;
233: vec4 matAmbient = vec4(MatAmbientColor, MatOpacity) * texMixed;
234:
235: // Normalize interpolated normal as it may have shrinked
236: vec3 fragNormal = normalize(Normal);
237:
238: // Calculate the direction vector from the fragment to the camera (origin)
239: vec3 camDir = normalize(-Position.xyz);
240:
241: // Workaround for gl_FrontFacing
242: #extension GL_OES_standard_derivatives : enable
243: vec3 fdx = dFdx(Position.xyz);
244: vec3 fdy = dFdy(Position.xyz);
245: vec3 faceNormal = normalize(cross(fdx,fdy));
246: if (dot(fragNormal, faceNormal) < 0.0) { // Back-facing
247: fragNormal = -fragNormal;
248: }
249:
250: // Calculates the Ambient+Diffuse and Specular colors for this fragment using the Phong model.
251: vec3 Ambdiff, Spec;
252: phongModel(Position, fragNormal, camDir, vec3(matAmbient), vec3(matDiffuse), Ambdiff, Spec);
253:
254: // Final fragment color
255: FragColor = min(vec4(Ambdiff + Spec, matDiffuse.a), vec4(1.0));
256:}
257:
goroutine 1 [running, locked to thread]:
github.com/g3n/g3nd/app.(*App).Update(0xc00008c460, 0xc00053b080, 0xa69e9a2)
g3nd/app/app.go:633 +0x2c8
github.com/g3n/engine/app.(*Application).Run(0xc000064300, 0xc0000bff28)
GOPATH/pkg/mod/github.com/g3n/engine@v0.1.1-0.20190920151355-4fba891551e6/app/app-desktop.go:87 +0x15b
github.com/g3n/g3nd/app.(*App).Run(0xc00008c460)
g3nd/app/app.go:614 +0x9f
main.main()
g3nd/main.go:24 +0x27
@capnm I forgot to update g3nd to use the latest version (did so now in https://github.com/g3n/g3nd/commit/6c8ff52178c0e4e9906778effe962c6e9c2dfb0f). Should work now!
Should work now!
Almost ;-)
Could you probably print the shader path? Why there the 2 shader copies?
./g3nd
20:15:02.677858:I:G3ND:G3N Demo v0.6 starting
20:15:02.678016:I:G3ND:OpenGL version: 4.5 (Core Profile) Mesa 19.2.0-devel - padoka PPA
20:15:02.680563:I:G3ND:Using data directory:g3nd/data
panic: error compiling Fragment Shader: 0:51(159): error: sampler arrays indexed with non-constant expressions are forbidden in GLSL 1.30 and later
01:#version 330 core
02:#define AMB_LIGHTS 1
03:#define DIR_LIGHTS 0
04:#define POINT_LIGHTS 0
05:#define SPOT_LIGHTS 0
06:#define MAT_TEXTURES 1
07:precision highp float;
08:
09:
10://
11:// Material properties uniform
12://
13:
14:// Material parameters uniform array
15:uniform vec3 Material[6];
16:// Macros to access elements inside the Material array
17:#define MatAmbientColor Material[0]
18:#define MatDiffuseColor Material[1]
19:#define MatSpecularColor Material[2]
20:#define MatEmissiveColor Material[3]
21:#define MatShininess Material[4].x
22:#define MatOpacity Material[4].y
23:#define MatPointSize Material[4].z
24:#define MatPointRotationZ Material[5].x
25:
26:#if MAT_TEXTURES > 0
27: // Texture unit sampler array
28: uniform sampler2D MatTexture[MAT_TEXTURES];
29: // Texture parameters (3*vec2 per texture)
30: uniform vec2 MatTexinfo[3*MAT_TEXTURES];
31: // Macros to access elements inside the MatTexinfo array
32: #define MatTexOffset(a) MatTexinfo[(3*a)]
33: #define MatTexRepeat(a) MatTexinfo[(3*a)+1]
34: #define MatTexFlipY(a) bool(MatTexinfo[(3*a)+2].x)
35: #define MatTexVisible(a) bool(MatTexinfo[(3*a)+2].y)
36: // Alpha compositing (see here: https://ciechanow.ski/alpha-compositing/)
37: vec4 Blend(vec4 texMixed, vec4 texColor) {
38: texMixed.rgb *= texMixed.a;
39: texColor.rgb *= texColor.a;
40: texMixed = texColor + texMixed * (1 - texColor.a);
41: if (texMixed.a > 0.0) {
42: texMixed.rgb /= texMixed.a;
43: }
44: return texMixed;
45: }
46:#endif
47:// GLSL 3.30 does not allow indexing texture sampler with non constant values.
48:// This macro is used to mix the texture with the specified index with the material color.
49:// It should be called for each texture index.
50:#if MAT_TEXTURES > 0
51:vec4 MIX_POINT_TEXTURE(vec4 texMixed, mat2 rotation, int i) { \
52: if (MatTexVisible(i)) { \
53: vec2 pt = gl_PointCoord - vec2(0.5); \
54: vec4 texColor = texture(MatTexture[i], (rotation * pt + vec2(0.5)) * MatTexRepeat(i) + MatTexOffset(i)); \
55: if (i == 0) { \
56: texMixed = texColor; \
57: } else { \
58: texMixed = mix(texMixed, texColor, texColor.a); \
59: } \
60: }
61: return texMixed;
62:}
63:#endif
64:
@capnm thanks! That was another shader with a similar issue that I forgot to modify. Updated g3nd and all should be golden now. Please let me know if it isn't π
Do you know some magic how to use the new go mod for a library development?
I'd tried go mod vendor, but it doesn't clones the (g3n) repository, it just copies the old tip files (which is useless β¦)
Hey @capnm yeah - It was tricky to find info about this when I started using go modules!
You can add a line like replace your/library/package => local/library/path
to the end of the go.mod
file for the application that uses your library. E.g. when developing the engine I modify the g3nd go.mod
to be:
module github.com/g3n/g3nd
go 1.12
require (
github.com/g3n/engine v0.1.1-0.20190920210015-bf87e32ba567
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
)
replace github.com/g3n/engine => ../engine
Hope this helps!
Cool, that's exactly what i needed, thanks! I clicked through all the demos and the shader compiler seems happy now :-)
@capnm, you can easily switch to a different version of a module by using go get <module>@<commitID>
Related to #2, I'm not sure where that comes from:
https://github.com/g3n/engine/blame/master/renderer/shaders/sources.go#L137 or
renderer/shaders/include/material.glsl:35: vec4 texColor = texture(MatTexture[i], FragTexcoord * MatTexRepeat(i) + MatTexOffset(i));
./g3nd 04:34:03.453577:I:G3ND:G3N Demo v0.6 starting 04:34:03.453624:I:G3ND:OpenGL version: 4.5 (Core Profile) Mesa 19.2.0-devel - padoka PPA 04:34:03.458111:I:G3ND:Using data directory:g3nd/data