HalfLambert + Color Ramp + Rim Mask

Hi guys,

I just started learning cg programming for shaders

I’m trying to do a half lambert shader with a rim mask following the gdc2011 paper by ben cloward:
http://www.gdcvault.com/play/1014362...ghting-in-STAR

So far I got this:

Shader “test/halfLambertRampRim” {
Properties {
_Color (“Main Color”, Color) = (1,1,1,1)
_Ramp (“Shading Ramp”, 2D) = “gray” {}
_BumpMap (“Normalmap”, 2D) = “bump” {}
_RimPower (“Rim Power”, Range(0.1,10.0)) = 3.0
_RimFresnel (“Rim Fresnel”, Range(0.1,10.0)) = 2.0
}

SubShader {
Tags { “RenderType” = “Opaque” }
CGPROGRAM
#pragma surface surf HalfLambert
#pragma target 3.0

sampler2D _Ramp;
float4 _Color;
sampler2D _BumpMap;
float _RimPower;

half4 LightingHalfLambert (SurfaceOutput s, half3 lightDir, half atten)
{
half NdotL = dot (s.Normal, lightDir);
half diff = NdotL * 0.5 + 0.5; //half Lambert here
half3 ramp = tex2D (_Ramp, float2(diff)).rgb;
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
c.a = s.Alpha;
return c;
}

struct Input {
float2 uv_BumpMap; //normalMap
float3 viewDir; // rim
float3 worldRefl;
INTERNAL_DATA
};

void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = _Color.rgb;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));

half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
o.Emission += pow (rim, _RimPower);
}
ENDCG
}
Fallback “Diffuse”
}

I would like to know if there’s a way to multiply the rim Mask by the wrapped color done by the color obtained via the lighting Pass

I mean something like o.Emission += pow(rim,_RimPower) * “light gradient color” (p38 of the pdf)

Thanks in advance :slight_smile:

Yeah, scratch doing it in emission and add it to the albedo in the lighting value, after you’ve done the shadow stuff.

…inside your LightingHalfLambert function…

...
half rim = 1.0 - saturate(dot (normalize(viewDir), s.Normal));
c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
c.rgb += pow(rim,_RimPower) * ramp;
c.a = s.Alpha;
return c;

For the most part this is what o.Emission does inside the surface shader anyway.

Oh yeah I see what you mean I’ll test doing that thanks, and thanks also for your TF2 shader it’s a great example on how to do what I’m trying to accomplish!

Ok so I got something that is starting to work out :slight_smile:

half4 LightingHalfLambert (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
{
half NdotL = dot (s.Normal, lightDir);
half diff = NdotL * 0.5 + 0.5; //half Lambert here

half4 c;

half3 ramp = tex2D (_Ramp, float2(diff)).rgb;
half3 wrap = s.Albedo * _LightColor0.rgb * ramp;

half rim = 1.0 - (saturate((dot (normalize(viewDir), s.Normal))));
half3 powRim = pow(rim,_RimPower);

half3 rimMask = wrap * powRim;

c.rgb = lerp(wrap, s.Albedo, rimMask)* (atten * 2);
c.a = s.Alpha;

return c;
}

But now if I add a maintex on the void surf the effects gets killed by the diffuse (doh!)

I’m going to try a different approach tomorrow :slight_smile: