Just a minor correction to main_vp,
the line reading:
should actually read:
Also in the .material file, make sure you add
in your pass section, if you have more than one light source.
Well, here is how it looks like (it works for me, please notify me if I'm missing something).
In the .material file:
Code: Select all
vertex_program Ogre/CelShadingTexturedVP cg
{
source Example_CelShadingTextured.cg
entry_point main_vp
profiles vs_1_1 arbvp1
default_params
{
param_named_auto lightPosition light_position_object_space 0
param_named_auto eyePosition camera_position_object_space
param_named_auto worldViewProj worldviewproj_matrix
param_named shininess float 10
}
}
fragment_program Ogre/CelShadingFP cg
{
source Example_CelShading.cg
entry_point main_fp
profiles ps_2_0 arbfp1 fp20
}
material Examples/CelShadingTextured
{
technique
{
pass
{
iteration once_per_light
vertex_program_ref Ogre/CelShadingTexturedVP
{
param_named shininess float 1.0 // you can change this as well
}
fragment_program_ref Ogre/CelShadingTexturedFP
{
}
texture_unit
{
texture cel_shading_diffuse.png 1d
tex_address_mode clamp
filtering none
}
texture_unit
{
texture cel_shading_specular.png 1d
tex_address_mode clamp
filtering none
tex_coord_set 1
}
texture_unit
{
texture cel_shading_edge.png 1d
tex_address_mode clamp
filtering none
tex_coord_set 2
}
texture_unit
{
texture diffuse_map.png //add your diffuse map here
}
texture_unit
{
texture specular_map.png //add your specular map here
}
}
}
}
Please notice that this requires ps_2_0 (to handle more than 4 input maps).
And Example_CelShadingTextured.cg:
Code: Select all
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,
float2 texCoord3 : TEXCOORD0,
out float2 uv3 : TEXCOORD3,
// 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);
uv3 = texCoord3;
}
void main_fp(float diffuseIn : TEXCOORD0,
float specularIn : TEXCOORD1,
float edge : TEXCOORD2,
out float4 colour : COLOR,
float2 uv3 : TEXCOORD3,
uniform sampler1D diffuseRamp,
uniform sampler1D specularRamp,
uniform sampler1D edgeRamp,
uniform sampler2D diffmap : register(s3),
uniform sampler2D specmap : register(s4)
)
{
// Step functions from textures
diffuseIn = tex1D(diffuseRamp, diffuseIn).x;
edge = tex1D(edgeRamp, edge).x;
float4 diffuse_map = tex2D( diffmap, uv3 );
colour = edge * ( ( diffuse_map * diffuseIn ) + ( tex2D( specmap, uv3 ) * specularIn) );
colour.a = diffuse_map.a;
}
Edit reason: Forgot to multiply by the "edge" factor in the final fragment shader output