I am trying to build a shader (in glsl 1.0) that uses an array of sampler2d textures, and an array of samplerCube textures. Strangely, I can't link it (and I can't get an error message) if I alternate the usage of the two textures. By trials and error, I located the code that caused the issue:
This fail to compile:
varying highp vec2 vTextureCoord;
varying highp vec2 vTextureCoord2;
varying lowp vec3 vLighting;
varying lowp vec4 vColor;
varying lowp vec3 vNormal;
#ifdef Textures\r\n"
uniform sampler2D uSampler[Textures];
uniform lowp vec2 texFlag[Textures];
uniform lowp mat3 texMat[Textures];
uniform lowp float tex_coord_set[Textures];
uniform samplerCube uSamplerC[Textures];
#endif
uniform lowp vec3 fogColor;
varying lowp float fogBlend;
void main(void) {
#ifdef Textures
mediump vec4 pixColor = vColor;
mediump vec3 SpecNormal = reflect(vec3(0.0,0.0,1.0), vNormal);
mediump vec4 texelColor;
pixColor += textureCube(uSamplerC[0], vNormal);
pixColor += texture2D(uSampler[0], vec2(0.0,0.0));
pixColor += textureCube(uSamplerC[1], vNormal);
pixColor += texture2D(uSampler[1], vec2(0.0,0.0));
else
mediump vec4 pixColor = vColor;
#endif
But if I put:
pixColor += textureCube(uSamplerC[0], vNormal);
pixColor += textureCube(uSamplerC[1], vNormal);
pixColor += texture2D(uSampler[0], vec2(0.0,0.0));
pixColor += texture2D(uSampler[1], vec2(0.0,0.0));
(putting first all sampler of one type) it seems to link perfectly. Why?
(note: this code, in current form, is pointless, I used it only to expose the issue)
Related
I have created a RawShaderMaterial for an InstancedBufferGeometry object that is rendering well with 1 sampler2D uniform. As soon as it uses a second sampler2D uniform, it renders with a lot of vertical tearings
Here is the fragment shader:
precision highp float;
uniform sampler2D utexture1;
uniform sampler2D utexture2;
varying float vindex;
varying vec2 vUv;
varying vec3 mapcolor;
vec4 gettexture(){
vec4 color;
if(vindex==0.){
color = texture2D(utexture1, vUv)*vec4(mapcolor,1.);
}else if(vindex==1.){
color = texture2D(utexture1, vUv)*vec4(mapcolor,1.);
}else if(vindex==2.){
color = texture2D(utexture2, vUv)*vec4(mapcolor,1.);
}else if(vindex==3.){
color = texture2D(utexture2, vUv)*vec4(mapcolor,1.);
}
return color;
}
void main() {
gl_FragColor = gettexture();
}
Notes: The 2 textures used for the sampler2D have the same size (512x512) and they are loaded before material creation.
Anyone knows where these vertical tearings come from?
Thank you in advance for your help!
I have variable in vertex shader "uIsTeapot".
uniform float uIsTeapot;
Vertex shader work with it very well, but fragment shader don't see it. If I use
if (uIsTeapot == 0.0)
then an error occured
"uIsTeapot": undeclared identifier
but I defined it in vertex shader. If I define uIsTeapot in both shaders as uniform, then program say "Could not initialise shaders" since program don't pass veryfication
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
EDITED:
I add mediump to variables and now program compiled without errors, but result is one object on screen, but I draw two object.
Vertex shader
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
attribute vec2 aTextureCoord;
attribute vec4 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
uniform vec3 uAmbientColor;
uniform vec3 uPointLightingLocation;
uniform vec3 uPointLightingColor;
uniform mediump float uIsTeapot;
//varying float vIsTeapot;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
varying vec4 vColor;
void main(void) {
if (uIsTeapot == 1.0) {
vec4 mvPosition = uMVMatrix * vec4(aVertexPosition, 1.0);
gl_Position = uPMatrix * mvPosition;
vec3 lightDirection = normalize(uPointLightingLocation - mvPosition.xyz);
vec3 transformedNormal = uNMatrix * aVertexNormal;
float directionalLightWeighting = max(dot(transformedNormal, lightDirection), 0.0);
directionalLightWeighting = 100.0;
vLightWeighting = uAmbientColor + uPointLightingColor * directionalLightWeighting;
vTextureCoord = aTextureCoord;
}
if (uIsTeapot == 0.0) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
} }
Fragment shader
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
varying vec4 vColor;
uniform sampler2D uSampler;
uniform mediump float uIsTeapot;
//varying float vIsTeapot;
void main(void) {
if (uIsTeapot == 1.0) {
vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
} else {
gl_FragColor = vColor;
}
}
You need to declare it in both shaders, with the same precision.
What do you mean by:
then program don't work right.
Can you post your vertex shader and your fragment shader? I suspect you are relying on the default precision, and it is likely that you are using highp in the vertex shader and mediump in the fragment shader
Try using:
uniform mediump float uIsTeapot;
... in both vertex shader and fragment shader.
I'm very new to OpenGL, GLSL and WebGL. I'm trying to get this sample code to work in a tool like http://shdr.bkcore.com/ but I can't get it to work.
Vertex Shader:
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
Fragment Shader:
precision highp float;
uniform float time;
uniform vec2 resolution;
varying vec3 fPosition;
varying vec3 fNormal;
uniform sampler2D tex0;
void main()
{
float border = 0.01;
float circle_radius = 0.5;
vec4 circle_color = vec4(1.0, 1.0, 1.0, 1.0);
vec2 circle_center = vec2(0.5, 0.5);
vec2 uv = gl_TexCoord[0].xy;
vec4 bkg_color = texture2D(tex0,uv * vec2(1.0, -1.0));
// Offset uv with the center of the circle.
uv -= circle_center;
float dist = sqrt(dot(uv, uv));
if ( (dist > (circle_radius+border)) || (dist < (circle_radius-border)) )
gl_FragColor = bkg_color;
else
gl_FragColor = circle_color;
}
I figured that this code must be from an outdated version of the language, so I changed the vertex shader to:
precision highp float;
attribute vec2 position;
attribute vec3 normal;
varying vec2 TextCoord;
attribute vec2 textCoord;
uniform mat3 normalMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
varying vec3 fNormal;
varying vec3 fPosition;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
TextCoord = vec2(textCoord);
}
That seemed to fix the error messages about undeclared identifiers and not being able to "convert from 'float' to highp 4-component something-or-other", but I have no idea if, functionally, this will do the same thing as the original intended.
Also, when I convert to this version of the Vertex Shader I have no idea what I'm supposed to do with this line in the Fragment Shader:
vec2 uv = gl_TexCoord[0].xy;
How do I convert this line to fit in with the converted vertex shader and how can I be sure that the vertex shader is even converted correctly?
gl_TexCoord is from desktop OpenGL, and not part of OpenGL ES. You'll need to create a new user-defined vec2 varying to hold the coordinate value.
i'm trying simple texture splatting on ios opengl es 2.0 (ipad). I have 4 tiled textures in pvrt compressed atlas (2x2 tiles). 4 single textures on 4 texture units was terribly slow.
vertex shader:
attribute lowp vec4 position;
attribute lowp vec2 tex0;
varying lowp vec2 surfCoord;
uniform mat4 projection_modelview;
uniform lowp float uv_coef;
varying lowp vec2 texCoord1;
varying lowp vec2 texCoord2;
varying lowp vec2 texCoord3;
varying lowp vec2 texCoord4;
void main()
{
gl_Position = projection_modelview * position;
vec2 texCoord = fract(vec2(position.x / uv_coef, position.y / uv_coef));
texCoord1 = texCoord * 0.5;
texCoord2 = texCoord1 + vec2(0.5, 0);
texCoord3 = texCoord1 + vec2(0, 0.5);
texCoord4 = texCoord1 + vec2(0.5, 0.5);
surfCoord = tex0;
}
fragment shader:
uniform sampler2D texture0; // surface alpha map
uniform sampler2D texture1; // atlas
varying lowp vec2 surfCoord;
varying lowp vec2 texCoord1;
varying lowp vec2 texCoord2;
varying lowp vec2 texCoord3;
varying lowp vec2 texCoord4;
void main()
{
lowp vec4 surfTexel = texture2D(texture0, surfCoord);
lowp vec4 texel1 = texture2D(texture1, texCoord1);
lowp vec4 texel2 = texture2D(texture1, texCoord2);
lowp vec4 texel3 = texture2D(texture1, texCoord3);
lowp vec4 texel4 = texture2D(texture1, texCoord4);
texel1 *= surfTexel.r;
texel2 = mix(texel1, texel2, surfTexel.g);
texel3 = mix(texel2, texel3, surfTexel.b);
gl_FragColor = mix(texel3, texel4, surfTexel.a);
}
shows this one:
(source: inputwish.com)
My problem is probably texture unit interpolators but i don't how to resolve. I don't see mistake in my shaders. Any advice please?
mistake is using fract in vertex shader. it's too early. It should be in fragment shader:
lowp vec4 texel1 = texture2D(texture1, fract(texCoord) * 0.5);
lowp vec4 texel2 = texture2D(texture1, fract(texCoord) * 0.5 + vec2(0.5, 0.0));
lowp vec4 texel3 = texture2D(texture1, fract(texCoord) * 0.5 + vec2(0.0, 0.5));
lowp vec4 texel4 = texture2D(texture1, fract(texCoord) * 0.5 + vec2(0.5, 0.5));
... and mix them together..
anyway it's slow because dependent texture reads on ipad ios.
I have been working in a skull with opengl es 2.0. The skull appeared without some faces:
After that I dedided to disable gl_cull_face. The problem with the faces was
solved but the the skull appears now without light and I havenĀ“t changed shader code:
I have tried with other lighting algorithms and the skull continues black. I can't understand what is the relationship between gldisable(gl_cull_face) and lighting. The shader code is this:
Vertex Shader:
uniform mediump mat4 MODELVIEWMATRIX;
uniform mediump mat4 PROJECTIONMATRIX;
uniform mediump mat3 NORMALMATRIX;
uniform mediump vec3 LIGHTPOSITION;
varying lowp vec3 lightcolor;
attribute mediump vec3 POSITION;
attribute lowp vec3 NORMAL;
lowp vec3 normal;
attribute mediump vec2 TEXCOORD0;
varying mediump vec2 texcoord0;
void main( void ) {
mediump vec3 position = vec3( MODELVIEWMATRIX * vec4( POSITION, 1.0 ) );
normal = normalize( NORMALMATRIX * NORMAL );
mediump vec3 lightdirection = normalize( LIGHTPOSITION - position );
lowp float ndotl = max( dot( normal, lightdirection ), 0.0 );
lightcolor = ndotl * vec3( 1.0 );
gl_Position = PROJECTIONMATRIX * vec4( position, 1.0 );
texcoord0 = TEXCOORD0;
}
Fragment Shader:
varying mediump vec2 texcoord0;
uniform sampler2D DIFFUSE;
varying lowp vec3 lightcolor;
void main( void ) {
gl_FragColor = texture2D( DIFFUSE, texcoord0 ) * vec4( lightcolor, 1.0 ) + vec4( 0.1);
}
Thank you.