Allegro.cc - Online Community

Allegro.cc Forums » The Depot » Tonight, there will be shadows

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Tonight, there will be shadows
Mark Oates
Member #1,146
March 2001
avatar

I have a goal tonight to get real-time shadows into my 3D arsenal.

Specifically, I'll be running through this tutorial.

I believe I have everything else setup and have a good shot. I'll be keeping an update log here, so please comment generously so I'm not stuck updating my last post with edits? Thanks!

Ok, first order of business... I need a nice simple "world" model that is good for checking shadows, so I'm off to blender to throw something together.

EDIT 1
Alright, I've got a little scene created: :)
{"name":"609994","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/3\/1392ef2fa90a3440378ac3799f6ad9ee.png","w":1440,"h":900,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/3\/1392ef2fa90a3440378ac3799f6ad9ee"}609994

EDIT 2
Okie dokie, The model is now working correctly inside the program and a good camera angle.
{"name":"609995","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/f\/0f0a2facd89010537ab74a4ec6d14d7c.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/f\/0f0a2facd89010537ab74a4ec6d14d7c"}609995

EDIT 3
To keep things focused on just-get-things-working, I grabbed the glm:: header files that are used in the tutorial to build the ortho transform for the light projection. Thanks to Elias' cool new feature, I was able to peruse the code much more easily and skim-check if there were any conflicts between the glm matrix and Allegro's ALLEGRO_TRANSFORM. So far no red flags. :)

EDIT 4
Alrightie, the difficulty curve has shot up. There are conflicts between my OpenGL/GLSL/version_numbers/Allegro/the_tutorial/my_knowledge_of_anything. For one reason or another, I am unable to create a framebuffer with this simple code (the glCheckFramebufferStatus line keeps sending me to "glCheckFrambufferStatus == FALSE") :( :

#SelectExpand
1GLuint FramebufferName = 0; 2 bool initialize() 3 //bool make_shadow_texture() 4 { 5 // The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer. 6 glGenFramebuffers(1, &FramebufferName); 7 glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); 8 std::cout << "FramebufferName==" << FramebufferName << std::endl; 9 10 // Depth texture. Slower than a depth buffer, but you can sample it later in your shader 11 GLuint depthTexture; 12 glGenTextures(1, &depthTexture); 13 glBindTexture(GL_TEXTURE_2D, depthTexture); 14 std::cout << "depthTexture==" << depthTexture << std::endl; 15 glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0); 16 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 17 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 18 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 19 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 20 21 glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0); 22 23 glDrawBuffer(GL_NONE); // No color buffer is drawn to. 24 25 // Always check that our framebuffer is ok 26### if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 27 { 28 std::cout << "glCheckFrambufferStatus == FALSE" << std::endl; 29 return false; 30 } 31 std::cout << "glCheckFrambufferStatus == TRUE" << std::endl; 32 return true; 33 }

To keep moving what I might have to do is just create a shader on an ALLEGRO_BITMAP that draws the depth in RGB. more investigation to continue...

EDIT 5
Also, to anybody who's interested, the tutorial's shaders have #version 330 core at the top, and upon compiling the shader I get the message "ERROR: version 330 is unavailable"

EDIT 6
Wooohf! I finally made some headway. This whole time I was having difficulty drawing to an ALLEGRO_BITMAP; It was coming out blank. It turns out it was because the object(s) I was trying to draw (the scene model from earlier) was not being drawn in both views, despite me having created the infrastructure. The static world model was considered a "special case" in the engine and not included in the list of entities to render in all views. Good news is, now I have 2 projections with different rendering methods working simultaniously. :)

Camera View:
{"name":"609996","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/8\/a8c99f72a570e25a16f175efc680c5df.png","w":1920,"h":1200,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/8\/a8c99f72a570e25a16f175efc680c5df"}609996
Light Projection View:
{"name":"609997","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/d\/ad607aced189ead5c93e1a1f58029b56.png","w":1920,"h":1200,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/d\/ad607aced189ead5c93e1a1f58029b56"}609997
Depth is right around the corner. :)

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

SiegeLord
Member #7,827
October 2006
avatar

What's going on here... :o:o

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Mark Oates
Member #1,146
March 2001
avatar

A cacophony of stream-of-concious efforts. ;D

When attempting to render to my depth-view, the depth test is somehow exactly flipped.
{"name":"609998","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/f\/8f41682a891e29552ab1a2b433c82782.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/f\/8f41682a891e29552ab1a2b433c82782"}609998

I'm even at the point now where I'm getting glitch art: 8-)
{"name":"609999","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/c\/ac088e791935043a4c1d615704677eed.png","w":1044,"h":706,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/c\/ac088e791935043a4c1d615704677eed"}609999

It looks like the shadows won't arrive for another day. Perhaps my weary body will be better equipped after a nights rest.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Gideon Weems
Member #3,925
October 2003

If this turns out to be good, we should put it on the wiki.

Mark Oates
Member #1,146
March 2001
avatar

So, the challenge continues!

In discouragement at being unfamiliar with rendering to a strict depth buffer, I decided to just create a simple shader that would draw depth to an ALLEGRO_BITMAP. What I did was pass into the shader the real-world-position of the camera, and calculate distance() to the real-world-position of the vertex. It worked... ish:
{"name":"610003","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/c\/5c5a4fe173e1b736e52c3676515892b8.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/c\/5c5a4fe173e1b736e52c3676515892b8"}610003
Darker colors represent being closer to the camera, while lighter colors are further.

But why is the floor white? My theory is that since I was calculating the distance to each vertex, glsl was calculating that the four corners of the bottom plane were at a far distance from the camera, and then interpolating those values to fill in the rest of the geometry.

At that point I realized that the camera's position is already (0,0,0) in the shader after the al_porjview_matrix is multiplied to the object in the shader, and I could avoid having to calculate a million distance() formulas, which are really slow. And the depth value that I need is already in the 4th component of the shader's gl_Position.

I coded it in, and it worked!
{"name":"610004","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/0\/2001f9c79772db6044463ddb07d8f73e.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/0\/2001f9c79772db6044463ddb07d8f73e"}610004
This is the actual depth data that I need (but to make it more visible, I had to multiply it by 0.05 because my view frustum is verrrrry deep. When I make it a frustum for the light projection, it probably won't need to be nearly as deep)

So much more to do! :D

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

GullRaDriel
Member #3,861
September 2003
avatar

That stuff is pretty cool Mark !

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Mark Oates
Member #1,146
March 2001
avatar

Thanks :)

Ok, it looks like I have run into a problem. When drawing to an ALLEGRO_BITMAP that is not the backbuffer (or a subbitmap of the backbuffer), the depth sorting gets all messed up. This is what the scene looks like when drawn per the usual way:

Normal:
{"name":"610013","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/9\/4913504c602951bba4ca578bd0e2597b.png","w":1920,"h":1200,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/9\/4913504c602951bba4ca578bd0e2597b"}610013

Depth Shader When Drawn On Backbuffer: - Looks good, everything appears to work out.
{"name":"610014","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/3\/33555fec41d7a9b9a45bdf7da92db8a0.png","w":1920,"h":1200,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/3\/33555fec41d7a9b9a45bdf7da92db8a0"}610014

Depth Shader On A Target Bitamp (that is NOT a Backbuffer): - EEKS!
{"name":"610015","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/b\/fb200f6810fbbe86d5dd3af9b9dc2457.png","w":1920,"h":1200,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/b\/fb200f6810fbbe86d5dd3af9b9dc2457"}610015

I'm not sure what's causing this problem. Any ideas? I'll try it without using a shader.

EDIT 1
Oh well interesting, it also has the same problem when not using the shader.

Normal Drawing on a Target Bitmap (that is NOT a Backbuffer): - Also EEKS!
{"name":"610016","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/2\/3265897c395bce43dd6e5a87da48da33.png","w":1920,"h":1200,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/2\/3265897c395bce43dd6e5a87da48da33"}610016

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Bruce Pascoe
Member #15,931
April 2015
avatar

I'm guessing it's because only the backbuffer has a Z-buffer. A regular bitmap is just a flat matrix of pixels, where would you store the depth info?

SiegeLord
Member #7,827
October 2006
avatar

It's possible for a bitmap to have a z buffer, but Allegro provides no means to create this. See https://github.com/liballeg/allegro5/issues/477.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Mark Oates
Member #1,146
March 2001
avatar

I'm guessing it's because only the backbuffer has a Z-buffer. A regular bitmap is just a flat matrix of pixels, where would you store the depth info?

Did not know that.

SiegeLord said:

It's possible for a bitmap to have a z buffer, but Allegro provides no means to create this. See https://github.com/liballeg/allegro5/issues/477.

Would use! I was wondering why offscreen bitmaps don't have multi-sampling.

Either way...

al_set_target_bitmap(backbuffer);
setup_projection(light);
draw_the_depth_pass();

al_set_target_bitmap(depth_pass_surface);
al_draw_bitmap(backbuffer);

al_set_target_bitmap(backbuffer);
// ... continue on as if nothing happened

Nothing will stop me! >:E

---

Also, incidentally, I noticed something wrong with the depth image:

{"name":"610019","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/e\/5ed9bfd99b90353c0d61df97ea97252e.png","w":941,"h":575,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/e\/5ed9bfd99b90353c0d61df97ea97252e"}610019

I thought there was something wrong with my depth algorithm, so I looked into it and it turns out the geometry was messed up. The cone was hovering above the plane by about 0.2:
{"name":"610021","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/6\/96cb22eaf7ad1c7e8e38bcd800cd3e14.gif","w":396,"h":211,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/6\/96cb22eaf7ad1c7e8e38bcd800cd3e14"}610021

So I fixed that:
{"name":"610022","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/c\/acce09e40629957190cb98e10404bfb6.png","w":727,"h":473,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/c\/acce09e40629957190cb98e10404bfb6"}610022

---

Ok. I'm excited to finally have a (sort of) depth map! Next up we should see some semblance of shadows. :)

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Bruce Pascoe
Member #15,931
April 2015
avatar

That hovering cone reminds me of old 90s CGI cartoons (e.g. Beast Wars) where it often looked like the characters were walking just above the ground.

Mark Oates
Member #1,146
March 2001
avatar

Ok, I owe you guys an update 8-)

I have achieved semblance of shadows!

This was the very first time where all the components are accounted for!

{"name":"610023","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/b\/3bdde501683c89772d8f8f4ddb782497.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/b\/3bdde501683c89772d8f8f4ddb782497"}610023

Everything's all out of wack, but it's all in there. All that's left is to work out the math just inside the shader. I added a bunch of little floating objects to make the depth more palatable. Note that this is not actual shadows mapped, rather it's the depth image just plastered onto the models as if it were a regular plain old texture map.
610024
The floating things are just reflective AllegroFlare logos.

It's cool 'cause if you look at the floor you can see that the rotating logos have "shadows" that are also rotating as well.

That's where it all started.

After that, I needed to make sure the 0.05 that I multiplied to the depth wouldn't be a problem.

{"name":"610025","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/5\/5581400a6160bb752680d37874f00768.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/5\/5581400a6160bb752680d37874f00768"}610025
^This is me checking that the light depth and camera depth data are not being confused with each other. In this image, the darker pixels represent smaller distance to the light source. So this shows that the light source is on the other side of the camera and that data is separate from the active viewing angle. It also shows that the value ranges for the light depth and camera depth are (essentially) the same.

Good. Everything is in order.

Now it's time to calculate an actual shadow map onto the scene.

And finally, without further ado, here is the first image showing an actual shadow projection:

{"name":"610026","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/5\/653de59d8f8b43741cf4b39030ce9efe.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/5\/653de59d8f8b43741cf4b39030ce9efe"}610026

All screwed up. 8-)

If you look carefully, you can see that the texture is looping for some reason. So somewhere the UV mapping coordinates are scaled incorrectly. So I scale them by some multiple:
{"name":"610027","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/8\/f830b1d3919a5aa5396799de48bd3f77.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/8\/f830b1d3919a5aa5396799de48bd3f77"}610027
^ Oops! wrong direction. :P I multiplied when I should have divided.

{"name":"610028","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/7\/47b33701eed38d4c6ef16abc33ef3f18.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/4\/7\/47b33701eed38d4c6ef16abc33ef3f18"}610028
Cool, but the alignment is off, too. So I put in 2 dials to let me offset the texture:

video

At this point I create a bunch of cool abstract art. But it's still a little tough to se what's going on so I put in some crappy texturing to get a better sense of space and depth:

video

It's so close. 8-) It looks like the depth calculation is correct - shadows are deforming onto the geometry correctly. It's cool how it working and not working at the same time. It's just that there is something amis with the actual projection itself.

... until next time ... ;)

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Arvidsson
Member #4,603
May 2004
avatar

This is a fun and interesting read! Please never stop ☺

GullRaDriel
Member #3,861
September 2003
avatar

Moar ! ;D

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

ks
Member #1,086
March 2001

This is great and quite like the updates. I would definitely support ($$) an Allegro 3D solution even if free or low cost alternatives exist.

Will you consider integrating https://github.com/assimp/assimp for model loading?

Peter Hull
Member #1,136
March 2001

On the other hand, you are 300% over schedule and not finished yet. Work harder, Oates.

;)

Mark Oates
Member #1,146
March 2001
avatar

I wanted to add that when trying to correctly align the light texture into the scene, one method I tried was to place the camera and the light at the exact same position. In theory, this would allow me to tinker with the UV position and scale, and see when the shadow projection and scene were in sync:

video

^ This is the light and the camera placed and viewing the scene from the exact same position, both are rotating around the scene together in sync.
;D Looks cool :D Unfortunately, it didn't prove to be as useful as I had thought so I went back to separate locations.

Also, I found out that you cannot make your own variables in GLSL with a gl_* prefix. I tried naming a variable gl_Position_from_light and got this wonderful work of bow tie art:

{"name":"610030","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/2\/c2f20f42e902ab1b24665329980c5306.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/2\/c2f20f42e902ab1b24665329980c5306"}610030

and an error message that read ERROR: 0:13: Identifier name 'gl_Position_from_light' cannot start with 'gl_'

Anyway, that's all in the past.

---

This is where we are now. As you can see by the end of the video, we're so close!

video

Ahgh! So close you can almost taste it! ;D

If you look closely at how the shadows are distorting, you can see that all the shadows seem to be bending inward towards the back, rather than outward. I think the reason is because I am using a perspective projection for the light, when I should be using an orthographic projection. It's as if the shadows at the center are OK, but further on the edge of the camera, they seem to bend in and shrink towards the back, like what would happen in a perspective projection.

So, if I "unproject" that perspective distortion...

Eh? What do you think? ;)

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

SiegeLord
Member #7,827
October 2006
avatar

I dunno, if you're simulating nearby a point light, then a projective transformation makes sense. If you're simulating a far away light, then orthographic would be fine.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Gideon Weems
Member #3,925
October 2003

ERROR: 0:13: Identifier name 'gl_Position_from_light' cannot start with 'gl_'

What sort of pre-processor magic makes this possible? It reminds me of printf-related warnings. The pre-processor sometimes comments about invalid format strings.

Will you be able to do this in real time?

Bruce Pascoe
Member #15,931
April 2015
avatar

I always assumed it was the compiler that generated the printf warnings. In that case it's just a matter of looking at the arguments of a printf() call--since the compiler already knows how to read the grammar--and parsing the format string. I would assume it's similar to how JS treats eval() differently depending on whether it's actually called as "eval" versus through an alias.

Peter Hull
Member #1,136
March 2001

Quote:

And he answered them not, but raised his eyes to the heavens, saying "Tonight, there will be shadows, threads shall be locked, and Phipps shall return."

From the Gospel of St Mark of Oates, 12:28

Bruce Pascoe
Member #15,931
April 2015
avatar

Who is this Phipps guy anyway?

Mark Oates
Member #1,146
March 2001
avatar

OK! Just got back from a wedding cruise and have had time to work on this puppy. I won't reveal to the end, but things are working and the shadows are straight up sexy.

{"name":"610039","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/1\/919015bc88e1531f2762f3b98e1d92c1.gif","w":320,"h":240,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/1\/919015bc88e1531f2762f3b98e1d92c1"}610039

SiegeLord said:

I dunno, if you're simulating nearby a point light, then a projective transformation makes sense. If you're simulating a far away light, then orthographic would be fine.

A perspective transform should work. In the tutorial, it uses a ortho transform, but there is another later section that says if you want to use a perspective transform then (...) and I didn't read that part. So, I dove into trying to fix it by switching back to ortho and it worked.

Sort of.

Part 1: Getting to the Orthographic Projection

It took awhile to get the ortho transform in place, since you can't just simply swap out al_perspective_transform with al_orthographic_transform. Here's what it looked like when I just swapped them out:

{"name":"610040","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/2\/325764e7f3f265cf3cedae492d098931.png","w":2088,"h":1412,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/2\/325764e7f3f265cf3cedae492d098931"}610040

When I looked closer, I could see these tiiiiiiiiny pixels in the top left of the frame, which happens to be the whole scene:

{"name":"610041","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/d\/3d9c20c9baa9479e8af8346d93921211.png","w":1761,"h":1184,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/d\/3d9c20c9baa9479e8af8346d93921211"}610041

The whole scene be about 10 'units' wide in geometry, which in iso projection is about 10 pixels. So, I had to scale it up and center it to match the view I had previously:

{"name":"610042","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/9\/29fd0732ac80de482dfc1f28147ae4c7.png","w":1072,"h":734,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/9\/29fd0732ac80de482dfc1f28147ae4c7"}610042

Awesome.

I ended up using the exact same ortho projection for the light and the scene, but from different viewing angles. That way I wouldn't have to worry about possible inconsistencies when merging the two projections for a shadow.

Ok, here's the interesting part. Notice that in the upper right corner (that's the light's view depth map) that the entire scene is black? This happened when I switched to ortho mode.

Something new is up with the depth z-values, so I tried a bunch of different things to see what I could get out of the pixel data. I tried curving the brightness of the colors in a bunch of different ways...

{"name":"610045","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/0\/504d0ad0c7f3b899178d8f619cb611fd.png","w":390,"h":250,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/0\/504d0ad0c7f3b899178d8f619cb611fd"}610045

...but found out that the z values were all flat 0.0.

Not sure what to do next, I tried just on a whim drawing only using the green color component (e.g. rgba(color.g, color.g, color.g, 1.0) ) and this came out:

{"name":"610043","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/1\/51736cd62cf09204188e0cbe1b2929b0.png","w":396,"h":250,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/1\/51736cd62cf09204188e0cbe1b2929b0"}610043

Well that's kinda strange. Previously, I was only using the color.a component, since the z-value for the pixel is stored in there (e.g. rgba(color.a, color.a, color.a, 1.0) ). Why now, would the green value just produce a simple gradient? So I investigated further and drew the image with proper colors rgba(color.r, color.g, color.b, 1.0):

{"name":"610044","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/2\/825b3b086a6f53e28185958cf2e761e6.png","w":386,"h":248,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/2\/825b3b086a6f53e28185958cf2e761e6"}610044

Strange again, I'm not sure what's going on in this picture... but... if you look reeeeeealy closely, you can see some very faint shapes in the RGBA render. Very very faint, and they appear to be in the blue part of the image.

:) It turns out, when using an orthographic projection, depth values are stored in the 3rd color component - blue. Instead of RGBA (or XYZD), it's RGB (XYD). It makes sense; there's no need to transform a z value once it's in orthographic projection. The only coordinates you would need are x, y, and depth. So here's the light projection drawn using only the 3rd color component rgba(color.b, color.b, color.b, 1.0).

{"name":"610046","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/1\/a14b6f39d7ecb193a1f67fbdbc024666.png","w":386,"h":248,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/1\/a14b6f39d7ecb193a1f67fbdbc024666"}610046

With a bit of texture position tweaking, the shadow mapping lines up! ;D ;D 8-) 8-)

{"name":"610047","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/e\/dec51f7ad187aadb39c1fb90213509a8.png","w":2144,"h":1468,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/e\/dec51f7ad187aadb39c1fb90213509a8"}610047

When everything is lined up there's really bad "shadow acne" but who cares!! It works!!!

;D

Part 2: Getting Rid of the Noise

The hard part is over, from this point on it's a battle of filtering out shadow noise, and I ended up using a solution of my own (not mentioned in the tutorial).

Quote:

Will you be able to do this [en.wikipedia.org] in real time?

Funny you mentioned that actually. As I was trying to figure out shadows, it was a bit difficult to see what was going on with the checker texture (because of that exact "checker shadow illusion") so I swapped out with a grass texture.

By filtering out for the "shadow acne" noise, at best I was able to get it to look like this:

{"name":"610051","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/b\/9b45cb1f05ba2048a93c64e20f0df9c5.png","w":2144,"h":1468,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/b\/9b45cb1f05ba2048a93c64e20f0df9c5"}610051

and at worst it looked like this:

{"name":"610050","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/c\/1cf54b72c86767024373f9bf21aef071.png","w":2144,"h":1468,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/c\/1cf54b72c86767024373f9bf21aef071"}610050

If you look closely, the worst-case-scenario-stripes-pattern is isolated to geometry that is facing away from the light, so to catch this case I ended up using a combination of plain-old-school shading combined with the casted shadows.

Here's the scene rendered with plain-old-school shading. This uses the light's point as the source and does not have a falloff for distance. Essentially, a plane is brighter when it's facing the light, and darker as it turns away:

{"name":"610049","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/d\/ad5d4226c6e0f5c52458447a0a3b668a.png","w":2144,"h":1468,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/d\/ad5d4226c6e0f5c52458447a0a3b668a"}610049

Then I curve it, so it's either black or white. Anything above 0.5 is pushed to 1.0 and anything below it is pushed to 0.0. Looks like this:

{"name":"610052","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/1\/e1fd1a06674fadabb496d17469aad88e.png","w":2144,"h":1468,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/1\/e1fd1a06674fadabb496d17469aad88e"}610052

Then I combine this shading data with the previous shadow map, using only the darkest colors (works by simply multiplying color1 * color2). Looks like this:

{"name":"610053","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/d\/ddf07087cf8e8fcc09def2f6e4e252d2.png","w":2144,"h":1468,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/d\/ddf07087cf8e8fcc09def2f6e4e252d2"}610053

All I have to do now is nicely blend the shadow with the normal shading of the scene and...

{"name":"610054","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a38c86de60c12dffc6dd73bc58d82de1.png","w":2144,"h":1468,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a38c86de60c12dffc6dd73bc58d82de1"}610054

...that is the first actual fully properly shadow mapped scene. And, it turns out that when I change the camera's projection to perspective, it worked without a hitch!! ;D

{"name":"610055","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/e\/3e7e0f06aeee66f34b812a9cc7857c9e.png","w":2144,"h":1468,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/e\/3e7e0f06aeee66f34b812a9cc7857c9e"}610055

(notice it renders the skybox now that the projection is perspective.)

Part 3: The Future

I started combining the shadows with different colors, and several different materials and shaders:

video

Things are starting to get serious:

{"name":"610058","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/b\/1b9068ce0865585b9a43c2b6b38083b7.png","w":1642,"h":946,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/b\/1b9068ce0865585b9a43c2b6b38083b7"}610058

;D

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Bruce Pascoe
Member #15,931
April 2015
avatar

That last shot looks awesome. Who knew Allegro could do full 3D (as opposed to 2.5D)? Not me! :)

GullRaDriel
Member #3,861
September 2003
avatar

Mark you rock.

Edit: This really is awesome.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

 1   2 


Go to: