Hard Light Productions Forums

Modding, Mission Design, and Coding => FS2 Open Coding - The Source Code Project (SCP) => Topic started by: newman on November 15, 2010, 04:33:02 am

Title: Transparency in the engine
Post by: newman on November 15, 2010, 04:33:02 am
Hi all, I've recently spoken with The_E on irc about this issue and he suggested I post it here.
Before I begin, I'd just like to say that I'm an artist for Diaspora, and know very little about coding - so I have no idea whether or not what I'm suggesting is even possible, or how complicated it is. I thought I'd throw the issue out there and see if a better way of handling transparency can be found. Warning: lots of text ahead :)
 
As the thread title suggests, this is about transparency and the way engine handles it in the game. Right now, the alpha channel on the diffuse (color) map is used to determine transparency: black is transparent, white is opaque, and say 50% gray is 50% transparent. That part's fine. The complication comes from the fact that anything you want to see through the transparent object on a ship needs to be set up in the pof as below that object in hierarchy - the transparent object itself (the one that has the alpha map applied) needs to be higher in the hierarchy than the stuff you see through it. This in itself isn't a problem on simpler setups where you only have, say, a cockpit canopy on a fighter - you set up your canopy is as detail0 and slave everything to that, problem solved (FUBAR's been testing this stuff and he actually tells me that your transparent object has to be detail0 to work properly - so you can't have say, the fighter main hull as detail0, then slaved to that the canopy, and below the canopy the cockpit interior - and this causes complications in some examples).
The problems begin on ships that need more, larger surfaces transparent or semi transparent. Since I'm a Diaspora member I'll be using ships from the BSG universe as an example of why this way of doing things causes us problems.

Let's begin with the ringship:
(http://i51.tinypic.com/2woli1d.jpg)

Once this one is built for Diaspora, we definitely want to have the interior of the ring actually modeled out, with transparent glass over it. Ideally, we'll also want to be able to see the inside of the glass as well from certain angles (right now means having two glass objects, one with polygon normals pointing outwards and the other with poly normals pointing inwards).
The problems on this one will arise mainly from the fact that the glass object(s) need to be detail-0, but they also need to spin (the entire ring section including the arms and parts of the main hull rotates). You can rotate sub-objects, but not sure about detail-0..
If the glass can work with not being detail-0 you can still get issues of not seeing some hull parts through it from certain angles (say, you park your fighter so you should be able to see the bridge through the glass, or the connecting arms). We did do some testing on this and the problem is more complex than one might imagine; even if everything is set up seemingly correctly, there's always some ship part you can't see through the glass.

Here's another example:

(http://i55.tinypic.com/1126dtk.jpg)

Not exactly the most accurate depiction of the botanical cruiser, but it'll do. The problems are, of course, the domes. With a single dome, it's not a problem at all. Set up the dome as detail0 and everything else below that. With multiple ones, you have a problem if you want to see other domes through other domes. Say you park you fighter in front of it, you should be able to see several domes right through each other. In parts where the transparent parts intersect you should see less and less transparent surfaces, the more glass objects you're looking through at once.

And finally, on to the actual request part:
We've been thinking of ways to get around these issues, but the best thing would be if the need for hierarchy for transparent objects was eliminated. I'm not sure if it's even possible, but if it is the best thing would be that everything that happens to be behind a transparent object (relative to the player) is visible through that object, no matter if it's another ship part which may or may not be higher in hierarchy, or another ship for that matter.

I hope you lot can make sense of what I wrote. If anybody would like to tackle this, I'd of course be willing to do any test models or textures to test it on - while this would be extremely useful to Diaspora, I'm sure there are other projects which could benefit from this as well. If it can't be done, well, thanks for listening and all your great work so far :)
Title: Re: Transparency in the engine
Post by: DaBrain on November 15, 2010, 05:14:18 am
I see three issues here:

1. The lack of support for two-sided materials. This one is probably the easiest to fix. Maybe The E can allow that in his material file.

2. Rendering order/sorting issues. Very hard to fix. Sorting issues are a common problem. You can even create content that is impossible to sort correctly.
There is a DX11 feature that allows rendering order independant transparency, but I doubt FSO will support that.
Also, I've never seen it being used by any game yet. I imagine it might be very costly.

http://www.yakiimo3d.com/2010/07/19/dx11-order-independent-transparency/
http://www.youtube.com/watch?v=zANEUhyT2y8


3. Hierachy... well it can be painful to set up, but at least you have the complete control. It would be frustrating if the engine rendered your model wrong and you had no way to fix it.
Title: Re: Transparency in the engine
Post by: Nuke on November 15, 2010, 05:42:19 am
this kinda thing is one of those big annoyances ive always had with the engine. it has a really hard time with transparency. subobjects all get rendered first, so if they are in front of detail 0 they will be covered up. also i think rendering order of subobjects is somewhat fixed by the submodel number, with no depth sorting at all, so transparency between subobjects is not considered and whatever gets rendered last is usually what you see. since this game engine was never really meant to deal with transparency it is somewhat fundamentally flawed when you try to implement it. there are methods to make small parts of of ships transparent, but it takes some rather complicated modding techniques. i dont think there is really any way around it, its something that would have to be handled properly in the code.
Title: Re: Transparency in the engine
Post by: newman on November 15, 2010, 06:47:05 am
Well, like I said, I have no idea if this is fixable at all, but at least this way I know I've tried :) I would encourage a brainstorming session on this here if there's more than a snowball's chance in hell of the transparency code getting improved, though. I wish I knew more about code, this way all I can do is ask and hope someone has an idea.
Title: Re: Transparency in the engine
Post by: Sushi on November 15, 2010, 09:12:53 am
Yeah, trying to deal with multiple overlapping transparent textures is a "hard problem" in 3d rendering in general, so it's not surprising that FSO chokes on it.
Title: Re: Transparency in the engine
Post by: DaBrain on November 15, 2010, 11:45:05 am
FS2 only used additive rendering for textures back then. There is no need to sort additive effects. No matter in which order you render them, the result will always be the same.


Alpha blended materials made the sorting more apparent. I think taylor already improved the sorting a lot.
Title: Re: Transparency in the engine
Post by: FUBAR-BDHR on November 15, 2010, 02:03:02 pm
There is another issue Newman forgot to mention.  While other objects can be seen through a transparency they can't be if they are inside a transparency.  Say you took and docked something inside of one of those domes.  It can't be seen. 

As for the issue with not having the transparency on detailx what happens there is you open a hole through the entire ship.  You can see the star field on the other side.  This happens even if there is a solid object behind the transparency with normals facing the direction you are looking from. 

One other note is that a lot of these items show up fine in PCS2 but not in game. 
Title: Re: Transparency in the engine
Post by: Galemp on November 15, 2010, 02:15:50 pm
I ran into this issue with the high-poly PVF Anubis, which has two glass cockpits. Fortunately the Blender-to-DAE-to-POF workflow lets you create transparent polies on a detached subobject, which then gets merged into the main geometry in the proper rendering order. You might want to make some test POFs (the botanical cruiser is an excellent example) to try it out.
Title: Re: Transparency in the engine
Post by: Dragon on November 15, 2010, 02:29:58 pm
Is that possible that while we're at it, somebody could look into the problem with cockpit glass being visible from inside the cockpit?
This bug is a real problem for anybody who wants to use cockpit view.
Title: Re: Transparency in the engine
Post by: The E on November 15, 2010, 02:32:23 pm
Dragon, that's a model issue more than anything. Namely, that the cockpit glass is apparently double sided. The current shaders only render polygons facing your way.
Title: Re: Transparency in the engine
Post by: Dragon on November 15, 2010, 03:27:23 pm
I have to check again, but I'm sure it occured on Mediavps models like Herc II, which worked fine in 3.6.9 (this started to appear in 3.6.10, the first notable case was Steve-O's fighters suddenly getting inside of their opaque glass rendered).
Title: Re: Transparency in the engine
Post by: The E on November 15, 2010, 03:31:11 pm
It's still a model issue. Only the front sides of polygons are rendered. If you are seeing it, it means it's facing your way.
Title: Re: Transparency in the engine
Post by: Nuke on November 15, 2010, 03:42:04 pm
i kind of have an issue on one ship where the cockpit glass that is meant to be visible from the outside only, can be seen from the cockpit model. but only until you fire your weapons for abit, then it goes away. though i think this has been fixed in recent builds.
Title: Re: Transparency in the engine
Post by: newman on November 15, 2010, 05:02:48 pm
I ran into this issue with the high-poly PVF Anubis, which has two glass cockpits. Fortunately the Blender-to-DAE-to-POF workflow lets you create transparent polies on a detached subobject, which then gets merged into the main geometry in the proper rendering order. You might want to make some test POFs (the botanical cruiser is an excellent example) to try it out.

Could you expand a bit on your method of doing this? Are you actually saying you can create polygons that will always be transparent (well, semi transparent) independently of the texture applied?
At any rate, what you're suggesting sounds interesting, I'd love to hear more specifics :)
Title: Re: Transparency in the engine
Post by: Galemp on November 15, 2010, 05:13:11 pm
Could you expand a bit on your method of doing this? Are you actually saying you can create polygons that will always be transparent (well, semi transparent) independently of the texture applied?

You still need a texture with transparency, of course; this method simply builds the mesh in such a way that the drawing order is arranged correctly. The relevant step is on this Wiki page (http://www.hard-light.net/wiki/index.php/Blender_to_POF_Conversions#Nameplates.2FCockpit_Glass:) but I'll quote:

Quote
Transparent objects are handled quite badly by FSO at the time of writing, and so the following technique is basically a hack to get around that.

If you have anything that requires transparency as a part of the hull or any subobject, you must:

   1. Select all faces that will need to be transparent. (For cockpits this means all the polies that would be the glass, and for nameplates it means just the floating nameplate rectangle polies)
   2. Detach these faces from the mesh they're a part of so they form their own mesh.
   3. Assign them the texture if necessary. (For cockpit glass just give it any old image called 'glass' and for nameplates give it any old image called 'nameplate'. Both these textures exist in the 3.6.10 MediaVPs and so will be used on your model with no further worry about it. If you need some other form of transparency you'll have to make your own transparent texture and use that.)
   4. Name the object in the form of '<Object the transparent polies came from>-trans'. So for example, the glass or nameplate would be called 'detail0-trans', because they were pulled off the main hull.
   5. Parent the transparent polies object to whatever object they originally came from. (Select the transparent object, then the parent object and press Ctrl+P->'Make Parent' ) For glass or a nameplate this would of course be detail0.

What basically happens is that PCS2 will re-attach the transparent polies to their parent object last in the list, which lets Freespace draw them last of all and so correctly transparent.

I haven't tried anything as complex as the botanical cruiser but for two glass domes it's worked perfectly.
Title: Re: Transparency in the engine
Post by: FUBAR-BDHR on November 15, 2010, 05:25:02 pm
I've tried it and it doesn't work for sub objects just for detail0.  Using it on subobjects results in the see clear through the ship issue I described above. 
Title: Re: Transparency in the engine
Post by: newman on November 15, 2010, 05:49:40 pm
Aw, shucks. Knew about that. Thought you had a magical solution to the problem. Still, thanks :)
Title: Re: Transparency in the engine
Post by: Spicious on November 15, 2010, 06:00:54 pm
That only applies with respect polygon order within an individual subobject. Getting around this would require moving the opaque geometry into a subobject.

If you need to be able to view a set of transparent things in multiple orderings, you're doomed.
Title: Re: Transparency in the engine
Post by: Galemp on November 16, 2010, 01:05:19 am
If you need to be able to view a set of transparent things in multiple orderings, you're domed.

Fixed that for you...
Title: Re: Transparency in the engine
Post by: Sushi on November 16, 2010, 09:13:18 am
If you need to be able to view a set of transparent things in multiple orderings, you're domed.

Fixed that for you...

 :lol:
Title: Re: Transparency in the engine
Post by: Vasudan Admiral on November 18, 2010, 07:55:31 pm
Umm, massive hack for just this particular case, but might you be able to make the glass polygons on the ring of that ship part of detail0, and then have all the opaque parts of the geometry (ring structure, window struts etc) as a rotating subobject? So the ring rotates but the glass stays in place?

You'd have to make sure the ring could not be destroyed mind you, or that would look really awkward. :p

As for the render sorting issue, it's even more complex than that! Assuming this is still the case in the engine, here's what can happen with transparency also, when the iceni is moved vertically from above to below the hatshepsut:
(http://i5.photobucket.com/albums/y184/VA--Twisted_Infinities/Misc/CloudProblem3.jpg)

(http://i5.photobucket.com/albums/y184/VA--Twisted_Infinities/Misc/CloudProblem2.jpg)

(http://i5.photobucket.com/albums/y184/VA--Twisted_Infinities/Misc/CloudProblem1.jpg)

As you can see, the second pic is basically an optical illusion, only made possible by the FS2 rendering engine. :)
(I know it's done in Fred here, but it happens the same way in-game)
Title: Re: Transparency in the engine
Post by: FUBAR-BDHR on November 18, 2010, 08:02:31 pm
The ring being detail0 hack has been though of but still has issues.  For one it doesn't work with inside and outside glass. So your hierarchy ends up like this:

Detail0 (outside glass)
->Inside glass
--->hull
----->rotation

Even with that there are parts that should be seen that aren't.  Also one day we will most likely need to blow out a section (it happens in the show) so yea the rotation really needs to be subsystems. 
Title: Re: Transparency in the engine
Post by: newman on November 19, 2010, 04:06:07 am
Even if we have to keep relying on sorting, making it so that transparency works even if transparent object isn't detail0 would be an improvement. Right now, it has to be detail0, and the way it should work to my understanding is, anything below it in hierarchy should be seen through it - which it isn't.
But ideally, we want to be able to have things like multiple domes with additive transparency when looking through all of them, meaning getting rid of depending on hierarchy in the pof.
Title: Re: Transparency in the engine
Post by: Nuke on November 19, 2010, 06:07:19 am
what if we take the main hull object, and replace all its textures with invisible, then to that model attach a copy as a submodel with textures intact. we would make this subsystem non-targetable, non-collidable and give it no hitpoints. you could also use the invisible model as a less complex collision mesh. now the transparency in those submodels are at the same level. if submodels are depth-sorted back to front, and transparent textures are at the bottom of the texture list. it should work. it would at least be worth a test. would be something like:

->hull (invisible textures with collide_invisible)
-->fakehull (textured, no_collide)
-->ring (transparent textures last)
Title: Re: Transparency in the engine
Post by: Angelus on November 19, 2010, 06:17:46 am
[daydream] if we only could manually set an override to render a subobject first on specific models only...[/daydream]
Title: Re: Transparency in the engine
Post by: Spicious on November 19, 2010, 08:52:21 am
Fiddling with submodel orderings won't help with the ring model. Looking through from the outside to the inside and back outside requires rendering the inside glass before the outside glass. But looking out from inside the ring into the ring elsewhere requires rendering the outside glass before the inside glass.
Title: Re: Transparency in the engine
Post by: Nuke on November 19, 2010, 09:14:25 am
a big transparent toroid has got to be one of the hardest things render correctly, especially when theres stuff in the middle of it. i have doubts that the idea expressed in my last post would work for that. but it might work for something like the agro ship.
Title: Re: Transparency in the engine
Post by: newman on November 26, 2010, 03:34:29 am
A bit of an update on this - I had an idea on how to make the botanical cruiser's multiple domes work, so I made a very quick pof to test it: we make the domes separate ships and dock them to the cruiser. Here's a test shot:

(http://i51.tinypic.com/2qq1f.jpg)

It actually works great. Which makes me wonder one thing - if it works well with separate ships, why can't it work on subsystems on a single one?
Title: Re: Transparency in the engine
Post by: Nuke on November 26, 2010, 04:58:44 am
because of the archaic way the engine sorts things?
Title: Re: Transparency in the engine
Post by: Spicious on November 26, 2010, 05:28:51 am
How thoroughly have you tested it?
Title: Re: Transparency in the engine
Post by: newman on November 26, 2010, 07:02:03 am
I just put a bunch of domes into fred, saved a mission, and ran it. Everything seemed fine. Guess I might try adding a few other ships and see if I can see them through all the domes (though if I see the domes through domes, which are other ships by themselves, I really should).
Title: Re: Transparency in the engine
Post by: Nuke on November 26, 2010, 09:06:59 am
if it turns out this works, maybe something along the lines of a $default cargo: tag is called for. it would have a child tags for +dockpoint: and +cargo: and any time that ship is created or placed in fred it would come with that cargo pre-installed. maybe also add a feature where the game treats it as a subsystem of the parent and puts local turrets and whatnot under the control of the parent ship. its not quite indended as a way to sneak around the transparency issues. but it would allow for stuff like modular turrets and other subsystems, also subsystems with transparency. of course the alternative is to support proper blending on subobjects.
Title: Re: Transparency in the engine
Post by: newman on November 26, 2010, 09:17:51 am
Sounds like a great idea to me. I can think of several instances where this would be extremely useful in Diaspora, pretty sure other projects would find plenty of uses for that too.
Title: Re: Transparency in the engine
Post by: swashmebuckle on November 26, 2010, 10:25:33 am
Yeah, that would be good for SWC on the freighters from the X-wing games that almost always are seen with their cargo containers.
Title: Re: Transparency in the engine
Post by: Topgun on November 26, 2010, 11:54:04 am
Why can't the engine render things in order of their z value?
Title: Re: Transparency in the engine
Post by: Iss Mneur on November 26, 2010, 12:07:13 pm
Why can't the engine render things in order of their z value?
IIRC, that is the problem, the engine doesn't deal with z value.  It just enumerate the list of objects and renders anything that is "visible".

As for why multiple ships work. Because every ship is a different object, its rendering call gets a different position, thus the engine just pushed the problem to the graphics card.  Because the graphics card is told the object's position in space, the graphics card then uses it own z buffering and ordering (calculated based on the position of the object) to figure out the transparency.
Title: Re: Transparency in the engine
Post by: newman on November 26, 2010, 12:18:42 pm
Don't suppose that info could be used to make it work on subsytems, then? Anyway, bottom line, it works.
I think Nuke's suggestion has a lot of merit. Hopefully one of the SCP wizards can make it happen..
Title: Re: Transparency in the engine
Post by: Sushi on November 26, 2010, 12:52:12 pm
Why can't the engine render things in order of their z value?
IIRC, that is the problem, the engine doesn't deal with z value.  It just enumerate the list of objects and renders anything that is "visible".

As for why multiple ships work. Because every ship is a different object, its rendering call gets a different position, thus the engine just pushed the problem to the graphics card.  Because the graphics card is told the object's position in space, the graphics card then uses it own z buffering and ordering (calculated based on the position of the object) to figure out the transparency.

Sounds like it's probably possible to update the renderer so that this works for subobjects, then.
Title: Re: Transparency in the engine
Post by: Iss Mneur on November 26, 2010, 01:00:38 pm
Sounds like it's probably possible to update the renderer so that this works for subobjects, then.

It probably is, but I don't know the details to be able to say definitively.  Nor could I say what the potential problems could be.
Title: Re: Transparency in the engine
Post by: DaBrain on November 26, 2010, 04:21:28 pm
Well... I consider the cargo trick a hack or work-around.

It's neither a clean nor an efficient solution.


As long as it is the only solution, I won't discourage anybody from using it though.
Title: Re: Transparency in the engine
Post by: Nuke on November 26, 2010, 04:36:09 pm
i think the submodels get rendered on a different pass than the hull model. so it does all the rendering for the subsystems in who knows what order, then it does the hull (or maybe the hull comes first). what it should do is sort all the submodels in reverse z order, rendering the hull at its place in line and not after (or before) the submodels. at least thats how i understand the problem.
Title: Re: Transparency in the engine
Post by: Galemp on November 26, 2010, 11:30:25 pm
Trick, hack, or workaround, it's still a brilliant solution and an excellent use of lateral thinking. Great job!
Title: Re: Transparency in the engine
Post by: ION3 on December 06, 2010, 04:46:36 pm
(http://i51.tinypic.com/2e1bpqa.jpg)

In this example the Drawing order would prapably be: Dome 3 -> Ship -> Dome 2 -> Dome 1   (assuming it's based on the distance of the object centers to the observer) (actually more likely to be based on the distance to an imaginary plane through the observer,  at an angle of 90 degrees to the direction the player is faced) (could also be based on bounding spheres?)

That means that the ship won't get drawn through dome 3, so the ship itself has to be split up into multiple sections aswell. So that the center of the ship section below dome three is further away than the center of dome three.
Title: Re: Transparency in the engine
Post by: Nuke on December 06, 2010, 05:14:39 pm
i think what needs to be done is while building the list of polygons to throw at gl. the lists for all the submodels are generated first and sent through, then the list of the polies in the hull model are sent. what i think needs to be done is the polygon list must be created for each, then the lists must be merged into a single list, and possibly z-sorted by polygon center (this may or may not be necessary), before being sent to the video card for rendering. z-sorting sorting submodels may work in some situations and would be faster, but there would be situations where it would not render correctly (for example situations where you have a trasparent subobject near the center of the ship, and parts of the hull exist both in front of and behind it with reguards to a specific view origin). mind you my understanding of opengl is very basic, and about all i know how to do is render a bunch of polies in wireframe.
Title: Re: Transparency in the engine
Post by: Pottuvoi on December 07, 2010, 06:53:57 am
Sadly this is also something every developer has to endure as current GPUs still cannot automagically render transparencies correctly. (there were some GPUs during old days that did this just fine...)
DX11 or Shader Model 5 finally brought some nice features which make per-pixel sorting of transparent samples/surfaces feasible, but I doubt that freespace will have proper support for a while.
Title: Re: Transparency in the engine
Post by: newman on December 07, 2010, 08:21:08 am
Well, using domes as separate ships that are docked to the cruiser's hull is a workaround, but it does open other cans of worms. It would be best if it would function as subsystems, which it currently doesn't.
Title: Re: Transparency in the engine
Post by: Tomo on December 07, 2010, 12:46:59 pm
It sounds like the ship drawing order is backwards at the moment - drawing subobjects first, then finally detail0.

If instead it drew Detail0 first, then the subobjects from furthest to closest (sorted by origin), that should work.

The limitation of this scheme is that Detail0 cannot contain any transparent geometry, but any and all subobjects can.
- Basically, you can always see the detail0, except where obscured by a subobject.

In ION3's drawing, this would mean SHIP > Dome 3 > Dome 2 > Dome 1

Thinking about it further, this would also require all glass to be double-sided as otherwise you'd lose the back of each dome.

(Edit)
... aaand I just realised why it's the way around it is.
Subobjects first means that you never have to check whether a subobject should be visible, as the 'turret' behind the ship gets obscured when the ship is drawn.

So to do this we'd need one heck of a lot more checking of the Z.

Likely a more fruitful effort would be working out how to pass the entire geometry to the GPU in one go, rather than several passes, so the GPU can do the z-sort.
Title: Re: Transparency in the engine
Post by: Nuke on December 07, 2010, 02:56:56 pm
z sorting sob-objects wouldn't cut it. you would need to create a polygon list for the whole model, not just individual submodels as its done now. then you would need to z-sort the list by polygon origin.