- Home /
Shader: Changing a Ramp Size
Hey, I'm trying to have the Toon Lighted Shader increase/decrease the size of the ramp depending on the main light's intensity. Any ideas how I'd go about this? I'm considering changing the line below to multiply by something, but I'm not sure what.
half d = dot (s.Normal, lightDir)*0.5 + 0.5;
^ This line because when I mess with the 0.5 numbers, it increases/decreases the ramp size.
Shader "Toon/Lighted" {
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 {"Queue"="Transparent" "RenderType"="Transparent"}
Blend SrcAlpha OneMinusSrcAlpha
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 = s.Alpha;
return c;
}
sampler2D _MainTex;
float4 _Color;
struct Input {
float2 uv_MainTex : TEXCOORD0;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Diffuse"
}
Answer by Owen-Reynolds · Jan 22, 2012 at 05:39 PM
You're on the right track. If you know what the old code was doing, makes it easier to modify. The code above looks up a 0-1 ramp value from the White/Black Ramp texture. You're allowed to not look it up, and instead just compute the ramp. In the old code, these two lines compute ramp:
half d = dot (s.Normal, lightDir)*0.5 + 0.5;
half3 ramp = tex2D (_Ramp, float2(d,d)).rgb; // we can skip this
The dot-product of your normal and the lightDir computes the percent of light you should get: 1 if you are facing, 0.7 for 45 degree angled away, 0 for an edge, and -1 for facing away. The range is -1 to 1. It's a really common value in lighting math.
Texture lookups think 0 is the left side and 1 is the right. So, DP*0.5+0.5 scales the -1 to 1 dot-prod into a 0-1 for the lookup. Since we aren't doing a texture lookup, we can ignore that. In math, a ramp looks like this (imagine low is black and high is white, so this represents black on the left, a short ramp to white, then white on the right):
1 ------------
/
/
0 -----------
-1 1 <- dot prod
Assume we have the raw -1 to 1: half d = dot(s.Normal, lightDir);
A general formula for a ramp is:
ramp = (d-CENTER)*SPEED+0.5;
ramp = Clamp(ramp, 0, 1); // this flattens the left/right sides
For CENTER, 0 means the lightwise edge, positive (up to one) brings it towards the light, negative (down to -1) brings it to the unlit side. Interesting numbers for SPEED are 1 (very wide) to huge. Of course, anything more than about 20 will be almost an instant change between colors. The 0.5 makes CENTER be the center (without it, CENTER is the left edge, and changing SPEED makes it grow to the right. With the 0.5, changing SPEED grows both ways.)
For example, ramp=(d - -0.25)*10 + 0.5;
would make a very small/sharp ramp (the 10 makes it change quickly,) which is centered towards the backside of the model (0 is the edge, so -0.25 is towards the backside.) You could also incorporate the *2
(in atten*2
) into here, saving a math step.
Okay, that helps a bit. I'm guessing I'd do something like:
half d = dot (s.Normal, lightDir)* ((0.4 + 0.4) * lightIntensity);
Now the problem is what to multiply it by. Any ideas?
Not that exactly -- that's just DOT*0.8*light. The trick is to compute a new value for the ramp variable, using dot(...) times something and plus something. Times grows/shrinks it, plus shifts it.
As to get the light intensity? There isn't nomrally such a thing. You'd have to set up zones (like in the smokey tavern, it's 1/2.)
How about the colour of the light? Would that be more conventional?
When you wrote "main light" I assumed you meant the one direction light. It's always got the same stats everywhere. It you want to check the closest point light...seems doable, but not my area.
The other thing you could do is simply make different ramp textures. One is for most everywhere. A few triggerboxes (the boss zone?) swap the texture in/out when you enter/leave.
Hah, again I overlook the simplest solution. That will more than suffice, and thanks for the information none the less!
Your answer
Follow this Question
Related Questions
Prevent light combining with other lights 0 Answers
Unity5 Any way to have a unlit no depth shader? 0 Answers
Shader Slider 1 Answer
How To Replicate the Untitled Goose Game Art Style? 0 Answers