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);
Related
I am writing an android game using Love2D in which I am using a Gaussian Blur Shader to get a bloom effect, however I am testing it on PC, and the results on PC and Android are very different, to the point of making the shader useless on Android.
Here is how the PC version looks like:
And Here is how the Android version looks like:
Both are running with the following shaders, doing a pass with offset direction vertical and horizontal.
// Vertex Shader:
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
varying vec2 coordinate2b;
varying vec2 coordinate1b;
varying vec2 coordinate0f;
varying vec2 coordinate1f;
varying vec2 coordinate2f;
uniform vec2 offset_direction;
vec4 position(mat4 transform_projection, vec4 vertex_position)
{
coordinate2b = VertexTexCoord.xy + -3.230769 * offset_direction;
coordinate1b = VertexTexCoord.xy + -1.384615 * offset_direction;
coordinate0f = VertexTexCoord.xy + 0.000000 * offset_direction;
coordinate1f = VertexTexCoord.xy + 1.384615 * offset_direction;
coordinate2f = VertexTexCoord.xy + 3.230769 * offset_direction;
return transform_projection * vertex_position;
}
// Fragment Shader:
#ifdef GL_ES
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
varying vec2 coordinate2b;
varying vec2 coordinate1b;
varying vec2 coordinate0f;
varying vec2 coordinate1f;
varying vec2 coordinate2f;
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords)
{
vec4 c = vec4(0.0);
c += vec4(0.070270) * Texel(texture, coordinate2b);
c += vec4(0.316216) * Texel(texture, coordinate1b);
c += vec4(0.227027) * Texel(texture, coordinate0f);
c += vec4(0.316216) * Texel(texture, coordinate1f);
c += vec4(0.070270) * Texel(texture, coordinate2f);
return c * color;
}
I am currently guessing the problem is with float precision, but I am not sure what I would have to do to fix that.
Thanks to Columbo, I found out two different problems when running the game on my android.
First was that texture filtering was not linear, this making the scaling optimization not working and having weird problems with scaling.
Second, love2d for android is not supporting gamma correction, so when running on my phone the game was not rendering color correctly and the blur was not visible due to the dark background.
Always check for gamma correction!
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 ...
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 want to colorize a sprite so that RGB channels are all 1 and alpha remains unchanged.
I gather this should be done with shaders, but the two accepted answers on StackOverflow (Change sprite color into white and libgdx changing sprite color while hurt) don't work for me - the result is transparent, and they don't work on http://shdr.bkcore.com/ either
All you need is to replace the RGB each with 1.0 in the fragment shader.
Vertex shader-- This is like the one in SpriteBatch with vertex color removed since you aren't using it:
attribute vec4 a_position;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
void main()
{
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
Fragment shader-- grab just the alpha value from the texture.:
#ifdef GL_ES
precision lowp float; //since the only value we're storing is part of a color
#endif
varying vec2 v_texCoords;
uniform sampler2D u_texture;
void main()
{
float alpha = texture2D(u_texture, v_texCoords).a;
gl_FragColor = vec4(1.0, 1.0, 1.0, alpha);
}
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.