I've written a GLSL shader for use in Unity3D with my pixelated iOS app. It has two ONE problems:
1) The effect doesn't always stay with the moon, and 2) the lighting doesn't look pixelated.
I'll explain a little. The shader is meant to cause a lighting effect on a foreground object when the moon is behind it. I have a sprite which is normally displayed as all black (like a silhouette), but when the moon object is close enough to it, it reveals the details of the texture, like so:
The actual sprite (without the shader) looks something like this:
The reason I am doing the effect this way is so that I can have a lightmap with only one texture. However, there are two problems with it:
1) As I get closer to the edge of the screen, the light effect doesn't follow the moon exactly. I'm not sure if this is related to my incorrect usage usage of the TEXCOORD1 variable. I've made a sprite that covers the whole screen so you can see how it doesn't follow the moon. Here's a picture of the problem in my test scene for the effect. There's a full-screen sprite with black stripes and alpha to show exactly where the effect is at all times. I want to get rid of this desync, because it makes the lighting look unrealistic.
2) The lighting effect caused is very sharp -- It would look better, I think, if each pixel was lit individually, as in SpriteLamp. I know it has to do with rounding the fragment coordinates in the shader, but since I never really know what the values of variables are in my shader, I can't seem to get this to work correctly.
I can round and floor the distance, but then I get this, which is obeying the distance from the moon, but not obeying the pixels in the original sprite. There is pixelation, but we end up with this weird curve across what should be just one pixel, if you catch my meaning...
What I'm looking for is more like this. See how the individual pixels of the original texture is lit?
Here's a link to the shader itself: http://pastebin.com/0zbqrP57. It's the default unity sprite shader, mostly, but with some code added in at the end of the SampleSpriteTexture function.
Here's the link to a unitypackage that you can use to look at the shader in action. Just try moving the moon around while the scene is playing.
https://drive.google.com/open?id=0BxCQjUHiAAQWZGpPZ3R2SExTcXc
MY QUESTION: Do you have any advice on how to solve these problems, or solutions to them?
Changing
OUT.worldSpacePosition = mul(_Object2World, OUT.vertex);
for
OUT.worldSpacePosition = mul(_Object2World, IN.vertex);
should fix moon misplacement.
For second problem I came up with this:
aS = floor(aS * 100) / 100;
bS = floor(bS * 100) / 100;
float dist = sqrt((aS * aS) + (bS * bS));
float percentClose = 1 - (dist / _LightStrength);
float rounded = floor(percentClose * 10) / 10;
if (color.r + color.g + color.b > 0) {
color.r = lerp(0, color.r, rounded);
color.g = lerp(0, color.g, rounded);
color.b = lerp(0, color.b, rounded);
}
I think you can drop if statement and lerps to just:
aS = floor(aS * 100) / 100;
bS = floor(bS * 100) / 100;
float dist = sqrt((aS * aS) + (bS * bS));
float percentClose = 1 - (dist / _LightStrength);
float rounded = floor(percentClose * 10) / 10;
color.rgb *= rounded;
But in this case you should test it on your end device and check if it improves performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With