J.Doe
J.Doe

Reputation: 1552

Blending issues with simple particles

I draw the particles in my game as a capsule (Two GL_POINTS, two GL_TRIANGLES). Everything is nicely batched so that I draw the triangles first, then the points second (two draw calls total).

My problem is that in OpenGL es you have to round GL_POINTS yourself, and I have been doing it like this in the fragment shader.

precision highp float;

varying float outColor;

vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

void main()
{
    vec2 circCoord = 2.0 * gl_PointCoord - 1.0;
    gl_FragColor = vec4( hsv2rgb( vec3(outColor / 360.0, 1.0, 1.0) ) , step(dot(circCoord, circCoord), 1.0) );
}

The problem is I also need to do depth sorting, because a particle is drawn in two separate draw calls sometimes the z position is not correct without depth buffering because they are drawn in two draw calls.

Now that I have the depth buffer going, and the rounded points they are not mixing well, and instead of having rounded particles they have a black area around them. Any ideas?

Some extra notes: I am doing ios opengl es (tile based deferred rendering I believe)

Each particle is initially defined as two points, the current location and the location it was in last frame. These two points are drawn with GL_POINTS later. Then the rectangle part is made with two triangles decided by finding a vector perpendicular to the vector of the two points.

Also the particles are already sorted in front to back order. Technically their z position is arbitrary, I just need them to be intact.

Upvotes: 0

Views: 152

Answers (1)

solidpixel
solidpixel

Reputation: 12109

Also the particles are already sorted in front to back order. Technically their z position is arbitrary, I just need them to be intact.

I suspect that's your problem.

Points are square. You can fiddle the blending to make them appear round, but the geometry (and hence the depth value) is still square. Things behind the point are being Z-failed by the corners which are outside of the coloured round region.

The only fix to this without changing your algorithm completely is either use a triangle mesh rather than a point (so the actual geometry is round), or discard fragments in the fragment shader for point pixels which are outside of the round region you want to keep.

Note that using discard in shaders can be relatively expensive, so check the performance of that approach ...

Upvotes: 1

Related Questions