[SOLVED] Render two translucent textures

Started by manji, November 16, 2010, 12:17:12

Previous topic - Next topic

manji

I want to render two translucent textures that intersect each other, exactly like this picture http://tiny.cc/xnqus. The transparent parts of each texture let everything behind them be visible, no matter the rendering order of the two textures. Any thoughts? Thanks.
toyWars game blog: http://toywars.wordpress.com/

broumbroum

Use some texture loader to convert a .png to the rgba texture format. You should find it on this forum. Heard of Slick util, I also provide JXA sf3texture on my own.

manji

Thnx for the quick reply broumbroum. I do use RGBA, I use this class http://www.cokeandcode.com/info/spaceinvaders104/org/newdawn/spaceinvaders/lwjgl/TextureLoader.java.
I am a noob, but I think the problem lies in the logic. When rendering transparent textures, you should do it from back to front. But in this case, there is not back and front....  ???
toyWars game blog: http://toywars.wordpress.com/

ryanm

If the textures are bitmask-transparent (every pixel is alpha 0 or 1, no inbetween values) you'll have no troubles, just make sure you have an alpha test enabled to reject the transparent fragments.

If you have varying alpha you have to be more careful. Split each quad in two so you've got 4 non-intersecting quads and render them in back-to-front order.

If this is the only thing you're drawing and the two quads' textures are pretty similar, you might be able to get away without the splitting and just disable the depth test.

manji

Very helpful ryanm. I have varying alpha (translucent textures), so I will go for the 2nd or 3rd solution. My textures are the same and rather simple. I had tried disabling depth testing, but is messes a little with the looks of my game. Splitting also makes sense. Thank you!
toyWars game blog: http://toywars.wordpress.com/

broumbroum

Yeah it should be alpha testing with depth test enabled, then splitting isnt required. My opinion is that trees look better by applying a real 3D volume, similar to a mushroom. Trees with sample of quads is old styling, isnt It? 

manji

I am not going for trees, I am trying to render a laser beam!  8)
I think if I solve this problem it will look nice, I am still working on it. I believe alpha testing will not work, because the texture has very smooth coloring on the edges. Disabling depth testing also is difficult to implement, because it messes with other blending stuff I have in the game. I am trying right now to implement the splitting way... I will update the thread if any progress takes place. Thnx!
toyWars game blog: http://toywars.wordpress.com/

manji

I did it! I used the splitting technique, to cut each texture in two. My game is in 3rd person, so I used two vectors toward the end of the beam, one for the direction of the character emitting the laser, and one for the position of the camera according to the beam's end. Comparing these vectors, I can understand which two rectangular textures I am facing, and render the other tow ones first. Maybe not the best or efficient solution, but the effect seems cool! Thank you guys, this forum is awesome! (I'm excited right now  ;D)
toyWars game blog: http://toywars.wordpress.com/

Rene

You might want to disable depth writing during the translucent stage, this will be slightly faster.

Also, may I suggest you try to render your laser using SRC_ALPHA, ONE as blend function? This usually looks better than SRC_ALPHA, ONE_MINUS_SRC_ALPHA for laser-like objects.
When I am king, they shall not have bread and shelter only, but also teachings out of books, for a full belly is little worth where the mind is starved - Mark Twain

manji

I do already use SRC_ALPHA, ONE, which looks great indeed  ;)
Disabling depth testing is problem, I cannot get blending right If i do it. The beam is emitted in front my character, so it must be rendered before he is. But I want objects in my game to become translucent when the camera gets behind them. I must have confused you. There seems to be not a right order to do this.  From back to front, it cannot be character->object->beam because the beam will be rendered on the character when facing front, neither can it be object->character->beam because then the beam will always be visible, even when going it goes objects, and also the character cannot be seen when other object behind him become translucent. Sorry for sucking at explaining the situation.
This is a picture of my character behind an object (wall) http://imgur.com/e2jzo.jpg
toyWars game blog: http://toywars.wordpress.com/

Rene

I understand what you mean, but it's possible to disable depth writing without disabling depth testing. To do so, call glDepthMask() with false as argument. If depth testing is enabled it will still work with the values already in the depth buffer. The advantages of doing this is that it improves performance if you're drawing a large amount of translucent objects (particle systems), and it will also make some artifacts less obvious or remove them altogether.

The second advantage may not be immediately clear. If so, consider a U-shaped, translucent object. If the object is drawn with a single draw call, there will be a situation where the polygons of nearest 'leg' will be drawn before the polygons of the other leg. If depth writing is still enabled, the second leg won't shop up. If you disable depth writing both legs will be visible. Depending on the material of the object the result may not be entirely correct, but it's usually better than the alternative.
When I am king, they shall not have bread and shelter only, but also teachings out of books, for a full belly is little worth where the mind is starved - Mark Twain

manji

Rene, I understand now what you say. This seems to work fine and is faster. I searched a little about what glDepthMask() does, and I see that it makes sense.
a) Render everything opaque you want while writing to depth buffer
b) Disable depth writing and render translucent objects using only using the existing depth values (so if a translucent object is behind an already drawn opaque object, it will be discarded)
I knew there should be a way without doing all the math stuff.
One last thought though troubles me. Since you disable depth writing(b), do you need to render all the translucent objects from back to front? I think not, and my game seems fine if I do not.
toyWars game blog: http://toywars.wordpress.com/

Rene

Quote from: manji on November 17, 2010, 12:01:46
One last thought though troubles me. Since you disable depth writing(b), do you need to render all the translucent objects from back to front? I think not, and my game seems fine if I do not.

Yes, you still need to draw from bact to front. In some cases the result will be exactly the same, but usually not.

Say you have an object which is evenly translucent, and an object which is partially translucent with some opaque pixels in it's texture. From the current camera position, the second object is behind the first object. If the second object is rendered after the first object, the opaque parts will overwrite the color of the first object, which is not what you want.
When I am king, they shall not have bread and shelter only, but also teachings out of books, for a full belly is little worth where the mind is starved - Mark Twain

broumbroum

Here's my answer (thanx to the previous Manji's posts) :
To render a picture like this #*!¬@ tree LOL, I find it possible in 3 passes, with the help of the stencil buffer and test.

1. draw both translucent quads by disabling both depth and color buffer, but enable stencil buffer write and depth test. (quads won't be shown, but masked)
2. let depth buffer and color on and depth test off, draw both translucent quads, crossing each other as seen, but stencil testing must be on with (stencil passes).
2. disable stencil test, enable normal depth test and draw both quads again.

:D