ambient_occlusion function

Hello,

I am currently translating the RenderMan shaders in the “Essential RenderMan Fast” book to OSL, for learning purposes.

For instance, I have translated

surface matte(
  float Ka = 1;
  float Kd = 1;
)
{
  normal Nf = faceforward (normalize(N), I);
  Oi = Os;
  Ci = Oi * Cs * (Ka * ambient() + Kd * diffuse(Nf)));
}

as follows

shader erf_matte(
    float Ka = 1,
    float Kd = 1,
    color inputColor = color(1, 0, 0),
    output color outputColor = color(0, 0, 1),
    output closure color myBSDF = diffuse(N)
)
{
    outputColor = inputColor;
    normal Nn = normalize(N);
    myBSDF = outputColor
        * (Ka * ambient_occlusion() + Kd * diffuse(Nn));
}

However, when I render, my solid is bright [red], not matte.
Is the absence of “matteness” due to the fact that the output color is not multiplied by the Input Opacity Factor (Oi in Renderman Shader), which is not available in OSL [according to the OSL Language Spec], as opposed to Renderman?

Many thanks for your help.

philroc

Hello there!

I think almost everything you did is good to go, except that the values are too high for OSL everything is already kind of normalized so you should aim for 0 - 1 values (1 is the maximum and almost always to high!), i’ve made some changes to your original code:

shader erf_matte(
float Ka = 0.1,
float Kd = 0.1,
color inputColor = color(0.5, 0, 0),
output color outputColor = color(0, 0, 0.5),
output closure color myBSDF = holdout()
)
{
outputColor = inputColor;
myBSDF = outputColor
* (Ka * ambient_occlusion() + Kd * diffuse(N));
}

And the result rendered on the viewport:


Hi tree3d,

thanks for you input.

Unfortunately, replacing 1 by .5 doesn’t solve the matteness (or lack thereof) problem.

If I replace

outColor = inColor;
normal Nn = normalize(N);
myBSDF = outColor
    * 
    ((Ka * ambient_occlusion())
    +
    (Kd * diffuse(Nn)));

by

outColor = inColor;
normal Nn = normalize(N);
myBSDF = outColor * diffuse(Nn);

I get the same effect, which means that ambient_occlusion(), Ka and Kd have no effect.

I have asked for help in the Google OSL Developers Group. If they provide a solution, I will post it here.

Cheers,

Philroc

Ehehehehehehe i was only regarding the normalization of the values and skipped the matte issue entirely!

Ok, so OSL has a native matte shader here:

I changed it a little bit:

surface
matte
    [[ string help = "Lambertian diffuse material" ]]
(
    float Kd = 1
        [[  string help = "Diffuse scaling",
            float min = 0, float max = 1 ]],
    color Cs = 1
        [[  string help = "Base color",
            float min = 0, float max = 1 ]],
    output closure color CL = holdout()
  )
{
    Ci = Kd * Cs * diffuse (N);
    CL = Ci;
    
}

I think it gives an output of a matte color:


I hope i helped, sorry for not going for the matte thingy the first time!