- Home /
Use texture to determine shading?
Currently I am procedurally generating a "ramp texture" containing the four shades that I wish to colour my object with. The idea being that the shader would pick one of the four shades depending upon the intensity of the light.
I hoped that the Toon shader would work for this but unfortunately it seem that it applies additional lighting over the top of the ramp's colours. If the light is bright then the objects colours will be very white and washed out - not great!
The code for the current shader is below:
Shader "Toon/Lit" {
Properties {
_Color ("Main Color", Color) = (0.5,0.5,0.5,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_Ramp ("Toon Ramp (RGB)", 2D) = "gray" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf ToonRamp
sampler2D _Ramp;
// custom lighting function that uses a texture ramp based
// on angle between light direction and normal
#pragma lighting ToonRamp exclude_path:prepass
inline half4 LightingToonRamp (SurfaceOutput s, half3 lightDir, half atten)
{
#ifndef USING_DIRECTIONAL_LIGHT
lightDir = normalize(lightDir);
#endif
half d = dot (s.Normal, lightDir)*0.5 + 0.5;
half3 ramp = tex2D (_Ramp, float2(d,d)).rgb;
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
c.a = 0;
return c;
}
sampler2D _MainTex;
struct Input {
float2 uv_MainTex : TEXCOORD0;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Diffuse"
}
I've only just started learning ShaderLab so any pointers would be much appreciated - I'm finding it pretty tough so far!
Thanks!
half3 ramp = tex2D (_Ramp, float2(d,d)).rgb;
Hmm, so you have a texture which I will assume is a greyscale, and you want to get a particular pixel on the diagonal line across it's center to effect the color of the object. Is that correct? Note by using float2(d,d) as the coordinate, you will ONLY use the diagonal line across the center of the texture, all other colors in the texture will be ignored.
Simple workaround solution: It is possible you may wish to adjust your _Ramp texture to be non-linear (ramp/curve up to white more slowly). Alternative: have the computed value of "d" ramp up more slowly by squaring it (d=d*d). I would test/play with different options for computing d, e.g. what happens if you don't add 0.5? or if you multiply the final d=d*0.5? Sometimes you end up finding effects that are even more interesting than intended, or useful in other situations.
So when you use the above shader the colours of the object are not actually the colours of the ramp but the light mixed with the colour of the ramp. So for example if I have a ramp texture which goes from dark green to black and I set my directional light's intensity to "10" then the colour of the object wouldn't be dark green (the lightest shade of the ramp) but would be white.
What I would like is to have a ramp with several set colours which the application can choose from depending upon the intensity of the light. I guess if you think of something like $$anonymous$$onument Valley - (http://cdn0.sbnation.com/assets/4155547/monumentvalley_gdc_long.png) - then it wouldn't be too far off :)
ok, I understood that part, but perhaps I misunderstood the parameters to your shader that define the inco$$anonymous$$g light you are talking about. lightDir
and atten
I interpreted as a 3d vector, and a light intensity value between 0 and 1, respectively.
What I would like is to have a ramp with several set colours which the application can choose from depending upon the intensity of the light.
I would think that if you made your ramp texture look like a dozen stripes each a distinct shade of grey, rather than a gradient of hundreds of greys, this shader would work as is. If you like particular ramp shade better than another, simply make THAT stripe wider in the texture.
Edit: Ah! I see what I was missing, the atten value is NOT a factor when computing "d". This is why the intensity of the light is not effecting which ramp color is chosen. Perhaps something like this will help.
half d = dot (s.Normal, lightDir)*0.5 + 0.5;
d=d*atten; //or is it (atten*2)? like lower in the shader not sure
half3 ramp = tex2D (_Ramp, float2(d,d)).rgb;