OpenGL Light Positions to D3D

Started by
2 comments, last by StakFallT 9 years, 11 months ago

Hi Gamdev.net,

I have a question that I'm hoping can be answered. I'm starting work on implementing shadow volumes in my game engine and I've been researching the topic a little here and there. I came across a PDF (located here: http://fabiensanglard.net/doom3_documentation/37730-293752.pdf) that disects part of the Shadow Volume code in the Doom 3 source. I tend to learn by getting something to work and then fiddiling with it until I completely understand it, so I'm trying to implement so I can master the concept before throwing it out and rewriting it, but I'm struggling with it a bit because the code seems to use quaternions for light rotations. This wouldn't be much of an issue except that everything that Direct3D 9 uses utilizes simply an x, y, and z value. There is a theta value...

Question 1) When I issue, to Direct3D 9, a statement to set a light's position or direction, are each of the components (x, y, and z) considered separate rotational vectors that have been formed by other values calculated internally by Direct 3D? Hard to explain but if you goto http://www.cs.princeton.edu/~gewang/projects/darth/stuff/quat_power.html and search in the document for the section Euler to Quaternion you'll see what I mean. I mean are the x, y, and z values some independant set of rotation values for each axis (Like some single value that encompasses the y and z rotations for x, the x and z rotations for y, and the x, and y rotations for z), or are x, y and z really just that and I'm overthinking them? If they really are just simple values to be treated, for example, as x is to be accompanied with y and z make up the entire rotation at face-value then how would one get a w value to use with the implementation presented in that paper I linked at the begining of the post? And how would this algorithm work with point lights? In that paper, the part that I'm referring to is on page 15 in Appendix A:


/*
Calculating Triangle Facing
Copyright (C) 2005 Id Software, Inc.
Written by J.M.P. van Waveren
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
*/
struct Vec4 {
float x, y, z, w;
};
struct Plane {
float a, b, c, d;
};
void CalculateFacing( const Plane *planes, const int numTriangles, const Vec4 &light, byte *facing ) {
int i;
for ( i = 0; i < numTriangles; i++ ) {
facing[i] = planes[i].a * light.x +
planes[i].b * light.y +
planes[i].c * light.z +
planes[i].d * light.w > 0.0f;
}
facing[numTriangles] = 1; // for dangling edges to reference
}
If I'm using D3D 9 lights can I just set light.w to 1.0f or 0.0f or would that have some bad mathematical effect? Is there some trick way that if D3D really does just use x, y, and z, and OpenGL uses Quaternions that I can make either one work or do I really need a conditional to check what API I'm using? I know it may seem like a basic question, but I've never really had to think this hard about how D3D actually handles it's directions or positions of lights. It's never ever been a problem up until now, now that I'm comparing it to OpenGL stuff. I would try reaching out to John Carmack on this but he's probably not exactly the most accessible guy :P Thanks in advance!
-- StakFallT
Advertisement

I haven't followed and read all of those links, but here's what I think is the right answer:

- When you set a DirectX9 light position, there are two modes. If you're setting a directional light, the X, Y and Z are the direction and W should be set to 0. If you're setting a point light, the X, Y and Z are the position and W should be set to 1.

- I'm pretty certain neither OpenGL nor DX9 uses quaternions for lighting natively in their fixed function pipelines, but with custom shaders maybe they are being used. I struggle to see why they'd be helpful for lighting though.

- The CalculateFacing function looks to me that it takes a whole bunch of plane equations and calculates whether they face toward the light or away from the light. I imagine that this is part of some code that's calculating the silhouette of an object. It probably iterates through all the triangles in the object, calculates which triangles face towards/away from a light, then uses that information to calculate which edges form the silhoutte, then extrudes those silhouette edges to construct some geometry that is used in stencil shadows. Stencil shadows have rather fallen out of favour (everyone seems to do shadow mapping these days) so learning how Doom3 does them might not be as valuable as you might hope (but I guess all learning is good).

Are you talking about fixed-function lighting in D3D? Because I'm pretty sure that Doom 3 would be using shaders...

@C0lumbo: Yup, that's exactly what it's doing. Just I saw the w in there, for lighting, and wasn't sure what to do with it.the setting w to 1 or 0 though was the info I was after :) Btw, what about if it's a spotlight? I'm guessing I'd set w to 0 like I would a directional? Shadow Mapping is being favored over volumes? I thought the volume technique came out after mapping?

@Hodgman: Well there's some optimization stuff in that first paper and it does mention using some hardware here and there throughout and if it's available; I'm not really sure where the code in that first paper matches and/or differs with the Doom 3 source. My guess is, it's some sort of hybrid -- that is, use hardware if available, otherwise do it on the cpu.

Btw, thanks guys for the quick replies!

This topic is closed to new replies.

Advertisement