[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Written by Jorrit Tyberghein, [email protected]. Last updated 28 September 1998.
This section contains a number of ideas and stuff but it is mostly outdated.
Normally the portal approach lends itself very well for dynamic worlds. However, the big problem is lighting. Static lightmaps are very static (as you can imagine) and are difficult to scale and recompute. This severely restricts what you can do dynamically in general. You can also use stencil shadows in which case there is no recalculation needed but the problem with stencil shadows is that they tend to get slower with big levels and lots of lights. Finally you can also use just regular vertex lighting with no shadows. The discussion below focusses on the situation where you want to use static lightmaps.
First a small definition. The sector-lights is the list of lights that affect some sector. Every sector will have a sector-lights list containing not only the lights in that sector but every light that shines through the sector. It will contain dynamic, pseudo-dynamic and static lights.
Another small note about lighting. Crystal Space currently has static lights, pseudo-dynamic lights and dynamic lights. The pseudo-dynamic lights are an extension on the static lights which allow the static light to change color or intensity but not move. The advantage of pseudo-dynamic lights compared to real dynamic lights is that shadows are computed more correctly. Pseudo-radiosity will also work correctly and there is no run-time view-frustum calculation as with dynamic lights. Their only disadvantage is that they cannot move.
Now on to the cases for dealing with lights:
When you create a new thing it is easy to update the static lightmaps for that thing. This involves taking all lights in the sector-lights list and doing a view frustum calculation for all the static lights and only for the new thing. This only means that lighting on the Thing itself will be correct but it will not mean that the Thing will cast shadows for static lights. Calculating correct shadows is more complicated and time consuming. We cannot just update the lightmaps of the polygons that will become shadowed since there is no way to know how much light we should remove. The problem is that there is an upper light-level. If many lights affect the same lumel then it will be capped. When that happens you cannot just subtract a light because it will then not correspond with the real amount of light still reaching the lumel. The only way to correct this would be to redo all static lighting precalculation for those polygons. This is time-consuming.
In this case it would be easier to remove the shadows. You can redo the needed static lighting precalculations. However you have to be careful here. If you remove a Thing which was added without doing shadows (previous paragraph) then you should not remove shadows! So we have to remember if a Thing has casted shadows or not so that we can remove them.
This basically boils down to first destroying it and then recreating it at another position. There is an optimization possible. If we know that a Thing is meant to move from one position to another without interruption then we can calculate the lightmaps as they will become finally (at the last position) and just linearly interpolate the lightmaps in between.
In future it will be possible to flag portals that are closed. When you open this portal you'll have to recalculate all lighting that goes through the new portal. If you know in advance that some polygon is going to be opened in the future you can already store a lot of helpful information together with this portal to make calculation easier. One possibility would be to store the light-patches combined with view-frustum for every light that hits the polygon. We can then just continue the static lighting precalculation when the portal opens. This would be useful for doors that open and when opened let through the light: the door would be a Thing. When closed the portal is also closed and blocks the light. As soon as the door opens the portal opens and let's the light come through. A disadvantage is that this will be sudden and not gradual (as the door opens). But I think this is better than not relighting at all. But see the discussion in the next paragraph.
The problem with the previous approach is that you cannot in general use it for closing a portal again. The problem is that while it is easy to add light to a static lightmap you cannot easily remove light (since lightvalues are capped to a maximum). So the above solution would really only be useful for doors that once opened, remain open for the rest of the game. But maybe we have another solution. When the engine knows that a portal can open/close we can do the static lighting calculations as usual but store all lighting information that came through that portal in separate static lightmaps. That would be surprisingly easy to do. What this means is that polygons may have several series of static lightmaps which are conditionally used depending on the state of nearby portals. Another big advantage of this approach is that you can then use linear interpolation to interpolate between the two static lightmaps when a door is opening. For example, when a door is 50% open you show 50% of the first static lightmap and 50% of the second.
In principle it is possible to open portals everywhere you want, to anywhere you want. In this case however it is more difficult to adjust the lighting. You can still do it but more slowly. Opening arbitrary portals is going to be useful when you create new sectors to simulate destroying a wall. For example, when you shoot a missile at a wall you could create a new portal on that wall which simulates a hole. You could also create a whole new sector behind the wall. Note that this is getting a little complicated. Calculating the lighting is relatively easy as the sector is brand new and you can just calculate the lighting. Also see Breaking Through below.
No problem but you'll not be able to remove the lighting easily without recomputing a lot. Note that in the current version of Crystal Space portals also have correctly lighted lightmaps so closing a portal will yield a polygon which is correctly lighted.
When you fire a missile at a wall you may expect to be able to break through to the sector that is behind that wall. Aside from the portal and lighting problems there is an additional problem here. The portal world does not in itself have spatial information like this. It does not know that there is a sector behind that polygon. In fact there really is no concept of "behind a polygon". This would of course be a solution. If you make breakable walls state-portals (portals which can be closed and opened on demand like explained earlier) then there is no problem. But if you want to support this in general then we'll need to find a way to calculate spatial information like this. Calculating this at run-time is probably too expensive (you have to traverse every sector in the world and see which one you're arriving in). One way to solve this would be with a sparse 3D matrix which contains all sectors that intersect with a given 3D cube. This could be precalculated and would greatly improve the speed of testing in which sector a given 3D location falls. This of course only works with worlds which are standard and contain no special space-warping features (like overlapping sectors). Mirrors and reflecting surfaces would be ok as they can be flagged as not defining extra geometry but only reflecting existing geometry.
In some cases it may be a good option to have the ability to add a static light. Static lights have the advantage that there is no run-time overhead as soon as they are merged with the other static lights. So if you want to be able to put a light at an arbitrary position which is never going to be removed again then you should be able to create new static lights. Note that you can (and should) use pseudo-dynamic lights when you know in advance where the light is going to be. A good option would probably be the ability to merge a pseudo-dynamic light with the static lights. When you know that a pseudo-dynamic light is never going to change then this would be a very good idea. So converting a pseudo-dynamic light to a static light should be possible.
This is more complicated. In general you should use pseudo-dynamic lights for this. The pseudo-dynamic light can be on by default. When you want the light to be removed (for example because it is destroyed by a missile or something). You can set the intensity of the pseudo-dynamic light to black and then remove it from the world.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated using texi2html 1.76.