Blending function for 3D sprites in openGL ES 2.0 - ios

I'm developing a 3D game for iOS with openGL ES2.
the 3D sprites should be semi-transparent with an alpha channel of about 0.5 to show the background.
The problem is that I want the back side of the 3D sprites to be completely not visible. In other words i want to see only the front side of the sprite (just like it would appear with an alpha channel = 1) but with the background visible through it.
Is there any blend function or some shader setting to obtain this effect?

Presumably your sprites are textured onto geometry (quads drawn using triangles or triangle strips)? All you need to do is enable face culling:
glEnable(GL_CULL_FACE);
This will prevent drawing the "back" side of any polygon well before it gets to the blending stage of the graphics pipeline -- so you get a performance win in addition to the visual effect your after.
You do need to make sure that your "front" and "back" sides are defined consistently, though. By default, OpenGL considers any polygon whose vertices are in counter-clockwise order to be front-facing (and vice versa). If enabling face culling makes all your sprites disappear, it's because their vertices are in clockwise order. Either reorder your vertices, or tell OpenGL that they're all backwards with glFrontFace(GL_CW).

Related

Manim - semi-transparent sphere doesn't cover lines

I'm trying to animate a trajectory of a particle on a spherical surface in manim. I made the sphere semi-transparent so it's easy to say when the particle is on the front side and when it is on the back side of the sphere. However after I plot the trajectory, even the parts that are supposed to be behind the sphere are the same color as the ones in front of it.
As you can see this issue is not present in the coordinate axes. The parts of axes that are inside of the sphere have different color, because the semi-transparent surface is between them and camera.
I'm using the following code
S=Sphere(center=(0,0,0), radius=1.09,resolution=(15, 15)).set_opacity(0.4)
S.set_color(GRAY)
self.add(axes,S)
for i in range(100):
self.play(Create(Traj[i]))
Where Traj is an array consisting of line elements of the trajectory.
Even if I set the sphere opacity to 1, I can still see the whole trajectory, even if most of it should be behind the spehre. How to make the sphere cover the back part of the trajectory?

Metal. Why does setting MTLCullMode to none turn off depth comparison?

I an rendering a simple box:
MDLMesh(boxWithExtent: ...)
In my draw loop when I turn off back-face culling:
renderCommandEncoder.setCullMode(.none)
All depth comparison is disabled and sides of the box are drawn completely wrong with back-facing quads in front of front-facing.
Huh?
My intent is to include back-facing surfaces in the depth comparison not ignore them. This is important for when I have, for example, a shape with semi-transparent textures that reveal the shape's internals which have a different shading style. How to I force depth comparison?
UPDATE
So Warren's suggestion is an improvement but it is still not correct.
My depthStencilDescriptor:
let depthStencilDescriptor = MTLDepthStencilDescriptor()
depthStencilDescriptor.depthCompareFunction = .less
depthStencilDescriptor.isDepthWriteEnabled = true
depthStencilState = device.makeDepthStencilState(descriptor: depthStencilDescriptor)
Within my draw loop I set depth stencil state:
renderCommandEncoder.setDepthStencilState(depthStencilState)
The resultant rendering
Description. This is a box mesh. Each box face uses a shader the paints a disk texture. The texture is transparent outside the body of the disk. The shader paints a red/white spiral texture on front-facings quads and a blue/black spiral texture on back-facing quads. The box sits in front of a camera aligned quad textured with a mobil image.
Notice how one of the textures paints over the rear back-facing quad with the background texture color. Notice also that the rear-most back-facing quad is not drawn at all.
Actually it is not possible to achieve the effect I am after. I basically want to do a simple composite - Porter/Duff - here but that is order dependent. Order cannot be guaranteed here so I am basically hosed.

Cocos2d - lunar eclipse effect on iPhone

i have a question about achieving an effect like on a lunar eclipse. The effect should look like in the first seconds of this gif. So just like a black shadow which goes over the circle. The ideal situation would be a function where i can passed a parameter in percentage to get this amount as a shadow on the circle:
The problem which i am facing is that my background is an gradient. So it's not possible to have a black circle which moves over the moon to get the effect.
I tried something with CCClippingNode but it looks not nice. Furthermore the clip on the edges was always a bit pixelated.
I thought about using something like a GLSL Shader to achieve the effect but i am not so familiar with GLSL and i can't find an example.
The effect is for an app game developed for an iphone. I use the cocos2d framework in version 3 (the current one).
Has somebody an idea how to get this effect? An idea where i can start to search?
Thank you in advance
The physics behind is simple you change the light shining on the moon. So
I would create a 1D gradient texture representing the lighting conditions
compute each rendered pixel of moon
you obviously have the 2D texture of moon. So you now need to obtain the position of each pixel inside the 1D lighting texture. So if moon is fully visible you are in sunlight. When partially eclipsed then you are in the umbra region. And finaly while total eclipse you are in penumbra region. so just compute the middle point's of the moon position. And for the rest use relative position in the moons motion direction.
So now just multiply the Moon surface with the lighting texture and render the output.
when working you can add the curvature correction
Now you got linerly cutted Moon phases but the real phases are curved as the lighting conditions differs also with radial distance from motion direction and moons center. To fix this you can do
convert the lighting to 2D texture
or shift the texture coordinate by some curvature dependent on the radial distance

xna drawprimitives: flip face normal

I'm drawing triangles and they're invisible from the view they should be visible, so how can I flip the direction?
Thanks
Invert the vertex order in the vertex or index buffer. Or change the backface culling settings. E.g. set the CullMode of the RasterizerState to CullMode.None.
Additionally, make sure that there are no problems with lighting that make your triangles black / invisible.

OpenGL point sprites with depth testing - a blending issue?

I am rendering point sprites (using OpenGL ES 2.0 on iOS) as a user's drawing strokes. I am storing these points in vertex buffer objects such that I need to perform depth testing in order for the sprites to appear in the correct order when they're submitted for drawing.
I'm seeing an odd effect when rendering these drawing strokes, as shown by the following screenshot:
Note the background-coloured 'border' around the edge of the blue stroke, where it is drawn over the green. The user drew the blue stroke after the green stroke, but when the VBOs are redrawn the blue stroke gets drawn first. When it comes to draw the green stroke, depth testing kicks in and sees that it should be behind the blue stroke, and so does this, with some success. It appears to me to be some kind of blending issue, or to do with incorrectly calculating the colour in the fragment shader? The edges of all strokes should be transparent, however it appears that the fragment shader combines it with the background texture when processing those fragments.
In my app I have created a depth renderbuffer and called glEnable(GL_DEPTH_TEST) using glDepthFunc(GL_LEQUAL). I have experimented with glDepthMask() to no avail. Blending is set to glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA), and the point sprite colour uses premultiplied alpha values. The drawing routine is very simple:
Bind render-to-texture FBO.
Draw background texture.
Draw point sprites (from a number of VBOs).
Draw this FBO's texture to the main framebuffer.
Present the main framebuffer.
EDIT
Here is some code from the drawing routine.
Setup state prior to drawing:
glDisable(GL_DITHER);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
Drawing routine:
[drawingView setFramebuffer:drawingView.scratchFramebuffer andClear:YES];
glUseProgram(programs[PROGRAM_TEXTURE]);
[self drawTexture:[self textureForBackgroundType:self.backgroundType]];
glUseProgram(programs[PROGRAM_POINT_SPRITE]);
// ...
// Draw all VBOs containing point sprite data
// ...
[drawingView setFramebuffer:drawingView.defaultFramebuffer andClear:YES];
glUseProgram(programs[PROGRAM_TEXTURE]);
[self drawTexture:drawingView.scratchTexture];
[drawingView presentFramebuffer:drawingView.defaultFramebuffer];
Thanks for any help.
If you want to draw non opaque geometries you have to z-sort them from back to front. This has been the only way to get a proper blending for many years. These days there are some algorithms for order independent transparency like Dual Depth Peeling but they are not applicable to iOS.

Resources