Getting a Light vector in OSL for Blender

OSL works with closures and closures are effectively summed over all lights in the scene. If you would like to alter for example the color based on some completely non physical interaction with a certain light as you do for some toon shaders you still might want to access a light object anyway. This article shows how this might be achieved.
Unfortunately what is described below does not work. Whether this is a bug or not I don't know, but getattribute("Lamp","object:location",L) does not get the location of the object named Lamp but the location of the object being shaded ... So no cel shading until this is fixed ...

The code below determines the light vector L by getting the object:location attribute from an object called Lamp and subtracting the point being shaded P. In Blender getting the location attribute in OSL only seems to work for real objects, not for actual lamps! (Maybe because a lamp has no node shader attached.)
shader oink(
color Color = 1,
output color Cout = Color
){
    vector L;
    getattribute("Lamp","object:location",L);
    P=transform("object","world",P);
    float cost=abs(dot(normalize(L-P),N));
    Cout = color(cost,1-cost,.2);  
}
Note that when we plug this calculated color for example into a diffuse shader, normal lighting calculations will still be performed, so in the example image we have a pinkish color on the side of the light object and a greenish color on the sides perpendicular to the light vector (including the side facing the camera). These colors are then diffusely lit by the same Lamp object (a bit too bright in this example :-)

Example node setup


No comments:

Post a Comment