## News on real-time shadows in D2X-XL and a call for help

**Moderators:** Grendel, Aus-RED-5

### News on real-time shadows in D2X-XL and a call for help

I have had some time recently to dig into the real-time shadowing code in D2X-XL, and finally managed to get it to work using a very simple 'ship' model in the form of a cube to simplify things.

In the course of this I have found out that even that model was already flawed - either inherently due to the oof format, or by the author, as one face had its normal (perpendicular on the face) pointing inside the model instead of outside.

After fixing this I finally managed to get working shadowing code.

When employing the regular ship models (both low and hires) shadowing didn't properly work though. This is due to flaws in the model data (like face vertex lists in the wrong order, normals pointing to the wrong the direction, adjacent faces not directly connected).

Bottom line: With the current models, realtime shadowing in D2X-XL will not be possible.

So if someone has time at his hands, he'd be welcome to create new, well-modeled player ships (and possibly other bots).

One technical hint: Face vertex order may be reversed, but the face normals must point to the proper direction (if this is assured, I can determine face winding in D2X-XL).

In the course of this I have found out that even that model was already flawed - either inherently due to the oof format, or by the author, as one face had its normal (perpendicular on the face) pointing inside the model instead of outside.

After fixing this I finally managed to get working shadowing code.

When employing the regular ship models (both low and hires) shadowing didn't properly work though. This is due to flaws in the model data (like face vertex lists in the wrong order, normals pointing to the wrong the direction, adjacent faces not directly connected).

Bottom line: With the current models, realtime shadowing in D2X-XL will not be possible.

So if someone has time at his hands, he'd be welcome to create new, well-modeled player ships (and possibly other bots).

One technical hint: Face vertex order may be reversed, but the face normals must point to the proper direction (if this is assured, I can determine face winding in D2X-XL).

You'd be better off remodeling them from scratch.

I was going to make a short animation featuring a Pyro for the CG class at University, but when I saw the ugly meshes of the models from the Descent Network I tried to fix them for a few hours, but I eventually got too frustrated to continue and started a completely different scene featuring some kind of mermaid.

I do however have a custom pyro where face normals and the entire mesh are 100% error free.

I still have major problems with shadow rendering though. Somehow all calculations are depending on viewer position, and I have no explanation for this. If you know something about this stuff and can help me, let me know and I will explain some more details.

Edit: I am slowly getting closer. Oh man, the D2 transformation code is really getting in my way here ...

I'm looking at the OGL2.1 spec, can't seem to find where it says how normals are computed. I'm thinking it'll be better to look at a 1.x specification for that information, since it's formatted differently and with older hardware in mind.

Say, why does OGL's normal computation matter anyway? Doesn't D2 compute all its own normals? And you need to have face culling off for shadows, so really OGL has no business knowing the shadow faces' normals.

[edit] pfffft one minute apart lol.

Currently it looks like the volume side's faces do not always have their normals facing to the proper direction.

Man I am

**so**close to finally having some working shadow rendering (at least for properly constructed models).

As far as test models go, test a 4 vertex pyramid, then move up to a 3x larger pyramid with a 1x pyramid taken out of the center (so you're left with 4 1x pyramids). If you can get both of those models to render correctly in all rotations relative to the light, most any solid model should work (not sure of the cases where any wouldn't, but it has to do with the number of faces per edge). If these test cases work but shadowing a complex object still doesn't work, odds are something's wrong with the object's model.

But I will explain to you what the problem is. To render the shadow volumes, you have to extrude the volume sides from the edges that form the silhouette of the model as seen from the light source.

Now face direction (front/back) is determined by OpenGL with some geometrical operation depending on the position of a polygons vertices (polygon winding). Lets take a quad for the sake of simplicity: You have four corners v[4] at (0,0), (1,0), (1,1) and (0,1). That is GL_CCW (counter-clockwise). You can determine this by determining the sign of (v[1].x - v[0].x) * (v[2].y - v [1].y) (you don't need to consider z for this). If it's < 0, you have GL_CCW, otherwise GL_CW.

Extruding a volume side quad goes by using its edge's two vertices (ev[2]) and computing two more vertices by projecting them to infinity as seen from the light source (lv). This goes like

ev[2] = (ev [1] - vl) * INFINITY

ev[3] = (ev [0] - vl) * INFINITY

where INFINITY is some sufficiently huge value. (You can do infinity projections by setting up a special transformation matrix, but it works good enough this way).

So far, so good, but when computing the silhouette edges, I am getting their vertices in some arbitrary order. That means that the volume sides extending from them have some random winding. That means that they can be considered a back face by OpenGL although they should be a front face and vice versa.

(A silhouette edge is an edge between two model faces where one of the faces is visible from the light source and the other is not).

Generally in D2 all faces are defined GL_CW (so you have to enable GL_CULL_FRONT if you want to have OpenGL not render the faces pointing away from the viewer - a small quirk in the engine). Now consider two adjacent model polygons (i.e. sharing an edge). Depending on which I treat first when determining silhouette edges, I will get the edge's vertices in the order (v

*,v[i+1]) or (v[i+1],v*

*) (i being a valid index of the polygon's vertex list).*

I am having an example using a cubic model where this already causes problems.

I have no idea how to fix this. And this the key to making this stuff finally work.

Edit: Maybe I can determine the winding of the faces after having transformed their vertices ... a volume face should have the winding of that face of its edge that is invisible to the light source ...

Edit 2: Seems like I can't ...I am having an example using a cubic model where this already causes problems.

I have no idea how to fix this. And this the key to making this stuff finally work.

Edit: Maybe I can determine the winding of the faces after having transformed their vertices ... a volume face should have the winding of that face of its edge that is invisible to the light source ...

Edit 2: Seems like I can't ...

- Shadowfury333
- DBB Ace
**Posts:**326**Joined:**Mon Aug 09, 2004 8:36 pm

Btw, the shadowing code is working now, but it is as I suspected: The Descent 2 models and also Eagle's hires pyro are horribly broken in terms of shadow rendering. Even my own custom Pyro had quite a few flaws (mostly duplicate faces). I have fixed most of them, but one is still present.

So in theory we can now have real time shadowing in d2x-xl, but in practise it doesn't work due to the badly built models. :-/

This is kind of a let down.

heh.

At least I learned a few more things about OpenGL and could optimize D2X-XL rendering processes a little bit. The guy(s) doing the initial OpenGL code did somewhat of a half-baked job. They were probably learning by doing, like me.