EDIT: I pasted a copy of the code for convenience.

I have a question about the halfway vector between the camera and light vectors giving odd results in my shader. I included screenshots of my OSL code, in case I may have got something wrong there.

I've been playing around with OSL, trying to understand lighting and shading more and using this site https://learnopengl.com/PBR/Theory as a sort of guide to help me. I had to do some hacks to compensate for blender's OSL limitations, but most things have been going okay-- until I tried to display my halfway vector. When I plug the halfway vector into the fresnel-schlick equation (used from the link to learnopengl), I get a flat wash of my base reflectance (variable 'f0' in my code). This can be seen in the first picture.

fresnelSchlick = f0 + (1.0 - f0) * pow(1.0 - max(dot(halfVector, V), 0.0), 5.0);

however when I swap the half vector for the surface normal, I get what I would expect the fresnel to look like.

fresnelSchlick = f0 + (1.0 - f0) * pow(1.0 - max(dot(Nn, V), 0.0), 5.0);


My question is, shouldn't I get a similar result when using the halfway vector? And shouldn't that be more "accurate" according to the fresnel-schlick approximation?

Thanks for any help and insight in advance!

EDIT: I pasted copy of the code for my fresnel calculations here. The light_position, camera_position, camera_vector, and shading_position parameters are driven by other Blender nodes. Since my original post I had updated my shader in other places, but I tried to simplify things here to only included things related to my issue with the fresnel.

shader microfacet_model(
    vector light_position = vector(0.0, 0.0, 0.0),
    vector camera_position = vector(0.0, 0.0, 0.0),
    vector camera_vector = vector(0.0, 0.0, 0.0),
    vector shading_position = vector (0.0, 0.0, 0.0),
    color albedo = color(1.0, 1.0, 1.0),
    float metallic = 0.0,
    float roughness = 0.0,
    output closure color BRDF = 0.0
    vector Pp = shading_position;

    vector L;
    L = normalize(light_position - P);

    I; //OSL's global variable for incidence ray
    vector V;
    V = normalize(camera_position - P);

    vector halfVector; //halfway vector between the incidence ray and incoming light vector
    halfVector = normalize(V + L);

    //fresnel-schlick approximation
    //describes the ratio of light reflected to light refracted
    color f0 = color(0.04); // surface reflection at zero incidence (i.e. typically 0.04 for most dielectric materials)
    f0 = mix(f0, albedo, metallic);
    vector fresnelSchlick;
    fresnelSchlick = f0 + (1.0 - f0) * pow(1.0 - max(dot(halfVector, V), 0.0), 5.0);
    BRDF = color(fresnelSchlick) * emission();

dot(halfVector, V) [dot(Nn, V)[2]

  • 2
    $\begingroup$ While it helps to see the code, i would recommend to paste the code you mention in the pictures as text in the question using the "code sample" {} function. $\endgroup$ – Xylvier Mar 18 at 4:04
  • 1
    $\begingroup$ Thank you for the heads up! I just updated my post to include the code mentioned in the pictures as text. It looks different because I've since updated my shader in other places, but I trimmed it down in my post to just the issue with the fresnel not behaving like I would have expected it. $\endgroup$ – emerca20 Mar 19 at 2:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.