Jibble

Author Topic: Dynamic Shadows in AGS - idea for module  (Read 819 times)

Cassiebsg

  • Cavefish
  • Fleeing the Cylon tyrrany...
    • Cassiebsg worked on one or more games that won an AGS Award!
    •  
    • Cassiebsg worked on one or more games that was nominated for an AGS Award!
Re: Dynamic Shadows in AGS - idea for module
« Reply #20 on: 05 Feb 2020, 18:28 »
People keep saying, not to focus on the limitations but look for the possibilities instead.  ;)
There are those who believe that life here began out there...

TheManInBoots

  • Epically wrote function to declare an int
Re: Dynamic Shadows in AGS - idea for module
« Reply #21 on: 05 Feb 2020, 19:31 »
Most obviously, the vertical scaling of the wall shadow is not correct. Assuming a distant lightsource and a vertical character, the shadow cast on a vertical surface will be exactly as tall as the character.
Yes, and they ARE in my illustrations.
So all of the vertical scaling is correct.
I think you didn't understand my illustrations.
Whenever you set the angle to 90 degrees (meaning the distant light source shines on the the vertical character in a linear way parallel to the ground) the shadow is as tall as the character.

(Also, consider how it works if the shadow is cast sideways.)

My model is close enough to reality.
It's a 2D assimilation.
In certain cases you might use the side view frame maybe.
But okay, if you want to have a perfectly realistic shadow then you should create a 3D model of the character sprite and calculate the shadow from a sideways angle and create a 3D model of the room to project the shadow on.
Sounds easy enough to do with AGS lol.

Well anyways, if you don't have time for it then there's no point for me to suggest ideas. It sounded like you were interested to do it that's why I shared it.
« Last Edit: 05 Feb 2020, 20:03 by TheManInBoots »

Snarky

  • Global Moderator
  • Global Moderator
  • Mittens Lord
  • Private Insultant
    • Best Innovation Award Winner 2018, for his numerous additions to the AGS open source ecosystem including the new Awards Ceremony client and modules
    • Snarky worked on one or more games that won an AGS Award!
    •  
    • Snarky worked on one or more games that was nominated for an AGS Award!
Re: Dynamic Shadows in AGS - idea for module
« Reply #22 on: 05 Feb 2020, 22:03 »
Most obviously, the vertical scaling of the wall shadow is not correct. Assuming a distant lightsource and a vertical character, the shadow cast on a vertical surface will be exactly as tall as the character.
Yes, and they ARE in my illustrations.
So all of the vertical scaling is correct.
I think you didn't understand my illustrations.

Whenever you set the angle to 90 degrees (meaning the distant light source shines on the the vertical character in a linear way parallel to the ground) the shadow is as tall as the character.

(The shadows in the scene are eyeballed, so they may not be quite accurate.)

This bit is wrong:

As before, now we place the shadow sprite on the X-intersection value with the baseline.


But this time, before shearing the lower part as we did for the x-axis, we will SCALE the shadow sprite first! But only for the y-value! We basically "squish" or negatively stretch it.
And we stretch it until it has exactly the height of the y-angle intersection point:



(I assume one could use the same code as the engine uses for character scaling, but do it only for the "y-lines" and not the "x-lines")

Once this is done, we shear the part below the baseline like we did for the x-axis.



And voila! The shadow is finished.

You're not supposed to "squeeze" the height of the shadow: the shadow of a vertical object on a vertical surface will not be distorted, regardless of the angle of the light (assuming the light-source is infinitely distant, and considering the object to be "flat"). It's just offset.

Imagine that the floor is glass, so the full shadow is cast upon the wall, as in this simple diagram:



Because the light is parallel (infinitely distant source) and the figure is parallel to the wall (both vertical), the shadow on the wall will be just as tall as the figure. No squeezing.

(Also, consider how it works if the shadow is cast sideways.)

My model is close enough to reality.
It's a 2D assimilation.

Perhaps it's close enough in some cases, but I think it's going to break pretty badly when, for example, the light comes from the side and shadows fall on a side wall (angled to the observer):



(Edit: Imagine the character walking from the left towards the wall on the right. In your model, the shadow on the wall will start off as an extremely squashed version of the sprite, then will gradually be stretched vertically as the character approaches.)

That's why I think something a bit more advanced (Edit: not even really more advanced, just more correct) is needed, though certainly not full 3D.
« Last Edit: 06 Feb 2020, 07:41 by Snarky »

eri0o

Re: Dynamic Shadows in AGS - idea for module
« Reply #23 on: 05 Feb 2020, 22:26 »
(I have an unreleased 3D math module if you need  to calculate stuff)

TheManInBoots

  • Epically wrote function to declare an int
Re: Dynamic Shadows in AGS - idea for module
« Reply #24 on: 06 Feb 2020, 13:17 »
Okay, I understand now what you're talking about Snarky. And you're right.
But it would be quite easy to adjust that in the method I proposed.

I'll explain it in geometrical terms, because I think it's easier to understand:

You simple move the entire shadow shape down to the intersection point:



And then you stretch only the lower part below the "shadow area" ("SA") baseline and shear it:



So that is easily solved and gives a perfect shadow shape for horizontal SA baselines.


Now for the angled walls, I tried it out:

With the method I initially proposed, you would get this result in your example:



If now you only stretch and shear the part below the SA baseline, and leave the upper part unstretched you get a similar result:



It is better and more realistic though, definitely.

However, I noticed another flaw in the method I proposed.
Since the wall is so angled, the shadow shape on the vertical wall should actually decrease it's width, since you look at it on it's angle.
Since that is not included, you can see that the legs are not fitting together on the vertical and horizontal SA:


So, there should be a stretching width wise (or on the y-coordinate, skipping x-lines) of the vertical shadow shape, depending on the angle of the wall. In the example, it would already look better:


But the legs are still not completely aligned. And that is because the gaps between the two legs, or the two arms and the body would slowly dissapear, the more the light comes in from the side. Because essentially the two legs, and the arms and the body, are more and more on one level now, from the light's perspective.
So you could create a similar effect of decreasing the gap by removing more gap pixels, the bigger the angle is. (the program could recognize a gap pixel when it runs through every x-value of the y-line. It reaches the first black pixel for one x-value. Then it reaches the transparent pixels. If after that for a higher x-value it reaches a black pixel again, then the transparent pixels before that and after the last black pixel count as "gap pixels".

Removing the gap pixels would make the vertical shadow look perfect in the example:



Side note on removing gap pixels:
Spoiler: ShowHide

It could also be possible to draw the turned character mask shape or import the mask shape unto the shadow shape, and add the turning axis.
It would not be all that complicated for the program to calculate the steps inbetween to make it look like the character is turning.

END OF SPOILER
___________________________________________________________________________________________________


Now you could also add an addition that when the wall's angle surpasses 45 degrees for example, that the module does not use the character's current view frame, but the view frame ID of the adjacent loop. This way you would have a perfect side shadow.

To illustrate:

You are using the side view as the shadow, and move it to the intersection point:



Now all you have to do is shear the part above the SA baseline (and not stretch it's height ;) ), and stretch it's width negatively, as I explained above.
And then all that is left to do is shear the lower part into place:



Looks good enough to me.

However what I noticed is that with such a strong wall angle you can't only shear the y-lines of the part below the SA baseline. The best result I got when shearing the y-lines only (and stretching) was:



Not exactly perfect, I know.
So you actually have to shear BOTH y-lines AND x-lines at the same time, and not stretch the lower part. Which makes it more complex to calculate the amount of shearing necessary. (Because shearing the y-lines completely changes the outcome of the shearing of the x-lines and vice versa). However it creates the perfect shadow shape.

That knowledge for double shearing might be useful for you, even if you'll use a different system.
Anyways, since you said you want to use a different system to create shadows, I'll leave it with that and leave you to it.
« Last Edit: 06 Feb 2020, 14:10 by TheManInBoots »