You can use message passing to transfer data from lightshader to surface shader
here is the lightshader :
light dirlight(
color lightcolor = 1;
float intensity = 1;
output float nondiffuse = 1;
output float nonspecular = 0
)
{
vector dir = vector "shader" (0,0,1);
solar( dir, 0 )
Cl = intensity * lightcolor;
}
the two param "nondiffuse" and "nonspecular" is to control the light effect on the surface
i.e.
nondiffuse = 1 => no diffuse on surface
nonspecular =1 => no specular on surface
here is the surface shader :
color diffuse(normal Nn)
{
extern point P;
color C = 0;
illuminance(P, Nn, PI/2)
{
float nondiff = 0;
lightsource("nondiffuse", nondiff);
C += Cl * (1 - nondiff) * (Nn . normalize(L));
}
return C;
}
color specular (normal Nn; vector V; float roughness)
{
extern point P;
color C = 0;
illuminance (P, Nn, PI/2)
{
float nonspec = 0;
lightsource("nonspecular", nonspec);
vector H = normalize(normalize(L) + V);
C += Cl * (1 - nonspec) * pow(max(0, Nn . H), 1/roughness);
}
return C;
}
surface testshader(color col1 = 0.5;
float roughness = 0.2,
Kd = 1,
Ks = 1)
{
normal Nn = normalize(N);
vector In = normalize(-I);
Ci = col1 * (Kd * diffuse(Nn)) + (Ks * specular(Nn, In, roughness));
}
Then u can get this:
[/img]