Looks nice. Can you talk about the shadows a bit more? Is it now shader based or what’s the “trick”?
Actually, the new system is just a semi-complex system that detects tiles on the map and renders the correct shadow in it’s place to a big FBO, then lowers the alpha level and outputs the FBO to the screen. So in a nutshell, I’m hand drawing the shadows and rendering them to an FBO. Without some kind of height map, there’s really no way to get the detail needed to make the shadows realistic looking without just drawing them.
Sadly, they no longer move. It took me a while to settle with what I have now, but I opt’ed for more accurate looking shadows than having moving ones. If I were to make them move I’d of lost a ton of detail during transformation (I’d probably draw them facing down, then warp the bottom left and right corners). But doing that wouldn’t allow of nearly as much detail in the end because I pretty much would only have detail on the bottom and top of the shadow, the sides would end up a little strange looking. If I went that route I’d probably re-rewrite the system and just do a proper raycasting system. But I don’t think that look would be good for RPC.
But, they will darken and fade based on time of day. The code is already in place, but I plan on redoing some of my clock code, so I haven’t enabled that part yet.
I do have some ideas for a “height map” system though, but I may try that later down the road. If my height map system idea would work. I could get the hard shadows and the accuracy I need, and still have them move based on the time of day… the problem comes from trying to figure out how to render said system extremely quickly, because of all the objects that will cast shadows eventually.
That’s a pity… Those shadows gotta move
I’ve been pondering ways to use a height map, I might give it a try. The coding side really isn’t that complicated for my idea to work, it’s really just a matter of figuring out how to do it quickly. But, many people have been concerned with the shadows no longer moving, maybe I’ll push my priorities up a bit and see if I can make it happen.
Gah, that’s very, very, similar to the idea I had in my head. Although his way is actually more complicated than my way needs to be. But the core idea is the same. I was going to use a gray scale height map of the tile, and based on what shade it was (lighter = higher) would tell the code how far out to draw each of the “shadow pixels” in whatever direction the sun is facing. His way seems to pretty much do that. Although his math seems a bit more complicated than it needs to be IMO. but he is accounting for a lot more than I need to, mainly a orthogonal environment.
Still though, bookmarked! Thanks.
With the comments from everyone disappointed that my new shadow system is no longer dynamic, I think I’ll go ahead and put forth the time to make it happen sooner than later.
and the triple-reply award goes to Rayvolution, to show off the first working version of dynamic hard shadows!
Nice. Did you do something similar to that article or was it something simpler like heightmap and raycasting?
I went with my original plan I had before seeing the thread.
What I did was made a grayscale heightmap of the object I want to cast a shadow, then internal to the shadow class I have a shadow builder that reads the map and splits up the various parts of the shadow (based on color on the grayscale) into separate images (kinda like slices of the building).
Then, I took those images and rendered them to a FBO, and re-rendered it out by +1, for as many times as that slice required in whatever direction they were being told to go. For example, if slice 10 was rendering, it would render itself 10 times each time moving out 1 pixel in whatever direction it was told to based on the time of day. Where as slice 5 would only “move out” 5 times. Slice 15, 15 times, and so forth. So what happens is the higher number slices (or the slices generated from the brighter colors on the height map) would push out longer distances.
Considering how many times I am rendering and re-rendering slices in a single FBO, I expected it to murder my frame rate, but to my surprise even calling the entire shadow rendering method 4 times per cycle (only normally gets called once) I am still running at 60FPS so far. But, I haven’t finished drawing all the shadows. There’s a chance it may run a bit too slow once all the shadows are put back in. We’ll see I guess.
That’s clever at least in it’s simplicity, if not efficiency. Whatever works though.
We’ll see if it’s really efficient enough once I get all the shadows done. I hope it is, because these results look a lot more natural/realistic than raycasting usually does in 2D games.
“It’s a bold strategy Cotton. Let’s see if it pays off for him.”
Ray, I’d be lying if I said I fully understand what you are doing here, so I may be jumping the gun. However instead of re-rendering each slice by the number of pixels it is required to project itself, couldn’t you scale the slice by the required amount in the required direction? As such you will only have to render it once (assuming the slice is an individual texture).
I envision that it would be something like:
- Create a 2d vector in the direction of the sunlight, with the magnitude of the vector related to the time of day.
- Scale the shadow slice by this vector multiplied by the height of slice.
- Render.
Does that fit the situation or have I missed the mark?
That sounds similar to something I was going to attempt actually.
The actual problem though is what it’ll look like. Since I’m dealing with pixel-art, LWJGL and Slick really suck at using image translations in scaled graphics and keeping them “pixel perfect”. Even when you properly scale your graphics, they still allow you to render things “between” the scaled pixels, including transformed images. For whatever reason that just seems to be how LWJGL/Slick do things. So the transformed shadows would end up not looking pixelated like the rest of the scene. That’s why I opt’ed for this way.
Here’s an example: (I used rotate, but the effect is the same either way)
The dark black shadow is the fake shadow, showing how it would look if I distorted the slice, the left is the current one.
Are you forcing your images to be GL_NEAREST?
Are you forcing your images to be GL_NEAREST?
Of course
Then you should be able to scale your images so that they stay pixelated, unless Slick does something behind the scenes. (Or I just don’t understand your problem completely ;))
Either way, very good work!
Ahh I’ve got you. My suggestion would be to render the shadows to a lower resolution texture/FBO, and then render this texture in the scene to maintain the pixelated effect.
Ahh I’ve got you. My suggestion would be to render the shadows to a lower resolution texture/FBO, and then render this texture in the scene to maintain the pixelated effect.
Hmm, I suppose that could work actually. All the non-FBO related transformation don’t really care about the resolution, it just outputs the texture. (thus, the effect in the image I linked). I might play around with it later then. Right now the shadows are running at a solid 60FPS anyway so I wasn’t really too concerned with optimizing it more quite yet.