Pixelation

General => General Discussion => Topic started by: PixelPiledriver on May 21, 2012, 10:15:16 pm

Title: Pixel Shaders
Post by: PixelPiledriver on May 21, 2012, 10:15:16 pm
The purpose of a Pixel Shader is to control the color of a rendered pixel.
Read this if you are unfamiliar with the topic (http://en.wikipedia.org/wiki/Shader).

I've taken interest in writing a 2D lighting Shader.

Lighting depends on many variables.
But as a massive simplification it depends on 2.
Surface direction (normal) and light source position:
(http://www.john-chapman.net/tutorials/per_pixel_lighting/images/fig2.gif)

In 3D art getting a normal is easy.
The data is already there as it is essential to how it is rendered.
But 2D art is different.
Altho we can find the normal of certain pixels, like the outer edges, there is no "physical" axis.
Surface normals are created by the artist and kept consistent only by choice.
It's exactly this sort of constructed fakeness that keeps me interested in art.
My purpose is not to replace per pixel artistic decisions of color.
It is to add another layer of control to a sprite that is interactive in a game engine.

We can represent direction as a color.
This is commonly thought of as Normal Mapping.
We can use an extra map to light a 2D image.

So first I had to figure out what kind of axis to pull data from.
I started with a 2-axis format:
(http://4.bp.blogspot.com/-0Omx8Yx41Tc/T7qMvnMyQ-I/AAAAAAAABdQ/w2ZkGmFYQSA/s1600/2axis.png)
This had some appealing results (which are lost, forgot to take screenshots), but I felt the control was a little off.

Then I tried using a quadrant method using the Blue channel to determine quadrant.
(http://1.bp.blogspot.com/-MEk-7QJrmxU/T7qM2RanJiI/AAAAAAAABdg/eywp2_kOSXc/s1600/quadrants.png)
The idea was to make it easier to find direction.
But I found the setup annoying to work with and abandoned it pretty quickly.

Having a third access could remove the need for quadrants.
My first thought was to use this 3-axis setup:
(http://4.bp.blogspot.com/-Z3HvpmwWUlw/T7qcDfJOoMI/AAAAAAAABd0/Rx6o77EzYUM/s1600/diagnol+axis.png)
It reminds me of Barycentric Coordinates (http://en.wikipedia.org/wiki/Barycentric_coordinate_system_(mathematics)) and therefore has some interesting properties.
It could have worked but I tried to look for other answers.

Then I came to this 3-axis setup:
(http://3.bp.blogspot.com/-_AmpgzyWcYs/T7qahkM6TLI/AAAAAAAABds/AE6Gm7MwAgk/s1600/3axis.png)
It has direction and matches how we traditionally think of a 3D axis making it easier to think about and use.
This is what I'm using now, and it works well.

So here's the progression of getting the base code to work.
I'm writing this from scratch and tweaking it to my needs.
The light source was from the mouse position so I could move it around and see changes quickly.
Old stuff and mistakes towards the top, new stuff and properly working towards the bottom.
(http://4.bp.blogspot.com/-Ptq5Uhr9V8M/T7mT9ZiU1dI/AAAAAAAABcQ/SgT_31vDfDg/s1600/2DLightingProgression.png)

The idea is to draw a normal map by hand.
Reducing the number of colors makes surface direction more apparent.
It's easier to grab from and stay consistent.
(http://1.bp.blogspot.com/-ABTSfcObfYI/T7q5uIonnTI/AAAAAAAABeM/oGfP5RPigb4/s1600/axisColorCount.png)

Manually drawing the normal map, such as the "brick" pattern on the sphere, in theory seems crazy.
But it ends up having really interesting and appealing results despite the fact that its a normal map defined with solid color lines.
(http://2.bp.blogspot.com/-6LqWGgvfFv8/T7q2c4ZlKKI/AAAAAAAABeA/TKZ8q1kyU7E/s1600/brick.png)

Here's some more test results using a sprite and 3 different types of normal map:
(http://2.bp.blogspot.com/-ZgZp7DjtGB4/T7qI1xu85kI/AAAAAAAABck/crDTkdtTSKE/s1600/ppdLightingTest_1.png)

Using multiple spheres for normals creates a crapload of distortion, but it's quick and easy to setup.
The last row is starting to actually look decent, even though it uses the multi-sphere normal map.
It's a bit too subtle but its also much more noticeable and cool when it happens in realtime and changes based on position.

Manually painting the normals has much more potential (and is my original goal of coding this) but I have not yet taken the time to make a really nice map.
That'll be my next test, probably on something static.
Obviously it's less expensive to use on static assets but is still doable for animations.

There's still a lot of work to do.
Even if you're not a programmer feel free to comment.
It could lead to a much better shader or other features.
Title: Re: Pixel Shaders
Post by: Conzeit on May 22, 2012, 02:07:21 am
wow, what an interesting idea  ;D

hmmm first thought in my head is you might want to program for the possibility that some people might not be going for a realistic representation of light, even if you're doing celshading you might want to give a sense of backlighting or fill lighting

http://udoncrew.deviantart.com/art/Fighting-Evolution-GUILE-53508437 This example I think shows well some (almost) backlighting with the sunlight, and the fill light towards the botton of the figures. I think most people would want to aproach this as a real-time photoshop filter, so it should be suitable for different aesthetics, or even maybe for making light completely unlike light. I think sometimes one of the coolest thing about 2D art is how meticulously light sometimes defines features when real light would never do such thing.

Now, to comment on the aproach that got the best results, it might be a good idea to be able to feed the program an outline and tell it these are the edges of the figure. For example imagine you feed your Princess'es outlines, from that the program can fill in the rest of the figure trough embossing around those edges, making a product somewhat like your spheres normal map,  then from there you can just adjust which parts are actually in front and which are towards the back by bringing them forward/backwards like you would with any photoshop layer or any layer based program.


I have no idea wether that made any sense to anyone but me but I hope it gives you some kind of inspiration atleast :p

BTW, thinking about making something 2d into 3d reminded me of the way photoshop uses depth maps to produced displaced images, and people use that to make stereoscopic 3d pictures. That spawned two thoughts 1-why arent you using depth maps to produce the normal maps? 2-you might want to look at photoshop tutorials on displacement maps to get some ideas for how artists usually think of 3difying a 2d image.


PS: You've been making some truly incredible crits on animation, way back when I used to be the only one who cared to make animation crits but I never had the experience or generosity to make crits as rich and helpful as those you've made (making screenshots of every little step to get Ggale to your animation bidding is what I call generosity).

I'm glad I get to see you inject so much life into good ol pixelation =)
Title: Re: Pixel Shaders
Post by: Tourist on May 22, 2012, 03:03:21 am
It looks like you're reinventing Zbrush.  Zbrush is mostly 3d and surface modeling these days, but it started with 2d brushes that painted pixels with surface normals.  Or maybe just a z-buffer that was used for real-time lighting, the effect is the same. 

The user could choose from several brushes, some that would paint flat, some that would build up the image, others that would flatten it down.  These could be combined with various colors or textures so that you could paint a color and height at the same time.  Lighting was separate, and a user could alter the lighting direction at any time.

Here is a link that sort of covers this feature: http://www.pixologic.com/zbrush/features/2_5D/ (http://www.pixologic.com/zbrush/features/2_5D/). 


If you're using software for processing the normals, maybe take a look at these articles.  They were written before pixel shaders were around, so the code might not be useful, but the math and logic are still good. 

http://www.gamedev.net/reference/articles/article1191.asp (http://www.gamedev.net/reference/articles/article1191.asp)
http://www.gamedev.net/page/resources/_/technical/math-and-physics/higher-accuracy-quantized-normals-r1252 (http://www.gamedev.net/page/resources/_/technical/math-and-physics/higher-accuracy-quantized-normals-r1252)

Representing the data as unit normals (where x^2 + y^2 = z^2) might be better than using independent variables.  With independent variables,  x = y = z = 64 has the same normal as x = y = z = 128.  Or just store it as theta and rho (or even cos(theta) and rho), which would front load the calculations but be faster if you were planning to do this real time in a game engine.

Hope this helps,
Tourist
Title: Re: Pixel Shaders
Post by: BladeJunker on May 22, 2012, 03:06:52 am
Well I like the concept and I consider it the next best step up from earlier more two dimensional lighting systems. I definitely think 2D in general should use everything afforded by modern technology like normal mapping and frame morphing, I certainly like what Vanillaware has done.

Drawing normals by hand doesn't sound that crazy to me since its essentially what CG modelers do in terms of surface normals. I definitely think Zbrush and the like would help with creation of such sprite layers. Its hard to say where you draw the line or not as you could probably get better results through CG model rendering with painterly passes afterwards.
Here's someone using CG as a base for sprite creation that could help maybe, basically you create a basic model to get the rudimentary normal map(Possibly with subdivision.)and paint in the more complex stuff afterwards. :-\ Idk, its hard to stick to pure 2D with these more complex demands.
http://forums.tigsource.com/index.php?topic=167.11274 (http://forums.tigsource.com/index.php?topic=167.11274)

Oh and I love that Princess Piledriver sprite work, Id love to play that game. ;D
Title: Re: Pixel Shaders
Post by: blumunkee on May 22, 2012, 04:31:52 am
Good stuff here. Seems like you could generate normal maps from the lightness values of the sprites. They'll probably still need some hand tweaking, but it should still speed up the process.
Title: Re: Pixel Shaders
Post by: API-Beast on May 22, 2012, 05:09:31 pm
Ah, thats something I have thought about too.

For creating the normal maps my idea was to paint a bump map and use a program like CrazyBump to generate a normal map out of it. Needs some exercise to get some good normal maps, I think.
(http://i.imgur.com/Guplw.png)
Another idea would be drawing a layer on top of your sprite with a light from the top in green and from the right in red. But I need to do some experimenting on that.

My concept was instead of having light sources like you have in 3D that you have a "light pass", e.g. that every light source is a sprite and composed into a single layer (additive or maximal blending).
The normal map is then simply a offset for the texel fetch. Red is the offset in X-Direction, Green the offset in Y-Direction (both of course transformed, the example image is using those values in a linear fashion but in dynamic applications something expontial will probably work better). Blue is Z in 3D, but since you don't have that in 2D you can use it for intensity e.g. how much light this pixel receives.

(http://i.imgur.com/3dX0C.png)

(http://i.imgur.com/6tF6u.png)
Title: Re: Pixel Shaders
Post by: Helm on May 22, 2012, 05:50:41 pm
It'd be really interesting if the normals for a sharp, pixel-crisp sprite were also sharp-pixel crisp. And if the lighting was forced to be less gradienty as well. Closer to a flatshaded vector coloring, really. It's difficult to explain what I mean.
Title: Re: Pixel Shaders
Post by: Conzeit on May 22, 2012, 08:49:01 pm
I think we instinctively know what you mean Helm, we pixelartists always want everything to be sharp :p I was trying to get to the same point with my example of the Guile ending comic up there, I think the best way to think of it would be thinking of the shader for this as a cel-shader/toon-shader that has the option to be pixel precise.
Title: Re: Pixel Shaders
Post by: Ryumaru on May 23, 2012, 05:25:53 am
It'd be really interesting if the normals for a sharp, pixel-crisp sprite were also sharp-pixel crisp. And if the lighting was forced to be less gradienty as well. Closer to a flatshaded vector coloring, really. It's difficult to explain what I mean.

This. I love the idea of dynamic real time lighting that still holds some of the pixel aesthetic to it. This stuff is way above my head but it all looks like nice experimentation! would love to see a princess piledriver game with beautiful animations and sexy lighting!
Title: Re: Pixel Shaders
Post by: PypeBros on May 23, 2012, 06:52:22 am
I remember of robotacon trying to do something similar in his arcade academy project (http://www.wayofthepixel.net/pixelation/index.php?topic=4427.msg62287#msg62287). Haven't compared the two approaches yet, though.
Title: Re: Pixel Shaders
Post by: Helm on May 23, 2012, 08:28:27 am
Glad I'm not alone in this. It'd be really interesting to see you attempt this, PP.
Title: Re: Pixel Shaders
Post by: tehwexxl0rz on May 29, 2012, 12:28:03 pm
I would actually advise against using a super crisp shader for the very reason that it's NOT pixel art. As long as it's automated, it can't possibly match the level of polish established by the base sprite. It would only serve to muddy and obscure the manual pixel-level detail.

Rather, I would recommend a soft and subtle effect that might enhance the sense of depth and tie the scene together without interfering with your pixel technique.
Title: Re: Pixel Shaders
Post by: Dusty on May 29, 2012, 02:38:16 pm
Would it help if you upscaled this by like x8 and then did the shading then scaled it down? I suppose this would be taxing in real-time though.
Title: Re: Pixel Shaders
Post by: rikfuzz on May 29, 2012, 03:51:32 pm
Reducing to a specific palette would probably keep it neat. 

Robotacon even experimented with dither patterns (for the backgrounds), I thought they looked really good, wish there were more examples posted in motion though. 

Title: Re: Pixel Shaders
Post by: PixelPiledriver on June 11, 2012, 10:04:57 pm
2 weeks ago I contracted a fairly intense illness.
I'm still feeling the affects and my ability to do work is pretty much 0.
Just wanted to say thanks for all the great replies.
I'll be out for a few and will respond appropriately later.
 :blind:
Title: Re: Pixel Shaders
Post by: Helm on June 11, 2012, 10:47:29 pm
I hope for your full recovery.
Title: Re: Pixel Shaders
Post by: ptoing on June 11, 2012, 10:48:54 pm
Get better soon.
Looking forward to where this is going a lot.
Title: Re: Pixel Shaders
Post by: PixelPiledriver on June 12, 2012, 05:50:28 pm
Thanks guys.
Title: Re: Pixel Shaders
Post by: tim on November 29, 2012, 11:07:04 am
Hello PixelPiledriver.
Have you continued since your last post ? This is very interesting and I'm actually trying to develop it for my game. I want lightning strikes during thunderstorms and the fire torch to dynamically light the surroundings. It should be fairly innovative and impressive in a pixel art game.

Fullscreen pic
(http://www.behindnowhere.com/screens/tree960.png)

Dynamic lighting concept
(for 1:1 pixel art click here (http://www.behindnowhere.com/screens/dynamiclighting.gif))
(http://www.behindnowhere.com/screens/dynamiclighting960.gif)

Basically to make it feel like pixel art I really sharpen and exagerate the normal map so the light is hard and there is no soft blending.