/* Cel shading vertex program for single-pass rendering

In this program, we want to calculate the diffuse and specular

ramp components, and the edge factor (for doing simple outlining)

For the outlining to look good, we need a pretty well curved model.

*/

void main_vp(float4 position : POSITION,

float3 normal : NORMAL,

// outputs

out float4 oPosition : POSITION,

out float diffuse : TEXCOORD0,

out float specular : TEXCOORD1,

out float edge : TEXCOORD2,

// parameters

uniform float3 lightPosition, // object space

uniform float3 eyePosition, // object space

uniform float4 shininess,

uniform float4x4 worldViewProj)

{

// calculate output position

oPosition = mul(worldViewProj, position);

// calculate light vector

float3 N = normalize(normal);

float3 L = normalize(lightPosition - position.xyz);

// Calculate diffuse component

diffuse = max(dot(N, L) , 0);

// Calculate specular component

float3 E = normalize(eyePosition - position.xyz);

float3 H = normalize(L + E);

specular = pow(max(dot(N, H), 0), shininess);

// Mask off specular if diffuse is 0

if (diffuse == 0) specular = 0;

// Edge detection, dot eye and normal vectors

edge = max(dot(N, E), 0);

}

void main_fp(float diffuseIn : TEXCOORD0,

float specularIn : TEXCOORD1,

float edge : TEXCOORD2,

out float4 colour : COLOR,

uniform float4 diffuse,

uniform float4 specular,

uniform sampler1D diffuseRamp,

uniform sampler1D specularRamp,

uniform sampler1D edgeRamp)

{

// Step functions from textures

diffuseIn = tex1D(diffuseRamp, diffuseIn).x;

specularIn = tex1D(specularRamp, specularIn).x;

edge = tex1D(edgeRamp, edge).x;

colour = edge * ((diffuse * diffuseIn) +

(specular * specularIn));

}