I have an application drawing some objects with OpenG-ES 2.0.The application fails to render on some of samsung devices. I tried debugging and it seems to be problem with the vertex and fragment shaders.
Here is my shader code:
Vertex Shader:
attribute vec3 Position;
attribute vec4 SourceColor;
varying vec4 DestinationColor;
uniform mat4 Projection;
uniform mat4 Modelview;
uniform mat4 CordTransform;
attribute float flag;
attribute float clubColorFlag;
attribute vec2 TexCoordIn; // New
varying vec2 TexCoordOut; // New
varying float flagS;
varying float flagClubColorS;
void main(void) {
gl_Position = Projection * Modelview * vec4(Position,1.0);
flagS = flag;
flagClubColorS = clubColorFlag;
if (clubColorFlag == 1.0) {
DestinationColor = vec4(0.190,0.309,0.309,1.0);
}
else {
DestinationColor = SourceColor;
}
exCoordOut = TexCoordIn;
gl_PointSize = 1.0;
}
Fragment Shader:
varying lowp vec4 DestinationColor;
varying lowp vec2 TexCoordOut; // New
uniform sampler2D Texture; // New
varying lowp float flagS;
varying lowp float flagClubColorS;
void main(void) {
gl_FragColor = DestinationColor;
if(flagS == 1.0){
gl_FragColor = DestinationColor;
}
else if (flagClubColorS == 1.0) {
gl_FragColor = DestinationColor;
}
else if (flagS == 0.0){
gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut); // New
}
}
I am not sure what is the problem but I get texture uniform -1 if I comment out the if-else part in fragment shader. In other scenario, it is zero. Both shaders compile without any errors.
Is it related to precision? Please help me to debug the issue.
I am answering my own question for people who are going to refer this later. I could kind of solve the issue.
The problem was not in either of the shaders. The issue was, I was using glDrawElements() method to draw objects with vertex and index buffers. I replaced this call with glDrawArrays() method using only vertex buffer and everything worked fine.
I am still not sure of the exact issue but it may help somebody struggling long for similar issue.
Related
I am trying to write an opengl shader that applies Vigenette Shader. But the issue I am facing is that it shows up a circle as you can see in the right image.
I want to find out what exactly must have been going wrong in my code.
I have also pasted the code below too.
Code For My Vigenette Shader
precision mediump float;
uniform sampler2D u_Texture;
uniform sampler2D u_Vigenette;
uniform sampler2D u_Map;
varying vec2 v_TexCoordinate;
void main()
{
vec3 texel = texture2D(u_Texture, v_TexCoordinate).rgb;
texel.r = (texel.r == 1.0)?.9961:texel.r;
texel.g = (texel.g == 1.0)?.9961:texel.g;
texel.b = (texel.b == 1.0)?.9961:texel.b;
texel = vec3(
texture2D(u_Map, vec2(texel.r, .16666)).r,
texture2D(u_Map, vec2(texel.g, .5)).g,
texture2D(u_Map, vec2(texel.b, .83333)).b);
texel.r = (texel.r == 1.0)?.9961:texel.r;
texel.g = (texel.g == 1.0)?.9961:texel.g;
texel.b = (texel.b == 1.0)?.9961:texel.b;
vec2 tc = (2.0 * v_TexCoordinate) - 1.0;
float d = dot(tc, tc);
vec2 lookup = vec2(d, texel.r);
texel.r = texture2D(u_Vigenette, lookup).r;
lookup.y = texel.g;
texel.g = texture2D(u_Vigenette, lookup).g;
lookup.y = texel.b;
texel.b = texture2D(u_Vigenette, lookup).b;
gl_FragColor = vec4(texel, 1.0);
}
Thanks in Advance for the help.
Bit of a guess because there's not enough information to be sure, but I think that your code is expecting the result of
float d = dot(tc, tc);
to be in the range 0 to 1, but it's actually in the range 0 to 2.
Perhaps you want to rescale it, or perhaps the u_Vigenette texture is set to repeat instead of clamp to edge.
I needed to create some ripling effect for one sprite in my game, here's the vertexShader:
attribute vec4 a_position; // just taking in necessary attributes
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans; // Combination of view and projection matrix
varying vec2 v_texCoords;
void main() {
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position; //as I said, it is sprite so no need for modelMatrix
}
and here's the fragment:
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoords;
uniform sampler2D u_texture; //texture of sprite
uniform float time;
void main()
{
vec2 uv;
if (time > 0.0) { // time is > 0.0 when I want the ripling effect to be applied,
vec2 cPos = -1.0 + 2.0 * v_texCoords.xy; // converting tex.Coords to -1 - 1
float cLength = length(cPos); //taking length of it
uv = v_texCoords.xy +( (cPos/cLength)*cos(cLength*12.0-time*4.0)*0.03 ) // just some calculations for the ripling effect
}
else
uv = v_texCoords.xy; // if I don't want to use the ripling effect, I use normal texCoords
vec4 tex = texture2D(u_texture, uv); //sampling texture
gl_FragColor = tex;
}
It all works fine, the performance's fine on PC, but when running it on android, the performance is a lot worse... As you can see, shader's are trivial but they somehow are expensive.. Anyways, sprite I draw has width about 2000 - 4000 px and height 720. Also, when I replace v_texCoords with different vector(for example vec2(1, 1)) in cPos calc: vec2 cPos = -1.0 + 2.0 * v_texCoords.xy; the performance improves heavily..
I don't really know what's so expensive there. If anyone had some advices, I'd be happy. Thanks in advance
I'm making a multi-platform Game Engine (Open source in the future), and I was making a game based on it. When testing on a Samsung Galaxy S2 (I9100B), it runs perfectly, but when I tried to run on my other phone (Samsung Galaxy S) the things get messy.
Here is a screenshot when running on Galaxy S2:
And here is when I run on the Galaxy S:
I managed to reduce the number of triangles in the scene too, but even with 50 triangles on the screen I got the same problem.
Disabling the lighting reduces the problem, but does not eliminate it. I thought that was a memory problem on my phone, so I tried on another Galaxy S, but the same problem occurs.
Does someone know where I can start looking? The automatic GC is not frequent (about 2 times per 5 seconds).
Samsung Galaxy S2:
Android Version 2.3.4
Kernel: 2.6.35.7-I9100UHKI2-CL553601 se.infra#SEI-07 #2
Samsung Galaxy S:
Android Version 2.3.3
Kernek: 2.6.35.7-I9000BVJJW4-CL240848 pescio#bldhp-4 #28
Fragment Shader Code:
precision mediump float;
uniform sampler2D uSampler;
uniform float uIsPoint;
uniform float uEnableLight;
uniform float uDisableTexture;
varying vec4 vColor;
varying vec2 vTextureCoord;
varying vec4 vPosition;
uniform vec3 uPointLightingColor;
varying vec3 vColorWeight;
void main(){
if(uIsPoint >= 2.0) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}else{
vec4 calcColor;
if(uEnableLight >= 2.0)
calcColor = vec4(vColor.rgb * vColorWeight, vColor.a);
else
calcColor = vColor;
vec4 texColor = vec4(1.0,1.0,1.0,1.0);
if(uDisableTexture < 2.0)
texColor = texture2D(uSampler, vTextureCoord);
gl_FragColor = vec4(texColor.rgb * calcColor.rgb, texColor.a*calcColor.a);
}
}
Vertex Shader Code:
//Atributos
uniform mat4 uMVMatrix; //Model/View Matrix
uniform mat4 uPMatrix; //Model/View/Projection Matrix
uniform mat3 uNMatrix; //Normal Matrix
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
attribute vec2 aTextureCoord;
attribute vec3 aNormal;
varying vec4 vColor;
varying vec2 vTextureCoord;
varying vec3 vNormal;
varying vec4 vPosition;
//Lighting
uniform vec3 uAmbientColor;
uniform vec3 uLightDir;
uniform vec3 uLightColor;
uniform vec3 uSpecLightColor;
uniform float uShine;
varying vec3 vColorWeight;
void main(){
//Lighting
vec3 normal = normalize(uNMatrix * aNormal);
vec3 lightNorm = normalize(uLightDir);
float lightWeight = max(dot(aNormal,lightNorm),0.0);
vec3 halfVec = normalize(uLightDir - gl_Position.xyz);
float specWeight = pow(max(dot(normal,halfVec),0.0),uShine);
vColorWeight = uAmbientColor + (lightWeight * uLightColor) + (uSpecLightColor*specWeight);
//Others
vNormal = uNMatrix * aNormal;
vPosition = uMVMatrix * vec4(aVertexPosition,1.0);
gl_Position = uPMatrix * vPosition;
vColor = aVertexColor;
gl_PointSize = 2.0;
vTextureCoord = aTextureCoord;
}
Try increasing your depth buffer precision.
http://www.opengl.org/wiki/Depth_Buffer_Precision
This looks like a vertex ordering issue. The Galaxy S probably has back face culling turned on by default, so it will remove all triangles that do not face the viewer.
Which triangles are front-facing can be determined with glFrontFace()
You should try both clockwise and counter-clockwise to see if the culled and non-culled triangles switch places. If they do, you must either turn off back-face culling or make sure the vertex order is the same for all triangles.
This two are My VertexShader and Fragment Shader file:
Vertex Shader File:
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
varying vec4 co;
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
co = inputTextureCoordinate;
}
Fragment Shader File:
uniform sampler2D videoFrame; // the texture with the scene you want to blur
varying mediump vec2 textureCoordinate;
varying mediump vec4 co;
precision mediump float;
vec4 nightVision()
{
float luminanceThreshold = 0.2; // 0.2
float colorAmplification = 2.0; // 4.0
float effectCoverage = 1.0; // 1.0
vec4 finalColor;
// Set effectCoverage to 1.0 for normal use.
if (co.x < effectCoverage)
{
vec3 c = texture2D(videoFrame, co.st).rgb;
float lum = dot(vec3(0.30, 0.59, 0.11), c);
if (lum < luminanceThreshold) {
c *= colorAmplification;
}
vec3 visionColor = vec3(0.1, 0.95, 0.2);
finalColor.rgb = (c) * visionColor;
} else {
finalColor = texture2D(videoFrame, co.st);
}
vec4 sum = vec4(0.0, 0.0, 0.0, 1.0);
sum.rgb = finalColor.rgb;
return sum;
}
void main(void)
{
gl_FragColor = nightVision();
}
Now, I want to Use this code to give the Camera Preview Effect in Android Camera preview. And also want to save the Picture that captured by that effect.
So is it possible to do so ???
If yes then Please help me with Some code as i am new to OpenGles with Android Camera.
Yes, it's definitely possible. There are a lot of different approaches to building this, and a small code sample won't really help much. The basic idea is to feed the frames you get from the camera to OpenGL as textures.
Check out Camera image as an OpenGL texture on top of the native camera viewfinder. The source code should give you an idea for how to proceed.
I've been stuck for several days now, trying to make my shader working properly.
The problem is that when I'm not attaching a texture on my object, I multiply the ambient by the light color and I get a dark object when no light, and illuminated properly when a light source is activated.
The problem is that when I attach a texture and multiply it by ambient and light color I get a transparent object that shows up only when a light source is activated, and you can even see through the object while it is illuminated!
I've been trying several codes snippets from the internet but I always get the same result. What I'm doing wrong here? I'm desperate...
The application is developed on Android.
Here is my Vertex Shader:
uniform mat4 uMVPMatrix;
uniform mat4 normalMatrix;
// eye pos
uniform vec3 eyePos;
// position and normal of the vertices
attribute vec4 aPosition;
attribute vec3 aNormal;
// texture variables
uniform float hasTexture;
varying float tex;
attribute vec2 textureCoord;
varying vec2 tCoord;
// lighting
uniform vec4 lightPos;
uniform vec4 lightColor;
// material
uniform vec4 matAmbient;
uniform vec4 matDiffuse;
uniform vec4 matSpecular;
uniform float matShininess;
// normals to pass on
varying vec3 vNormal;
varying vec3 EyespaceNormal;
varying vec3 lightDir, eyeVec;
void main() {
// pass on texture variables
tex = hasTexture;
tCoord = textureCoord;
// normal
EyespaceNormal = vec3(normalMatrix * vec4(aNormal, 1.0));
// the vertex position
vec4 position = uMVPMatrix * aPosition;
// light dir
lightDir = lightPos.xyz - position.xyz;
eyeVec = -position.xyz;
gl_Position = uMVPMatrix * aPosition;
}
And here is my Fragment shader:
precision mediump float;
// texture variables
uniform sampler2D texture1; // color texture
varying float tex;
varying vec2 tCoord;
varying vec3 vNormal;
varying vec3 EyespaceNormal;
// light
uniform vec4 lightPos;
uniform vec4 lightColor;
// material
uniform vec4 matAmbient;
uniform vec4 matDiffuse;
uniform vec4 matSpecular;
uniform float matShininess;
// eye pos
uniform vec3 eyePos;
// from vertex s
varying vec3 lightDir, eyeVec;
void main() {
vec4 b = lightColor;
vec4 c = matAmbient;
vec4 d = matDiffuse;
vec4 e = matSpecular;
vec3 g = eyePos;
float f = matShininess;
vec3 N = normalize(EyespaceNormal);
vec3 E = normalize(eyeVec);
vec3 L = normalize(lightDir);
// Reflect the vector. Use this or reflect(incidentV, N);
vec3 reflectV = reflect(-L, N);
// Get lighting terms
vec4 ambientTerm;
if (tex >= 1.0) {
ambientTerm = texture2D(texture1, tCoord);
}
else
ambientTerm = matAmbient * lightColor;
vec4 diffuseTerm = matDiffuse * max(dot(N, L), 0.0);
vec4 specularTerm = matSpecular * pow(max(dot(reflectV, E), 0.0), matShininess);
gl_FragColor = ambientTerm * diffuseTerm + specularTerm;
}
Thanks in advance.
OK I found it, thanks to JPD002, I was revising the shader again, and I found out that it has to be
vec4 diffuseTerm = matDiffuse * max(dot(N, L), 0.0);
vec4 specularTerm = matSpecular * pow(max(dot(reflectV, E), 1.0), matShininess);
Thanks JDP002, it is always good to have 4 eyes on code rather than 2 =D