Tuesday, December 30, 2008

Visibility System And Shadow Casters

hi, last days i'v been working on my visibility system, rendering system and redesign few things related to them, also fix some low performance issues in big levels.
so in order to attack those issues i stared so see what could be optimized, one thing was the pvs data set which was basically a list of visible objects created from specific view point.
this pvs is needed for both camera and lights, also mirror materials needs to generate this set for the mirror generation pass.
those list was filled in few places but the thing is that we could do alot of the work in load time and achive better performance and still get the same thing.
so instead of keeping list of scene objects which could be changed doring the game (for example: another bot got in or out), i'm using a bit set for lights and camera pvs.
each entity update which areas they belong to, lights only update thier bit set when they move/change.
when i want to render the scene, i only need to check camera pvs bit set and see which areas are visible. to know which entity is visible is just a matter of checking the right bits in camera bit set.
in lighting pass we need to know which areas the current light influenced, so to get this info we need to do an AND bit operator between current light bit set and camera bit set, the result is the areas the light can influence and the camera can see.
the same thing is done for shadows generation, that using the same light bit set pvs with an exception.
when we are generating shadows we still need to consider shadows that comes from unvisible objects, object that is not visible still can cast visible shadow!
to solve this issue, we should check if the shadow volume of that object is intersecting our view frustum, if so it means this object needs to be rendered into the shadow map even if its not visible!.
if you dont handle those object you will get wrong shadows.
for example: if you have an open space scene with sun as the only light source and simple cave built from floor, ceiling and walls. when you enter the cave and look down (ceiling is not visible!) you still want to see the shadow of the ceiling.
here is screenshots from medium scene with unvisible shadow caster

shadows off

shadows generating from unvisible ceiling of this hallway

Sunday, December 14, 2008

Portals

hi, this time i had to recreate my portals visibility system, why? well i had some nasty bug that pop out when doing my pvs (possible visibility set) on complicated levels with lots of portals crossing each other.
i will try to explain the problem so when you see one you could attack it :)
little info about portals for some of you who don't familiar with it.
portals is related to visibility system because they help to cull scene areas, how?
think for a moment on a door that connecting two rooms room A and room B, if you stand in room A and looking through the door you only can a portion of room B.
now if you doesn't look through the door, you probably wont see room B (if you cant see the door, you cant see the room/s it leads to)
so portals basically hand placed (can be places automatically) in few places (not just corridors) as convex polygons (usually quads).
now, when you want to know which areas are visible, you start from camera area and check which portals inside this area, for each portal you clip your current frustum planes (the camera planes) against the portal and check again with the new clipped planes as the new frustum (yes its recursive function) and so on and on for each portal until there is nothing to see/visit.
now each portal you enter lead you to a new area so you flag this area so you know it is visible.
after you quit this function you end up with a list of areas that are potentially visible from camera area. this is the basic idea but few trick here and there could do this faster!
now that you know whats portals, i try to explain why i think recursive function for portals visibility are not so good in complicating levels with lots of portals!
the thing is that every portal you pass, the current frustum get clipped and pass for the next check, for every area you visit you also flag it so you wont check it again (this also helps to break the recursion, if not you can get stack overflow) because other portals can also leads to it.
because of this you can have few routes (in the recursion tree) that can lead to the same area! but not all of them will result in a visible area at the end! this is because we flag all the visited areas so the other routes that start like the first one but ends different (in terms of areas) wont even ends! meaning the area at the end of their route wont even visit because the first ones was flagged as visited - resulting in a none visible area that needs to be visible!!
i hope you didn't get lost in this long explanation and get the idea, so here is my solution to this problem:
the way i solve it is to look at the problem as a tree where the camera eye placed at the root, each portal is node, each branch is an area. (this is just how it help me to solve the problem).
i scan this tree by levels!, this way the areas are visited in a sorted order relative to eye pos (the root) and all the routes advance one step at a time and not allowing one route to get to the end (leaf) and others stay at the beginning.
here is few screenshots that shows portals in action:

visible portals in green, none visible in red

visible portals in green, none visible in red
yellow lines are current frustum planes
NOTE: portals are clipped against current frustum thats why part of the portal is red and the other part is green

Wednesday, December 3, 2008

Gamma Correction

hi, after reading the article "the importance of being linear" in gpu gems 3, i decided that its a good thing to add gamma correction into my engine.
by setting the right gamma value everything will look more real and the colors get the right felling.
there is few tecniques to do that, i decided to do it as a post process on the final pixel color by applying the function:
gammaCorrectedColor = pow(finalColor, 1/gammaValue)
as a bonus we can now optimize light interaction because the light bounds doesn't need to be big in order to make the effected area more clear and bright.
also, its a good idea to make the gamma value controllable so every player could set it as needed, i'm using the console to change it.
here is a screenshot of the effect:

without gamma correction

with gamma correction