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.
Related
I use Vuforia SDK to render the video stream of my phone's camera on the screen.
So the texture is generated by the Vuforia library, not me.
The shaders used to render this background are:
// Vertex Shader
attribute vec4 a_position;
attribute vec2 a_textureCoords;
varying vec2 v_textureCoords;
uniform mat4 u_projectionMatrix;
void main()
{
gl_Position = u_projectionMatrix * a_position;
v_textureCoords = a_textureCoords;
}
// Fragment Shader
varying highp vec2 v_textureCoords;
uniform sampler2D u_currentTexture;
void main()
{
vec4 currentColor = texture2D(u_currentTexture, v_textureCoords);
gl_FragColor = currentColor;
}
Now, I want an overlay in the upper-left corner of the screen:
I don't want this overlay to display only a pink texture, but rather a multiply blend of the pink texture and the background texture. Note that the textures do not have the same coordinates.
But for now, let's forget about the blending and let's just render the background texture in the shader program of the pink texture. So in the end, yes, one should see no difference between the background-only version and the bacground with overlay version.
As you can see (look at the painting and the top of the chair), there is a small offset...
The shaders used to render the overlay are:
// Vertex Shader
attribute vec4 a_position;
attribute vec2 a_currentTextureCoords;
varying vec2 v_currentTextureCoords;
void main()
{
gl_Position = a_position;
v_currentTextureCoords = a_currentTextureCoords;
}
// Fragment Shader
varying highp vec2 v_currentTextureCoords;
uniform sampler2D u_currentTexture;
uniform sampler2D u_backgroundTexture;
void main()
{
vec2 screenSize = vec2(1080.0, 1920.0);
vec2 cameraResolution = vec2(720.0, 1280.0);
vec2 texelSize = vec2(1.0 / screenSize.x, 1.0 / screenSize.y);
vec2 scaleFactor = vec2(cameraResolution.x / screenSize.x, cameraResolution.y / screenSize.y);
vec2 uv = gl_FragCoord.xy * texelSize * scaleFactor;
uv = vec2(scaleFactor.y - uv.y, scaleFactor.x - uv.x);
vec4 backgroundColor = texture2D(u_backgroundTexture, uv);
gl_FragColor = backgroundColor;
}
Are my calculations wrong?
Why do you need this line?
uv = vec2(scaleFactor.y - uv.y, scaleFactor.x - uv.x);
Not sure what arithmetic relationship the absolute texture coordinates have with the scale factor which needs an addition or a subtraction ...
P.S. it's not related to your question, but your shaders will be shorter and easier to read if you just use the vector operations in the language. For example, replace:
vec2 scaleFactor = vec2(cameraResolution.x / screenSize.x, cameraResolution.y / screenSize.y);
... with ...
vec2 scaleFactor = cameraResolution / screenSize;
As long as the vector types are the same length, it will do exactly what you expect with a lot less typing ...
My games runs fine on newer devices (eg..droid turbo, galaxy note 3) but on my motorola xoom there are problems, such as :
1) My shaderProgram causes the stage that is drawn inside of it to not be rendered
2) Touch inputs don't work every time using InputProcessor (only senses 90% of the time)
These are the problems I currently notice. Could this be because it is an older OS version (4.1.2)? Not that old. Are known bugs with libgdx's ShaderProgram? Even then, the touch input not sensing every click is very strange. Thanks for your time and help! My rendering code for the shaderProgram is all correct, so no need to show that. And for touchInput, I am just using touchDown method from InputProcessor.
EDIT :
Error produced by shaderProgram
"(22) : error C1101: ambiguous overloaded function reference "smoothstep(mediump float, float, lowp float)"
Vertex Shader
#version 100
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_worldView;
uniform vec2 u_lightPos;
uniform vec3 u_lightColor;
uniform vec4 u_spaceColor;
varying vec4 v_color;
varying vec2 v_texCoords;
varying vec2 v_lightPos;
varying vec3 v_lightColor;
varying vec2 v_position;
varying vec4 v_spaceColor;
void main() {
v_color = a_color;
v_lightColor = u_lightColor;
v_lightPos = u_lightPos;
v_position.xy = a_position.xy;
v_texCoords = a_texCoord0;
gl_Position = u_worldView * a_position;
v_spaceColor = u_spaceColor;
}
Fragment Shader
#version 100
#ifdef GL_ES
precision lowp float;
#endif
varying vec4 v_color;
varying vec2 v_texCoords;
varying vec2 v_lightPos;
varying vec3 v_lightColor;
varying vec2 v_position;
varying vec4 v_spaceColor;
uniform sampler2D u_texture;
void main() {
for(int row = 0; row < 2; row++) {
for(int col = 0; col < 2; col++) {
float dist = distance(v_position, vec2(-1 + col, 1 - row));
float delta = 0.1;
float alpha = smoothstep(100.0-delta, 100.0, dist);
if(dist > 23.0){
gl_FragColor = mix(v_spaceColor, v_color, alpha);
}
else{
gl_FragColor = v_color * texture2D(u_texture, v_texCoords);
}
}
}
}
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 try to make clippingNode with circle stencil, but the result is the edge is not smooth
Tried with DrawNode.drawDot and a Sprite as stencil, same result
I also tried with many threshold numbers, still the same, could be worse.. this image is using 0.05
Is there anyway to make the edge smoother?
I'm using cocos2d-x 3.5
Try the solution provided in this forum by using anti-aliasing:
const char* ccPositionColorLengthTexture_frag = STRINGIFY(
\n#ifdef GL_ES\n
\n#extension GL_OES_standard_derivatives : enable\n
varying mediump vec4 v_color;
varying mediump vec2 v_texcoord;
\n#else\n
varying vec4 v_color;
varying vec2 v_texcoord;
\n#endif\n
void main()
{
\n#if defined GL_OES_standard_derivatives\n
gl_FragColor = v_color*smoothstep(0.0, length(fwidth(v_texcoord)), 1.0 - length(v_texcoord));\n
\n#else\n
gl_FragColor = v_color*step(0.0, 1.0 - length(v_texcoord));
\n#endif\n
}
);
with some adjustments like
changed the:
dot->drawDot(end, DOT_RADIUS / 2.0, color);
to:
dot->drawSegment(start, end, DOT_RADIUS / 2, color);
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