Shadow class from scenobject
by Duncan Gray · in Torque Game Engine · 12/22/2005 (11:00 pm) · 33 replies
I have, with some help from Ben, derived the shadow class from sceneobject and made it a client side sceneobject. This effectivly solves the problem of shadows which dissapear when the shadow casting object is off-screen and the shadow should still be onscreen.
It works well in that regard but I am still getting some anoying misplacement of shadows with the shadow being set to low on the shadow bitmap. The positioning code is all correct by the look of it and I don't want to just "hack it right" because I prefer code that does what it was designed to do.
I can email source to anyone who want to lend a hand in sorting it out.
It works well in that regard but I am still getting some anoying misplacement of shadows with the shadow being set to low on the shadow bitmap. The positioning code is all correct by the look of it and I don't want to just "hack it right" because I prefer code that does what it was designed to do.
I can email source to anyone who want to lend a hand in sorting it out.
About the author
#2
The Shadow class, during it's renderObject cycle, takes the creator's renderTransform to calculate the position of that shapeInstance on the shadow bitmap. Doing it this way means the ShapeBase and TSStatic classes no longer call renderShadow at all and also removes the code duplication in those two classes.
The update/process order could still be a problem on moving objects ( so far it does not look like its a problem) but I'm using a static tree as the main basis of my observations to eliminate motion problems for now.
I'll keep looking, I'm sure it's something so simple that I'm overlooking it as an option.
12/23/2005 (3:28 pm)
When the shadow object gets created, the Shadow class stores the pointer to the object which created it as well as the pointer to the creator's shapeinstance.The Shadow class, during it's renderObject cycle, takes the creator's renderTransform to calculate the position of that shapeInstance on the shadow bitmap. Doing it this way means the ShapeBase and TSStatic classes no longer call renderShadow at all and also removes the code duplication in those two classes.
The update/process order could still be a problem on moving objects ( so far it does not look like its a problem) but I'm using a static tree as the main basis of my observations to eliminate motion problems for now.
I'll keep looking, I'm sure it's something so simple that I'm overlooking it as an option.
#3
12/23/2005 (3:59 pm)
Maybe your texgen equations aren't quite right? It might be, especially if it's using GL texgen, that the verts aren't in quite the same space as before...
#4
The reason I'm not jumping up and down with joy is that the only change this mod makes is to prevent shadows from disapearing as described in the first post. All other shadow problems example are still present.
At certain angles the shape does not scale correctly onto the bitmap and so the shadow edges can sometimes appear clipped. If I take the shapes largest dimension and adjust the scale so that it fits the bitmap, then the positioning on the bitmap is incorrect. These were all problems I encountered before making the changes. Close but no cigar I'm affraid.
I found some free source code which generates shadows using the depth buffer of the video card, but it requires each scene to be rendered 3 times which will impact frame rate a bit but it does self shadow which is a step up from the current method. It's still a shadow mapping method, not volume shadows. But getting it into TGE could be a problem.
12/24/2005 (5:06 pm)
I found a minor bug in the positioning ( my fault ) which sorts out the offset problem so its working ok now.The reason I'm not jumping up and down with joy is that the only change this mod makes is to prevent shadows from disapearing as described in the first post. All other shadow problems example are still present.
At certain angles the shape does not scale correctly onto the bitmap and so the shadow edges can sometimes appear clipped. If I take the shapes largest dimension and adjust the scale so that it fits the bitmap, then the positioning on the bitmap is incorrect. These were all problems I encountered before making the changes. Close but no cigar I'm affraid.
I found some free source code which generates shadows using the depth buffer of the video card, but it requires each scene to be rendered 3 times which will impact frame rate a bit but it does self shadow which is a step up from the current method. It's still a shadow mapping method, not volume shadows. But getting it into TGE could be a problem.
#5
12/24/2005 (5:29 pm)
Does TSE shader technology solve any of these shadow problems?
#6
As far as the problems you see in TGE, the geometry one you saw could be fixed by making the dot product check for the geometry project code more lenient. I'm not sure what you're describing as the second problem ("At certain angles the shape does not scale correctly onto the bitmap and so the shadow edges can sometimes appear clipped. ") but the scaling math is fairly straightforward - I'm sure with a bit of pen and paper time you could reverse engineer it and derive something that better fit your needs. Right now it uses the shape radius, maybe you just need to make the bounding box bigger?
Shadows are really, really hard to do Right and fast. Check out some of the discussions on gd-algorithms for examples of just how convoluted everything gets. Often times close is good enough. :)
12/24/2005 (8:10 pm)
TSE doesn't have a unified shadow solution yet. That's MS4. That said we've encountered tremendous success with various per-game shadow solutions. For Think Tanks XBox we ported the existing shadow code (and this might be in CVS now, not sure). MBU has a stencil-shadow-ish solution.As far as the problems you see in TGE, the geometry one you saw could be fixed by making the dot product check for the geometry project code more lenient. I'm not sure what you're describing as the second problem ("At certain angles the shape does not scale correctly onto the bitmap and so the shadow edges can sometimes appear clipped. ") but the scaling math is fairly straightforward - I'm sure with a bit of pen and paper time you could reverse engineer it and derive something that better fit your needs. Right now it uses the shape radius, maybe you just need to make the bounding box bigger?
Shadows are really, really hard to do Right and fast. Check out some of the discussions on gd-algorithms for examples of just how convoluted everything gets. Often times close is good enough. :)
#7
The picture below shows 2 trees (dark brown vertical lines) on some terrain (light brown, flat, then sloping). The two yellow lines are light vectors. Length A shows the shadow length on the flat section of terrain. Length B shows the shadow length on a sloping section of terrain.
As you can see, objects of same height can produce shadows of varying length, depending on the angles of the 'shadow-receiver'. Below is a screenshot to show the length on a slope. Note the gap in the middle of the shadow due to terrain falling 'below' the light vector. What should be happening is that the shadow darkness should match the darkness of the gap section because they are both lacking the same amount of light or, experiencing the same amount of shade if you prefer, in that section. It should be possible to read the ambient and direct light values and set the shadow 'color' accordingly. More on that later.
In order to produce a shadow in TGE, all objects in the path of the shadow are located and asked to build a polylist so that a depth texture can be constructed. To find out how long an area you need to search, you need a shadow length. As you can see above, it's a pretty unknown factor, so TGE does a guess which is object radius * 10. I don't know why radius was chosen because with a tall object like a tree, itwould be more accurate to use the height.
It's also possible to cast a ray from the top of the object, along the light vector, and when you hit something, thats your, more accurate, shadow length. But again its not so simple, what if the ray hits a section of building but the remainder of the shadow is on terrain?
Why am I fussing about this? It takes time to search an area and build list of pollygons which lie in that area. The more accurate the search area, the higher the efficiency. The above picture shows an object and two boxes. The purple box is the objBox used by scenestate (in this mod) to determine if the shadow is in view. The big green box is the shadowbox which gets searched and any -shadow-receiving objects in there will have to build a depth mask, even though the shadow is only going to be in the purple box. The closer the green box matches the purple box, the faster the shadow production will be. The green-box is also aligned with world-space whereas the purple box is aligned with the light vector. If the green shadowbox could somehow be aligned with the light vector, combined with a ray cast to determine a more accurate search area....
The efficiency problem is further compounded when you have multiple objects in close proximity because the same area is searched once by each shadow producing object, resulting in multiple searches of the same area and multiple polylistbuilds for the objects in the search area.
Note the many overlapping green boxes in there. It would be way better if all static objects did their buildPolyList once and cached the results, say during scene lighting time. What I mean is, use the container bins (8x8m) as a convienient coekie cutter, build poly lists for each container, save them. Later when a moving object (player,vehicle) needs to cast a shadow, you just check what bins its shadowbox overlaps and get the save polylists from those bins.
I hope this helps people understand just how hard TGE has to work to produce shadows. More importantly, if my assesment is correct, theres plenty of room for improvement. However those improvements wont increase the quality of the shadows, just the production speed.
12/24/2005 (8:16 pm)
Ben, thanks, Ill post a screenshot of the clipping problem, meanwhile, I've filtered down my discoveries as follows which might be helpful to others taking this route.The picture below shows 2 trees (dark brown vertical lines) on some terrain (light brown, flat, then sloping). The two yellow lines are light vectors. Length A shows the shadow length on the flat section of terrain. Length B shows the shadow length on a sloping section of terrain.
As you can see, objects of same height can produce shadows of varying length, depending on the angles of the 'shadow-receiver'. Below is a screenshot to show the length on a slope. Note the gap in the middle of the shadow due to terrain falling 'below' the light vector. What should be happening is that the shadow darkness should match the darkness of the gap section because they are both lacking the same amount of light or, experiencing the same amount of shade if you prefer, in that section. It should be possible to read the ambient and direct light values and set the shadow 'color' accordingly. More on that later.
In order to produce a shadow in TGE, all objects in the path of the shadow are located and asked to build a polylist so that a depth texture can be constructed. To find out how long an area you need to search, you need a shadow length. As you can see above, it's a pretty unknown factor, so TGE does a guess which is object radius * 10. I don't know why radius was chosen because with a tall object like a tree, itwould be more accurate to use the height.It's also possible to cast a ray from the top of the object, along the light vector, and when you hit something, thats your, more accurate, shadow length. But again its not so simple, what if the ray hits a section of building but the remainder of the shadow is on terrain?
Why am I fussing about this? It takes time to search an area and build list of pollygons which lie in that area. The more accurate the search area, the higher the efficiency. The above picture shows an object and two boxes. The purple box is the objBox used by scenestate (in this mod) to determine if the shadow is in view. The big green box is the shadowbox which gets searched and any -shadow-receiving objects in there will have to build a depth mask, even though the shadow is only going to be in the purple box. The closer the green box matches the purple box, the faster the shadow production will be. The green-box is also aligned with world-space whereas the purple box is aligned with the light vector. If the green shadowbox could somehow be aligned with the light vector, combined with a ray cast to determine a more accurate search area....The efficiency problem is further compounded when you have multiple objects in close proximity because the same area is searched once by each shadow producing object, resulting in multiple searches of the same area and multiple polylistbuilds for the objects in the search area.
Note the many overlapping green boxes in there. It would be way better if all static objects did their buildPolyList once and cached the results, say during scene lighting time. What I mean is, use the container bins (8x8m) as a convienient coekie cutter, build poly lists for each container, save them. Later when a moving object (player,vehicle) needs to cast a shadow, you just check what bins its shadowbox overlaps and get the save polylists from those bins.I hope this helps people understand just how hard TGE has to work to produce shadows. More importantly, if my assesment is correct, theres plenty of room for improvement. However those improvements wont increase the quality of the shadows, just the production speed.
#8
Compared to the previous cluttered picture, this one is much cleaner with less overlaps of search areas.
Now, what does a ray cast cost compared to the previous clutter. Is it faster? Just some thoughts.
12/25/2005 (7:16 pm)
Here I implemented a cast ray from the top corners of the ObjBox (purple box) and used the longest cast as the shadow length. I also used the mWorldBox as the shadowBox (green box) because that comprises the best fit to the ObjBox.Compared to the previous cluttered picture, this one is much cleaner with less overlaps of search areas.
Now, what does a ray cast cost compared to the previous clutter. Is it faster? Just some thoughts.
#9
The angled matrix is flawed, causing the box used by the depthsortlist to be rotated on the y axis and thus creating a non optimum surface area. See the picture for english version...
That red area should be a rectangle but instead its a pointy affair and any shadow projection outside of it will be clipped. I put a white arrow near the top to indicate the depthsortlist box
It should look like below, after correcting the rotation by using the alternative matrix build method.
12/25/2005 (9:46 pm)
I believe a found one cause of the clipping problem I noticed. The Shadow class builds a light matrix based on the light direction. It does a check for a z value on the vector (i.e. is the light horizontal or angeled up or down) and choices a different matrix build method accordingly. The angled matrix is flawed, causing the box used by the depthsortlist to be rotated on the y axis and thus creating a non optimum surface area. See the picture for english version...
That red area should be a rectangle but instead its a pointy affair and any shadow projection outside of it will be clipped. I put a white arrow near the top to indicate the depthsortlist boxIt should look like below, after correcting the rotation by using the alternative matrix build method.
#10
The problem comes about in TSMesh::renderShadow where there is a check for Translucent materials and return. It does not seem to cause a problem by rendering transparent sections as you can see in the next picture below. It was probably a design decision based on some tree/object designs using transparent sections that end up looking like big square blocks on the object when shadowed. It would be better to include an addfield variable so that you could decide on a tree by tree basis whether you want to render the transparent portions or not. It would be nice if you could render through the transparent part to get an image of the non-transparent parts. I don't know if thats possible.

And now I can get to the final anoying problem before I can wrap this up and polish it. There appears to be a texture blending problem with the shadows and the shadow receiving object. The next pictures shows the above tree, same camera angle, but at a slightly greater distance. Notice the gap in the middle. Its not a clipping problem because thats been solved. I don't know what it is yet.
12/26/2005 (4:51 am)
Another problem solved. If you look at the tops of the tree shadows in the above pics, you will see the fluffy/leafy part is missing in most of the pictures. Those sections contain transparent sections and 95% of the time, they just don't get rendered. Why 5% of the time they do get rendered?, dont know.The problem comes about in TSMesh::renderShadow where there is a check for Translucent materials and return. It does not seem to cause a problem by rendering transparent sections as you can see in the next picture below. It was probably a design decision based on some tree/object designs using transparent sections that end up looking like big square blocks on the object when shadowed. It would be better to include an addfield variable so that you could decide on a tree by tree basis whether you want to render the transparent portions or not. It would be nice if you could render through the transparent part to get an image of the non-transparent parts. I don't know if thats possible.

And now I can get to the final anoying problem before I can wrap this up and polish it. There appears to be a texture blending problem with the shadows and the shadow receiving object. The next pictures shows the above tree, same camera angle, but at a slightly greater distance. Notice the gap in the middle. Its not a clipping problem because thats been solved. I don't know what it is yet.
#11
Shadows are technically an area where there is an absense of light except for whatever ambient light is present. I changed the shadow creation code to now use the sun ambient light level and color so that mesh shadows now exactly match diff shadows in color and darkness on any level, automatically.
You can see that the gap in the shadow in the middle is almost not noticeable because the shadow color/level is the same as the terrain shadow color.
Here I parked a vehicle partially in the shade of a diff object. See any difference in the shadows?
Oh yes, you may notice that wheeled vehicle tires also cast shadows.
I haven't found the fix for the previous post yet.
12/26/2005 (10:34 pm)
The above pics had a slight offset introduced when I was testing the new shadowbox. Its been fixed.Shadows are technically an area where there is an absense of light except for whatever ambient light is present. I changed the shadow creation code to now use the sun ambient light level and color so that mesh shadows now exactly match diff shadows in color and darkness on any level, automatically.
You can see that the gap in the shadow in the middle is almost not noticeable because the shadow color/level is the same as the terrain shadow color.
Here I parked a vehicle partially in the shade of a diff object. See any difference in the shadows?Oh yes, you may notice that wheeled vehicle tires also cast shadows.
I haven't found the fix for the previous post yet.
#12
(I have some ideas on how to fix this for TSE/Atlas, of course, but they're involved. ;)
For the size-of-query issue, I'd use the world aligned box to get a list of objects, then check to see if their bounds intersect the object aligned box. If so, then I'd call getPolyList on them. There's a findPolyhedron or similar call on Container that does something like this. Anyway, this ought to reduce the cost of large boxes significantly, unless you have a very dense environment with many objects in which case you might have to do some sort of bin-walking as a secondary tier.
Nice fix on the clipping issue.
Once you've had a chance to pound on this a little more, I'd love to sit down with you and find a way to get this taken "that extra step" and put into Torque HEAD. Some very nice work here.
I'm left with only one question - why isn't this awesome discussion you've written up on TDN? ;)
12/27/2005 (1:18 am)
Well, the terrain does LOD - could it be that that area of the terrain is changing LOD as you move in/out and causing problems in that way? Applying a bias by temporarily bumping the near/far planes closer for the duration of the shadow render might fix the problem or at least reduce it. If it remains then you'll have to find a way to get the exact geometry rendered that frame, which is a larger architectural problem. (I have some ideas on how to fix this for TSE/Atlas, of course, but they're involved. ;)
For the size-of-query issue, I'd use the world aligned box to get a list of objects, then check to see if their bounds intersect the object aligned box. If so, then I'd call getPolyList on them. There's a findPolyhedron or similar call on Container that does something like this. Anyway, this ought to reduce the cost of large boxes significantly, unless you have a very dense environment with many objects in which case you might have to do some sort of bin-walking as a secondary tier.
Nice fix on the clipping issue.
Once you've had a chance to pound on this a little more, I'd love to sit down with you and find a way to get this taken "that extra step" and put into Torque HEAD. Some very nice work here.
I'm left with only one question - why isn't this awesome discussion you've written up on TDN? ;)
#13
12/27/2005 (1:34 am)
Ben, no problem, I'd like to pound it out a bit more and polish it. I still have one or two other ideas I'd want to try an incorporate but need to research them a bit.
#14
12/27/2005 (3:34 am)
Great! Just drop me an e-mail when you're ready, and we can get things going.
#15
When the camera distance is moved, some of the objects in the jigsaw puzzel (including terrain polys) may go missing because those objects have jumped to a new LOD. This could deffinitely explain the problem.
Currently the shadow class only uses camera distance to change bitmap size from 64x64 to 32x32 when distance exceeds about 250m. It does a new partion build at that point (for statics) On moving objects it does a partion build(including depth sort and build poly) on every render cycle, which explains my you don't see this problem on player or vehicle shadows.
Which means a 'cpu cheap' way to resolve it would be to check, on each shadow render cycle, whether any of the shadow receiving objects have changed LOD and then do a build poly list again on only the object which changed LOD to get the new puzzel pieces for the current LOD.
On shapes you simply call getCurrentDetailLevel() because the entire shape gets affected by a LOD change, but on terrain its a different animal because only some poly's change/get merged.
I have not mucked about in the terrain and dif code much. For this to work, the
(1) terrain buildPolyList would have to take into account the LOD of the affected area
(2) If so, we need a fast way to determine/flag if any of the terrain poly's within the shadow box have changed LOD so that we can do a new buildPolyList.
Getting back to moving objects, a performance increase can therefore be achieved by checking if the object has actually moved position (within some tolerance level) before doing a new partionbuild, rather than just doing it every render cycle.
12/27/2005 (2:45 pm)
Regarding the LOD issue. It's my vague understanding that the engine uses the depth sort and build poly list to set up an array of polygons which the shadow will be drawn onto. Kind of like a jigsaw puzzle. Once the puzzle is built, the shadow bitmap is mapped onto it.When the camera distance is moved, some of the objects in the jigsaw puzzel (including terrain polys) may go missing because those objects have jumped to a new LOD. This could deffinitely explain the problem.
Currently the shadow class only uses camera distance to change bitmap size from 64x64 to 32x32 when distance exceeds about 250m. It does a new partion build at that point (for statics) On moving objects it does a partion build(including depth sort and build poly) on every render cycle, which explains my you don't see this problem on player or vehicle shadows.
Which means a 'cpu cheap' way to resolve it would be to check, on each shadow render cycle, whether any of the shadow receiving objects have changed LOD and then do a build poly list again on only the object which changed LOD to get the new puzzel pieces for the current LOD.
On shapes you simply call getCurrentDetailLevel() because the entire shape gets affected by a LOD change, but on terrain its a different animal because only some poly's change/get merged.
I have not mucked about in the terrain and dif code much. For this to work, the
(1) terrain buildPolyList would have to take into account the LOD of the affected area
(2) If so, we need a fast way to determine/flag if any of the terrain poly's within the shadow box have changed LOD so that we can do a new buildPolyList.
Getting back to moving objects, a performance increase can therefore be achieved by checking if the object has actually moved position (within some tolerance level) before doing a new partionbuild, rather than just doing it every render cycle.
#16
I have not looked at the above LOD issue yet, because its not that noticeable and therefore low priority.
The original Shadow class recreates the shadow bitmap based on a basic size/LOD lookup table, meaning, as you get further from the shadow, the on screen shadow size changes(gets smaller) so you need less detail in the shadow. It therefore recreates the shadow (using some cpu time) in order to save some memory with a smaller bitmap, the final bitmap being a 8x8 (or 16x16, not sure) blob shadow.
We can debate the merrits of saving cpu cycles as opposed to saving memory and perhaps just stick with one bitmap size, but seeing as the lookup table only implements 4 LOD levels, the cpu time can be ignored in favour of better memory management.
The new Shadow class therefore adds two additional LOD levels taking the closeup shadow bitmap to 256x256 as opposed to the old 64x64 maximum. The result is much better/finer detail in the shadow.

The old Shadow class did not delete the bitmap when the shadow caster was off screen. If you have 64 players, 100 trees etc then you could be sitting with memory going to waste which could be of value on console platforms. I need to look into the pros and cons of deleting the bitmap when shadows are offscreen and recreating them as needed.
12/30/2005 (2:37 pm)
Update, I have implemented the above performance movement check for shadow partion builds, using a quick matrix comparison to see if anything has changed.I have not looked at the above LOD issue yet, because its not that noticeable and therefore low priority.
The original Shadow class recreates the shadow bitmap based on a basic size/LOD lookup table, meaning, as you get further from the shadow, the on screen shadow size changes(gets smaller) so you need less detail in the shadow. It therefore recreates the shadow (using some cpu time) in order to save some memory with a smaller bitmap, the final bitmap being a 8x8 (or 16x16, not sure) blob shadow.
We can debate the merrits of saving cpu cycles as opposed to saving memory and perhaps just stick with one bitmap size, but seeing as the lookup table only implements 4 LOD levels, the cpu time can be ignored in favour of better memory management.
The new Shadow class therefore adds two additional LOD levels taking the closeup shadow bitmap to 256x256 as opposed to the old 64x64 maximum. The result is much better/finer detail in the shadow.

The old Shadow class did not delete the bitmap when the shadow caster was off screen. If you have 64 players, 100 trees etc then you could be sitting with memory going to waste which could be of value on console platforms. I need to look into the pros and cons of deleting the bitmap when shadows are offscreen and recreating them as needed.
#17
Main advantage of doing so: memory management. The bitmap loader in TGE 1.4 onwards, 1st checks if an image is already loaded before loading a new copy. This means if you have 100 identical trees, only one shadow bitmap will exist in memory.
The internal shadow bitmap is unique to each shadow caster because the shadow class can't determine if each object of similar type is positioned and angled exactly the same as another object of similar type etc.
So using the standard shadow code on 100 trees means 100 differnt shadow bitmaps in memory.
If I can implement the above deleting of bitmaps when not on screen, it would of course help the situation, but if you are building a forest, good luck.
The second reason for fake shadows is in relation to transparent sections. Most trees use transparent parts for the leaves which the current shadow code cant render.
The tree shadow on the right (below image) is a fake. Ideally it should be blurred a bit to match the real shadow on the left.

I have a plan for generating shadows which include tranparent sections, its a bit more cpu intensive than the current method but on static objects its not a problem because it only gets done once during mission load time. For moving objects, it would require a more modern computer so its use would be determined by setting an option flag by the user.
I'll put the concept in the next post, someone with good Opengl knowledge can write it in 1-2 hours. Have a bash at it.
12/30/2005 (3:05 pm)
The new shadow class allows for projecting fake shadows in place of internally generated shadows, obviously only usefull on static objects.Main advantage of doing so: memory management. The bitmap loader in TGE 1.4 onwards, 1st checks if an image is already loaded before loading a new copy. This means if you have 100 identical trees, only one shadow bitmap will exist in memory.
The internal shadow bitmap is unique to each shadow caster because the shadow class can't determine if each object of similar type is positioned and angled exactly the same as another object of similar type etc.
So using the standard shadow code on 100 trees means 100 differnt shadow bitmaps in memory.
If I can implement the above deleting of bitmaps when not on screen, it would of course help the situation, but if you are building a forest, good luck.
The second reason for fake shadows is in relation to transparent sections. Most trees use transparent parts for the leaves which the current shadow code cant render.
The tree shadow on the right (below image) is a fake. Ideally it should be blurred a bit to match the real shadow on the left.

I have a plan for generating shadows which include tranparent sections, its a bit more cpu intensive than the current method but on static objects its not a problem because it only gets done once during mission load time. For moving objects, it would require a more modern computer so its use would be determined by setting an option flag by the user.
I'll put the concept in the next post, someone with good Opengl knowledge can write it in 1-2 hours. Have a bash at it.
#18
{
// mat is the object matrix as seen from the sun vector
// BitmapSize is the size of the bitmap height or width(its square)
return;
// Not implemented yet, but here is the basic untested plan of action
/*
(1) check if the video card has an AUX buffer by calling
S32 numBuffers;
glGetIntegerv(GL_AUX_BUFFERS, &numBuffers);
if(numBuffers<1)
return;
(2) set up opengl projection matrix (viewport same size as bitmap)
(3) set up model matrix using mat (viewed from light vector)
(4) tell opengl to draw to buffer AUX0
(5) setup opengl for a black background:
glClearColor(0,0,0,0);
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
(6) render the shadow casting object
mOwnerInstance->render(); // draw the object to the buffer
(7) create a bitmap to store the render
GBitmap * blackBmp = new GBitmap;
blackBmp->allocateBitmap(bmpWidth,bmpHeight,false,GBitmap::RGB);
(8) tell opengl to read from buffer AUX0,
(9) read from the buffer to the bitmap, only alpha values required
glReadPixels(xcenter-(BitmapSize>>1),ycenter-(BitmapSize>>1),BitmapSize,BitmapSize,GL_ALPHA,GL_UNSIGNED_BYTE,(void*)blackBmp->getBits(0));
(10) mShadowTexture.refresh();
*/
}
The bitmap may then have to be inverted or alpah inverted etc to match the texture blend which the shadow render method uses.
And in practice the bitmap would be created and managed outside of the above texture management method.
12/30/2005 (3:06 pm)
Void Shadow::createShadowTexture(MatrixF & mat, U16 BitmapSize){
// mat is the object matrix as seen from the sun vector
// BitmapSize is the size of the bitmap height or width(its square)
return;
// Not implemented yet, but here is the basic untested plan of action
/*
(1) check if the video card has an AUX buffer by calling
S32 numBuffers;
glGetIntegerv(GL_AUX_BUFFERS, &numBuffers);
if(numBuffers<1)
return;
(2) set up opengl projection matrix (viewport same size as bitmap)
(3) set up model matrix using mat (viewed from light vector)
(4) tell opengl to draw to buffer AUX0
(5) setup opengl for a black background:
glClearColor(0,0,0,0);
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
(6) render the shadow casting object
mOwnerInstance->render(); // draw the object to the buffer
(7) create a bitmap to store the render
GBitmap * blackBmp = new GBitmap;
blackBmp->allocateBitmap(bmpWidth,bmpHeight,false,GBitmap::RGB);
(8) tell opengl to read from buffer AUX0,
(9) read from the buffer to the bitmap, only alpha values required
glReadPixels(xcenter-(BitmapSize>>1),ycenter-(BitmapSize>>1),BitmapSize,BitmapSize,GL_ALPHA,GL_UNSIGNED_BYTE,(void*)blackBmp->getBits(0));
(10) mShadowTexture.refresh();
*/
}
The bitmap may then have to be inverted or alpah inverted etc to match the texture blend which the shadow render method uses.
And in practice the bitmap would be created and managed outside of the above texture management method.
#19
I have no clue how to build the new 1.4 and no skill either, but i would give anything to see this resource implemented in tge. this, and detail maps :) (on separate uv's please).
happy new year..
12/30/2005 (3:14 pm)
'cries'I have no clue how to build the new 1.4 and no skill either, but i would give anything to see this resource implemented in tge. this, and detail maps :) (on separate uv's please).
happy new year..
#20
Have you considered using TSShapeInstance::snapshot() and then taking the alpha channel? :)
12/31/2005 (3:13 pm)
Duncan,Have you considered using TSShapeInstance::snapshot() and then taking the alpha channel? :)
Associate Matt Fairfax
PopCap