Getting the Light Direction in TSMesh::render()
by DavidRM · in Torque Game Engine · 04/13/2006 (4:26 pm) · 13 replies
I'm trying to implement cel shading for TSMesh. I've run into a couple of issues, but the one I'm concerned with right now is getting the proper light direction.
I can get the "shadow direction" (the direction of the sunlight) by doing:
My Problem
I'm not sure how to adjust/tranform/sacrifice the correct breed of chicken to have that light direction match the mesh being rendered.
Right now, it's as though the light direction is constant relative to the mesh being render. In other words, moving/spinning around doesn't seem to be affecting the direction the light is coming from.
Any help would be appreciated.
Thanks.
-David
I can get the "shadow direction" (the direction of the sunlight) by doing:
lightManager->getShadowLightDirection();
My Problem
I'm not sure how to adjust/tranform/sacrifice the correct breed of chicken to have that light direction match the mesh being rendered.
Right now, it's as though the light direction is constant relative to the mesh being render. In other words, moving/spinning around doesn't seem to be affecting the direction the light is coming from.
Any help would be appreciated.
Thanks.
-David
#2
04/14/2006 (7:47 pm)
I wish I could help, since I'd be really interested in this lighting method...
#3
I'd imagine that getShadowLightDirection is going to return its direction in worldspace. Your lighting looks like it's calculating object space. So I'd imagine you need to do something like this:
Hope that pushes you in the right direction
Brian "bzztbomb" Richardson -- Knowhere Studios
04/15/2006 (4:06 pm)
Just taking a random little guess here:I'd imagine that getShadowLightDirection is going to return its direction in worldspace. Your lighting looks like it's calculating object space. So I'd imagine you need to do something like this:
VectorF lightDir = lightManager->getShadowLightDirection(); lightDir = mWorldToObject.mul(lightDir);
Hope that pushes you in the right direction
Brian "bzztbomb" Richardson -- Knowhere Studios
#4
That did help. Thanks.
Now to find a simple way to get at the mWorldToObj member or getWorldTransform() function from TSMesh (which doesn't seem to have any link back to the object being rendered).
Passing the world-to-object transform matrix down into the TSMesh::render() function was my first rather hack-kludge solution. It mostly worked. ;) But I kept thinking that there had to be a more direct (and simple) way of doing that.
Still digging. :)
Thanks again!
-David
04/15/2006 (7:08 pm)
Brian,That did help. Thanks.
Now to find a simple way to get at the mWorldToObj member or getWorldTransform() function from TSMesh (which doesn't seem to have any link back to the object being rendered).
Passing the world-to-object transform matrix down into the TSMesh::render() function was my first rather hack-kludge solution. It mostly worked. ;) But I kept thinking that there had to be a more direct (and simple) way of doing that.
Still digging. :)
Thanks again!
-David
#5
04/18/2006 (8:55 am)
I'm sure you can use some DGL or GL commands to grab the current MODEL_VIEW matrix. Invert it, and you'll have a matrix equivalent to mWorldToObj.
#6
Because that's not working. Specifically, it seems that the light direction is affected by the direction of the camera, not the direction of the light source.
Am I missing something?
Thanks!
-David
04/18/2006 (9:35 am)
Like this?Point3F lightVector; lightVector=-lightManager->getShadowLightDirection(); MatrixF modelView; dglGetModelview(&modelView); modelView.inverse(); modelView.mulP(lightVector); lightVector.normalize();
Because that's not working. Specifically, it seems that the light direction is affected by the direction of the camera, not the direction of the light source.
Am I missing something?
Thanks!
-David
#7
So I went back to a variation of the hack I was trying to avoid: I changed TSMesh::render() to have the world-to-object transform passed in as a parameter (const MatrixF *). Seems to work OK, though I now have an odd bug to track down in billboard rendering. I think I ran afoul of some default parameters somewhere.
It's progress:

Thanks.
-David
04/19/2006 (5:48 pm)
Can't use the model view matrix...unless you can remove the "view" part from it. Which seems more trouble than it's worth.So I went back to a variation of the hack I was trying to avoid: I changed TSMesh::render() to have the world-to-object transform passed in as a parameter (const MatrixF *). Seems to work OK, though I now have an odd bug to track down in billboard rendering. I think I ran afoul of some default parameters somewhere.
It's progress:

Thanks.
-David
#8
04/19/2006 (7:57 pm)
That looks great! I'd love it if you released the renderer changes when you were done, but that's totally up to you. I really wish I knew more about the renderer setup to help you with the lighting stuff >.<
#9
04/19/2006 (8:07 pm)
Seems like no one likes to release cel-shading code :( I hope someon does someday.
#10
04/19/2006 (8:25 pm)
I just got TGE and seeing this makes me excited to learn enough to do stuff like this. Nice work! (I hope you release the code too ;))
#11
I use multitexturing, layering a 1-dimensional shading "texture" on top of the model. The shading texture is much like the one talked about here:
www.gamedev.net/reference/programming/features/celshading/
For the texture coordinates, I go through the vertices of the model and take the dot product of each vertex normal and the light vector (converted into object space).
Currently, I do the multitexturing as a separate pass. My plan is to integrate with Torque's multitexturing for detail maps and environment maps. That will save me going through the polygon list, as well as the overhead of setting up OpenGL, and resetting it again.
The ugliest part of all of this has been (and remains) getting the world-to-object transform into the render() function. That requires a change that ripples up the engine from the low level render() routine to most of the game objects and even a few GUI controls.
-David
04/19/2006 (8:26 pm)
I'll release the cel shading code when I've cleaned it up some. In the meantime, here's the gist of it:I use multitexturing, layering a 1-dimensional shading "texture" on top of the model. The shading texture is much like the one talked about here:
www.gamedev.net/reference/programming/features/celshading/
For the texture coordinates, I go through the vertices of the model and take the dot product of each vertex normal and the light vector (converted into object space).
Currently, I do the multitexturing as a separate pass. My plan is to integrate with Torque's multitexturing for detail maps and environment maps. That will save me going through the polygon list, as well as the overhead of setting up OpenGL, and resetting it again.
The ugliest part of all of this has been (and remains) getting the world-to-object transform into the render() function. That requires a change that ripples up the engine from the low level render() routine to most of the game objects and even a few GUI controls.
-David
#12
No, mulP is wrong. What you want there is mulV. mulP is intended for a point (which has positional information), whereas mulV is intended for vectors (for which only the rotation should be transformed).
04/19/2006 (9:19 pm)
RE: "Like this?"No, mulP is wrong. What you want there is mulV. mulP is intended for a point (which has positional information), whereas mulV is intended for vectors (for which only the rotation should be transformed).
Torque Owner DavidRM
Progress, I figure, especially if you saw some of the stuff I was seeing earlier this week. ;)
Anyway, I'm having no luck puzzling out how to transform the light direction. Right now, it's always hitting the model from the same direction, regardless of whether inside or outside. Once I can get the sunlight direction adjusting properly, I'll worry about interior lights.
Any help would be appreciated.
Thanks.
-David