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
-
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 :)
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
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).
-
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.
-
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.
-
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 :)
-
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:
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.
-
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.
-
Aw, shucks. Knew about that. Thought you had a magical solution to the problem. Still, thanks :)
-
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.
-
If you need to be able to view a set of transparent things in multiple orderings, you're domed.
Fixed that for you...
-
If you need to be able to view a set of transparent things in multiple orderings, you're domed.
Fixed that for you...
:lol:
-
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)
-
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.
-
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.
-
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)
-
[daydream] if we only could manually set an override to render a subobject first on specific models only...[/daydream]
-
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.
-
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.
-
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?
-
because of the archaic way the engine sorts things?
-
How thoroughly have you tested it?
-
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).
-
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.
-
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.
-
Yeah, that would be good for SWC on the freighters from the X-wing games that almost always are seen with their cargo containers.
-
Why can't the engine render things in order of their z value?
-
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.
-
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..
-
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.
-
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.
-
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.
-
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.
-
Trick, hack, or workaround, it's still a brilliant solution and an excellent use of lateral thinking. Great job!
-
(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.
-
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.
-
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.
-
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.
-
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.
-
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.