So i'm trying to fade off a mesh but setting it's alpha sets the alpha of each constituting triangle separately, thus overlapping parts fade differently from non-overlapping parts. this is not good for me, i'd prefer uniform fade off.
see attached figure for full alpha, and faded off alpha, the intersection of the two strokes is more opaque, that's what i don't want.
is there any solution? rendering to rendertarget and then setting alpha for this would work but i'm working with thousands of meshes, and so this would slow down the app too much. i was hoping that maybe you can think of some other solution, using shaders perhaps?
thanks for your ideas.
Comments
Did you expected this fx ? https://www.dropbox.com/s/ev989ha9pdw5lec/mesh.avi?dl=0
i don't understand completely your comment.
coincidentally i have also an app called fragmenter that works similarly as your video shows, see my signature for more info about it if you are interested.
and indeed my question is related to some features related to my drawing app.
but what i want to achieve is something else:
given a mesh that is. e.g. the union of two triangles that overlap. i want to set opacity 50% for this mesh so that all pixels become 50% transparent. the problem is that setting setAlpha(50) will make each triangle 50% transparent and at the end the overlapping part will be less transparent, just like on the 2nd picture i attached to my first comment.
Fragmenter - animated loop machine and IKONOMIKON - the memory game
Fragmenter - animated loop machine and IKONOMIKON - the memory game
Second approach is to draw shapes on RenderTarget and use setAlpha
A) As @Yan suggested: render your mesh without alpha to a rendertarget than render that render target with alpha.
Similar to A, draw your mesh to stencil, then draw stencil to screen. Unfortunately stencil isn't exposed to lua
C) Maybe we can do it in a single pass with stencil test and render at the same time
D) Use Z-buffer and draw your mesh in 'font to back' order: first triangle is drawn in front and last in background
I think C would be the best technique, do you reckon we should add lua bindings for OpenGL stencil management ?
With stencil you could theoretically draw as usual, without a shader, and just let OpenGL keep or discard your fragment based on stencil content, while updating the stencil at the same time.
@Yan, please let us know how you would do it with a shader.
meanwhile and in case the shader way won't work, @hgy29,
A) for 10000 rendertargets will surely be too slow,
B,C) sounds good, i'm not familiar with opengl stencil, so i's not clear what and how it does (having a look at a wikipedia page i was not instantly wiser), but if it can do this, then i'm for it, surely
D) i again don't understand this completely, as giving different depths for the triangles would still make this undesired effect when they become transparent, so you probably mean something more tricky.
in any case what to do to achieve a solution like C)?
Fragmenter - animated loop machine and IKONOMIKON - the memory game
So if you afraid for 10000 rendertargets will surely be too slow you can have a one big render - call this main and draw a small renders with applied alpha tro this main canvas
"you can have a one big render - call this main and draw a small renders with applied alpha tro this main canvas "
that will have exactly the same problem with intersecting triangles i think as i currently have.
Fragmenter - animated loop machine and IKONOMIKON - the memory game
D option is in fact quite similar, but tries to use depth test instead of stencil test. When you draw something in 3D, you typically don't want objects in the background to be displayed in front of those in foreground. To achieve this, OpenGL tracks Z value of fragments drawn and discard fragments which are behind something already drawn.
If you can add a Z value to your mesh triangles (value shouldn't matter since you use orthographic projection) and arrange for faces to be drawn from front to back, then OpenGL will discard pixels drawn twice since they would necessarily be behind the first drawn pixels.
"If you can add a Z value to your mesh triangles (value shouldn't matter since you use orthographic projection) and arrange for faces to be drawn from front to back, then OpenGL will discard pixels drawn twice since they would necessarily be behind the first drawn pixels."
-are you sure? even if the top one has 50% alpha, the lower triangles will be discarded?
-if for both solutions gideros needs to be updated too than i guess the stencil solution is cleaner (as if my mesh has 1000 triangles, then i need to set different z-value for each of them, which seems to be sort of untidy solution), moreover i'm experimenting with 3d polygonal brushes, which would not work together with the depth-check solution
Fragmenter - animated loop machine and IKONOMIKON - the memory game
And yes, I will expose stencil ops to lua, in a future version, probably with Sprite object. However using depth test is possible with current gideros with 3D meshes, but I agree: this is hackish.
this limitation of opengl transparency turns out to be helpful, if i get time to do it, i will test the depth solution, until there are stencils. what i'm curious about though that if there is no z-value, then why transparency works fine for '2d sprites', is it done with different algorithms? or opengl recognizes if two objects are in the same plane and then alpha is done as expected?
also, about the stencil solution, will be there a way to make gideros/opengl process the triangles backwards?
because if not, then i need to add the triangles in reverse order to the mesh, which means that whenever user draws another segment of triangles, then i need to rewrite the whole indexarray to put the new triangles at the beginning - this is not too efficient.
Fragmenter - animated loop machine and IKONOMIKON - the memory game
Fragmenter - animated loop machine and IKONOMIKON - the memory game
the question is how else to do this or perhaps how else i can do the smoothing so that it works with stencil.
Fragmenter - animated loop machine and IKONOMIKON - the memory game
actually i realised that it does happen occasionally that the user draws so much on a frame that i reach the vertexarray limit and i need to divide the drawing into more meshes. in this case stencil etc nothing seems to work, am i right?
so at the end i need to start to experiment with rendering to rendertargets, ideally i can reuse the same rendertarget as @Yan proposed, so at least memory-wise it won't be a problem, performance-wise i have worries, but i will need to test.
Fragmenter - animated loop machine and IKONOMIKON - the memory game
Aside from this, splitting your shape in several meshes wouldn't have been an issue, since stencil tests can be done on a group of sprites. I added stencil control in gideros anyway, it may be handy for some other case.
Likes: antix, keszegh
Fragmenter - animated loop machine and IKONOMIKON - the memory game
Fragmenter - animated loop machine and IKONOMIKON - the memory game
Likes: keszegh, SinisterSoft
Fragmenter - animated loop machine and IKONOMIKON - the memory game
well, i guess not, reading back my message about "actually i realised that it does happen occasionally that the user draws so much on a frame that i reach the vertexarray limit and i need to divide the drawing into more meshes. in this case stencil etc nothing seems to work, am i right? "
Fragmenter - animated loop machine and IKONOMIKON - the memory game
Fragmenter - animated loop machine and IKONOMIKON - the memory game
in any case, having a pixel not be able to be written after it is written once won't work for me.
just to repeat: i want to achieve the same as drawing a complicated thing and then rendering it to a rendertarget and decreasing the alpha of the result (and putting only this on screen). so there is a way to do it using rendertarget, just if doing the same is possible with stencil then i guess that would have considerably less resource penalty.
Fragmenter - animated loop machine and IKONOMIKON - the memory game
Fragmenter - animated loop machine and IKONOMIKON - the memory game