Jump to content

Dynamic Lighting with Spriter animations


Trixt0r
 Share

Recommended Posts

Hey guys,

I created this thread to let you discuss about the here mentioned topic, since this is not really Spriter feature related.

Anyway, I tested the shading stuff with Spriter and pre rendered/generated normal maps. I used tombmonkey's flower girl for the tests (sorry tombmonkey, but the ZIP file, you provided, has not normal maps for every sprite. In addition your program (Crazy Bump, I think?) removed the alpha channel for the normal map, which would end up in some very ugly rendering. So I had to create my own with ShaderMap 2. But those which you uploaded are much better and smoother than mine. Maybe you could add the remaining if you've got time.)

And here you have some screenshots:

First of all the scene without shading:

64jk.png

And here is the same scene with some lights and a dark environment:

pxn6.png

r9ol.png

ozaj.png

yktg.png

da5c.png

As you can see it does not look very good because the character was not designed for dynamic light rendering and the normal maps are really shitty.

It looks like an emboss effect.

What do you think?

Maybe we could create some other scenes with different art styles and proper normal maps.

- Trixt0r

Link to comment
Share on other sites

I don't think I can spare time to make height maps for all the images, since I'm already crunching hardcore to try and get a project finished before the year is over.

I made enough maps to complete the standing and walking animations, I didn't know normal maps required alphas, can't you make normals using the height maps in the files? I painted them to get a volumetric look, and they certainly looked well in crazybump preview window.

iIvC5iwwRqSiN.jpg

The effect is good even when normals where made from just 1 height map.

Or, could you just load the head normal map and place the head spinning alone with a couple fixed position lights so we can see if in fact the normals adapt well to rotation. In your example this is not clear since the light is always the same, and the normal mapping is a bit confusing.

I'm sorry for being a pest, but I'm on the fence if I should back sprite lamp since I'm on the poor side and I can't afford to buy stuff I won't end up using.

If it actually works like you suggest and it can be used with skeletal animation then we are in for some crazy looking stuff coming from indies.

And bwwd seriously, if you are not interested in this, just stop posting about it.

Link to comment
Share on other sites

I didn't know normal maps required alphas

Sorry that I did not notice you about that. In general normal maps do not require an alpha channel. But if you make animations with Spriter and sprites which have an alpha channel you do not see (or do not care about) how the rectangle of your sprite overlaps with another sprite which is drawn below. Now if you draw the same normal sprites to your normal buffer in your engine and your alpha channel was not preserved when generating the maps your resulting image on the normal buffer will look different than the color/diffuse buffer because now you have some blue-ish color values (i.e. the z-value of the surface normal) where some transparency should be.

Ok, I made a little rotation test for the head with your normal map, tombmonkey:

q0tr.gif

Looks much better than mine. :D

I think it should be done differently, similar to rayman legends, so if theres lihgting then it reveals second map and blends between lit and unlit body part.
I do not get what you mean. Rayman Legends uses standard illumination models with some more advanced techniques (area lighting, etc.). I would not discuss about those things here.

This thread is meant to be a place to discuss about illumination and cut off animations in general. What Ubisoft's engine is doing in Rayman goes beyond this whole stuff.

not sure how to implement this in a construct 2 platformer environment, any tips would be greatly appreciated
I started with this little example. If you get how the vector calculations work, you can go further and involve an angle into your shader program and rotate the vectors from the normal map. It is very simple compared to the normal mapping in a "real" 3D space, where you have to calculate tangentspace matrices and stuff.

Edit: Using proper normal maps can lead to very very nice visual effects:

- Trixt0r

Link to comment
Share on other sites

While I see the potential of dynamic lighting through normal maps, I am not yet convinced. I tried to like it for 2D art, but it does feel a bit computer generated (not just the examples shown here)...and that is just not a look I'm very fond of. I know this can be solved spending more time on the normal maps, and some different lighting algorithms. But I just wanted to raise my concerns.

I also have to say that for my particular art-style, I think 'simple' rim lighting would suffice. When you look at this image (I'm linking to a copy on the internet and hope Double Fine won't mind) you see the results of hand-drawn rim lighting that is subsequently added to the character based on the location and colour of the lights. I also think this would be a bit easier to calculate on mobile devices than full normal mapping.

I'm not saying rim lighting is the way to go, and that normal maps are a waste of time. It was just something I wanted to bring into the mix.

I do wonder how best implement normal maps with modular animation. Simple use-case: I have a nose on my face. The nose is a separate object (for whichever reason). How would I ensure that a. the heights of the nose and the face match up, and b. how would I make modules cast shadows upon other modules (nose on face)? - Otherwise the perceived depth might break the illusion.

just some thoughts...

Link to comment
Share on other sites

Trixtor that looks balls awesome.

And the cell shaded example you posted, with sprite lamp that would be easy as hell to do. Maybe next year when sprite lamp is out we can make a small game to show off this tech with spriter in a more complete way.

Misj, the reason there aren't many examples of 2D art using normal mapping is simply because it's too hard to generate a decent normal map from a 2D image with current tools. if I needed to make a good normal for a 2D image I would need to start by painting an height map, then taking that height map into zbrush to develop it further and then output a normal map, this whole process is way WAY too long, and it's mainly the reason no one does it. Also, there's this thing where most of the examples out there have programmer art, and usually a single light with no ambient, which lead to things that don't look aesthetically pleasing.

With spritelamp and skeletal animation we are bound to see some crazy stuff surface, obviously characters need to be designed to make use of normal mapping and dynamic lighting, and then there's the thing of setting up the lights which is an art on itself (there's people specialized solely on this) but with proper usage and some artistic sensibilities there are awesome things waiting to happen.

Link to comment
Share on other sites

Misj, the reason there aren't many examples of 2D art using normal mapping is simply because it's too hard to generate a decent normal map from a 2D image with current tools. if I needed to make a good normal for a 2D image I would need to start by painting an height map, then taking that height map into zbrush to develop it further and then output a normal map, this whole process is way WAY too long, and it's mainly the reason no one does it. Also, there's this thing where most of the examples out there have programmer art, and usually a single light with no ambient, which lead to things that don't look aesthetically pleasing.

I do like the idea behind spritelamp, I think it's closer to the artist's workflow. It is just too early for me to be confident...

When it works I'll be all for it, as I see some nice possibilities. I'm just not sure yet.

Link to comment
Share on other sites

[...] but it does feel a bit computer generated [...]
Of course because those maps are computer generated :D. No one has time to make normal maps by hand.
[...] I think 'simple' rim lighting would suffice [...]
Yeah, I am using such a rimlight technique in my current LibGDX engine inspired by this post (sorry for reposting my videos...).
I do wonder how best implement normal maps with modular animation. Simple use-case: I have a nose on my face. The nose is a separate object (for whichever reason). How would I ensure that a. the heights of the nose and the face match up, and b. how would I make modules cast shadows upon other modules (nose on face)? - Otherwise the perceived depth might break the illusion.
For a.: It is quite easy if you think in 3D (because every common lighting model works with 3 dimensions, it does not matter how many dimensions (2 or 3) your rendering engine is using). Give your nose and your face different z values and the rest will be done by the illumination model in your engine.

For b.: Casting/mapping shadows is engine related and as an artist I would not worry about the implementation stuff (I did not implement it yet, but I think it is not that hard).

Maybe next year when sprite lamp is out we can make a small game to show off this tech with spriter in a more complete way.
I am ready for it. ;D
That ryu looks better but hes not moving so its easier[...]
It makes nothing easier. You still have to create a normal map for that sprite and the effort is similar to the one you have if you would use sprites which are composed of different bodyparts. And the effort gets equal if you use a texture atlas for all your bodyparts.

I do not understand why you guys worry about dynamic/realistic lighting combined with bone based sprite animations? If you have well fitting normal maps the resulting visual effects will please you as hell :D. Maybe I underestimate the workload for creating normal maps by hand, but to solve this problem: Sprite Lamp is coming... I am looking forward to this peace of software.

- Trixt0r

Link to comment
Share on other sites

[...] but it does feel a bit computer generated [...]
Of course because those maps are computer generated :D. No one has time to make normal maps by hand.
Maybe I underestimate the workload for creating normal maps by hand, but to solve this problem: Sprite Lamp is coming... I am looking forward to this peace of software.

This is what I find the most interesting of spritelamp...it would allow me to easily create artistic normal maps. If those are done right, all my reservations go away (although artistically I prefer ambient lights with highlights and minor shadows over dark due to the absense of light...but that should be achievable with the right shaders and ambient lights)

I do wonder how best implement normal maps with modular animation. Simple use-case: I have a nose on my face. The nose is a separate object (for whichever reason). How would I ensure that a. the heights of the nose and the face match up, and b. how would I make modules cast shadows upon other modules (nose on face)? - Otherwise the perceived depth might break the illusion.
For a.: It is quite easy if you think in 3D (because every common lighting model works with 3 dimensions, it does not matter how many dimensions (2 or 3) your rendering engine is using). Give your nose and your face different z values and the rest will be done by the illumination model in your engine.
But would that work when dynamically reordering parts? - Would that require dynamic z-values, or could we use the z-order to correct this?

On that note...would the light be applied on each part separately or on a pre-constructed character. Yes, I know this doesn't matter from an artistic point of view, but it does matter...

Link to comment
Share on other sites

But would that work when dynamically reordering parts? - Would that require dynamic z-values, or could we use the z-order to correct this?

Yes it should work. I do not know what you mean by "could we use the z-order to correct this", but it would work with the z order you use in Spriter. How far the z index 0 is away from z index 10 depends on the engine itself. I would just use a factor to control those z indices and distances. For your example let's say the nose is on z index 5 (above the face) and the faces has a z index 1. The distance between the z values should be then:

zDistance = (nose_index - face_index)*factor

let's say factor is 0.01 (how big this factor is depends on your camera properties, etc.) then you get a distance of 0.04, and the face has a z value of 0.01 and the nose 0.05. The distance can be taken e.g. for some shadow mapping (if the distance is bigger than 0.06 do not apply shadow mapping or something like that...) and the z value itself is lateron useful for your lighting, e.g. for illuminating only sprites in the background, etc..

On that note...would the light be applied on each part separately or on a pre-constructed character. Yes, I know this doesn't matter from an artistic point of view, but it does matter...

This depens heavily on the engine, you use. Because if your engine uses forward light rendering, every light calculation is applied to each sprite. If you use deferred light rendering the illumination stuff has to be calculated from a geometry buffer (a group of different textures your engine renders to) which contains all the information (positions, colors, normals, etc.) you need to make the lighting happen. And this g-buffer contains your whole scene you can currently see, i.e. all your characters which get animated (or anything else that can be drawn). The drawing happens then in 2 steps: render to the g-buffer and then render the illumination stuff to the screen with the g-buffer.

I hope this clearifies some things :D

Edit: The guy who made the cel shading with the ryu sprite posted a link to the resources. Looks like he is using a similar technique Sprite Lamp is using. For those who are interested in how the lighting would look like with a non cel shader, i.e. lambert shader:

gmlg.png

I think it looks good, much more 3d-ish, but the cel shader fits better to the art style (I am using the same normal map the dude is using in his video, so the lighting has nothing to do with the normal map itself).

- Trixt0r

Link to comment
Share on other sites

75ee.jpg

I was studying the files from the Ryu and I say it was very smart the way he generated the normal map.

I must admit I didn't understand how normals worked, I thought they where these magical things that only 3D software could make, after reading about them on polycount and seeing this example on how the channels are mixed I can say with confidence that I could paint some pretty good normals without needing sprite lamp.

I wish the people from sprite lamp would post the normal map for the goat and the plague doctor on their kickstarter, since the software seems to do little more than auto mixing the images.

Trixtor

I have this very simple spriter character from a personal project lying around, I will try to find time to paint normals for it in the following week and maybe you can load it and we see how it looks?

Link to comment
Share on other sites

Hey guys.

I implemented a little command line tool with Java which is able to create a normal map from two given textures which represent a sprite lit from the right and from above.

In the zip file are two executable jar files which work slightly different. normalsGeneratorTwo.jar uses the mathematical right algorithm to create the normals but the other jar produces a better solution in my opinion.

To run it you should update your Java runtime environment to 1.7. Call the tool from the command line (on Windows from cmd.exe, on Unix from the console).

The usage is:

java -jar normalsGenerator.jar nameOfTheHorizontalLitTexture.png nameOfTheVerticalLitTexture.png outPutName.png

The last argument is optional, if it is not given the tool will create a file named "normalMap.png".

Edit: tombonkey, yeah sounds good. I have to do some other works for university in the next weeks (until Christmas) but I will try to test it if I have time.

Edit2: Added file, sorry :D

- Trixt0r

normalGenerators.zip

Link to comment
Share on other sites

Im trying to make this with construct 2 but is difficult with the plugin that i have

I didn't know normal maps required alphas

Sorry that I did not notice you about that. In general normal maps do not require an alpha channel. But if you make animations with Spriter and sprites which have an alpha channel you do not see (or do not care about) how the rectangle of your sprite overlaps with another sprite which is drawn below. Now if you draw the same normal sprites to your normal buffer in your engine and your alpha channel was not preserved when generating the maps your resulting image on the normal buffer will look different than the color/diffuse buffer because now you have some blue-ish color values (i.e. the z-value of the surface normal) where some transparency should be.

Ok, I made a little rotation test for the head with your normal map, tombmonkey:

q0tr.gif

Looks much better than mine. :D

I think it should be done differently, similar to rayman legends, so if theres lihgting then it reveals second map and blends between lit and unlit body part.
I do not get what you mean. Rayman Legends uses standard illumination models with some more advanced techniques (area lighting, etc.). I would not discuss about those things here.

This thread is meant to be a place to discuss about illumination and cut off animations in general. What Ubisoft's engine is doing in Rayman goes beyond this whole stuff.

not sure how to implement this in a construct 2 platformer environment, any tips would be greatly appreciated
I started with this little example. If you get how the vector calculations work, you can go further and involve an angle into your shader program and rotate the vectors from the normal map. It is very simple compared to the normal mapping in a "real" 3D space, where you have to calculate tangentspace matrices and stuff.

Edit: Using proper normal maps can lead to very very nice visual effects:

- Trixt0r

Link to comment
Share on other sites

  • 10 months later...

Hey guys, I know this topic has been inactive for a while.

But I've got some work in progress that I'd like to share.

I am working on a tool that automatically generates Normal Maps with only a sprite file as the input image.

Of course, the resulting Map isn't as perfect as a hand drawn one, but in cases where you have a large number of sprites, like animation frames or body parts of a character you want to animate with a tool like Spriter, the quality should be good enough.

This is the Normal Map, Depth Map, Ambient Occlusion Map and Specularity Map, that my Tool (Sprite DLight - hopefully soon on Kickstarter) produced from the original sprite in a matter of seconds: (downscaled from 512x512px)

Ryu_Sprite_DLight_Maps.png

Seems like the original hand painted normal map's Red Channel was inverted. My tool also has various fine tuning options like Inversion of the Channels, Intensity and Volume Boost Sliders and a lot more.

If somebody has an atlas of bodyparts for an animated character he wants to try out with dynamic lighting, you can send me your art and I can see if the tool can generate a nice normal map for it.

Link to comment
Share on other sites

  • 2 weeks later...
  • 3 weeks later...

The Kickstarter of Sprite DLight can now be previewed here:

http://kck.st/1vVwkRs

There is an example for dynamic lighting + skeletal animation in the video. It has been done with Spine, but things should work for Spriter in a similar way.

On the Construct 2 Forums, there is also a discussion, involving C2 and Spriter integration with normal maps: https://www.scirra.com/forum/sprite-dli ... rt_t118649

TLDR version:

Sprite_DLight_Infograph_KS.png

Launch will be next Tuesday.

I'd love to try processing some art made for use with Spriter.

It would be amazing to combine these two technologies.

Link to comment
Share on other sites

I'm quite impressed that you managed to implement an algorithm which is able to calculate such an accurate normal map just from a single (diffuse? the pumpkin is already shaded) texture.

There are already tools like Crazy Bump out there, but they do not create such a good normal map for 2D sprites and are only useful for textures like walls, floors, etc.

I would like to see your tool in action.

Will it be for free?

Is there already a demo application available?

- Trixt0r

Link to comment
Share on other sites

Thanks a lot, Trixt0r.

In case of the pumpkin example, the normals were calculated from the shaded sprite. Working with diffuse textures is also possible, as the tool has a volume boost that 'inflates' flat shapes.

In the skeletal animation example in the video, the body parts were based on vector art which consisted of flat shapes, and the resulting normal maps turned out well.

The tool won't be for free, as you can see on the Kickstarter page preview, but the prices are even far below other (less powerful) normal map generators.

There is no demo yet, but backers will be able to participate in beta testing shortly after the end of the campaign.

Link to comment
Share on other sites

Hi Dee,

 

Its great to have you in the forum and Sprite DLight looks awesome. It's definitely impressive it generates such great looking normal maps automatically.  We're going to look into implementation on the Spriter/C2 side, but can't until we take care of a handful of other things first, so it will likely be a little while. 

 

Cheers,
Mike at BrashMonkey

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...