...Not exactly what I was hoping for, but close. It uses a lookup texture (Material Texture 1). You'll have to tweak this to adjust the threshold and strength of the effect.

This is just a demonstration and what I am using now.









Code:

// toon.fx
// xXxGuitar511

float4x4 matWorldViewProj;
float4x4 matWorldView;
float4x4 matWorld;
float4x4 matView;
float3  vecViewPos;
texture entSkin1;
texture mtlSkin1;


sampler map_toon = sampler_state
{texture = <entSkin1>;};

sampler map_lookup = sampler_state
{
	texture = <mtlSkin1>;
	AddressU = CLAMP;
	AddressV = CLAMP;
};


struct VS_IN
{
	float4 Pos	: POSITION;
	float2 Tex	: TEXCOORD0;
	float3 Nor	: NORMAL;
};

struct VS_OUT
{
	float4 Pos	: POSITION;
	float2 Tex	: TEXCOORD0;
	float3 Nor	: TEXCOORD1;
	float3 Dir	: TEXCOORD2;
};

struct PS_IN
{
	float2 Tex	: TEXCOORD0;
	float3 Nor	: TEXCOORD1;
	float3 Dir	: TEXCOORD2;
};


VS_OUT VS(VS_IN In)
{
	VS_OUT Out;
	//
	Out.Pos = mul(In.Pos, matWorldViewProj);
	float3 wPos = mul(In.Pos, matWorld);
	Out.Tex = In.Tex;
	//
	Out.Nor = normalize(mul(In.Nor, matWorldView));
	Out.Dir = normalize(wPos - vecViewPos);
	//
	return Out;
}


float4 PS(PS_IN In) : COLOR
{
	float4 Out = {0, 0, 0, 1};
	float3 Col = tex2D(map_toon, In.Tex);
	//
	float3 face = {0, 0, -1};
	float lit = saturate(dot(In.Nor, face));
	//
	float3 Ref = tex2D(map_lookup, float2(lit, 0.25));
	Ref = saturate((Ref - 0.5)*2 + 1);
	Ref += saturate(Ref - 0.5) * 2;
	//
	Out.rgb = Col * Ref;
	//
	return Out;
}


technique toon
{
	pass p1
	{
		VertexShader = compile vs_2_0 VS();
		PixelShader = compile ps_2_0 PS();
	}
}



Last edited by xXxDisciple; 11/10/08 05:27.

xXxGuitar511
- Programmer