OSL Sky Texture Issue

There is a zip file with a set of OSL shaders for blender/cycles dated February 2014 located here:

http://www.openshading.com/osl/example-shaders/

I have been trying to get the sky texture shader to work, so far without success.

Using the Hosek/Wilkie model I get a black background with any set of inputs. Using Preetham (ie - any text string other than Hosek / Wilkie) I get a colour which depends only on the “radiance parameter”. This colour is constant over the whole sky dome.

/*
 * Copyright 2011-2013 Blender Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

#include "stdosl.h"
#include "node_color.h"

float sky_angle_between(float thetav, float phiv, float theta, float phi)
{
    float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta);

        return 0.0;
    if (cospsi > 1.0)
    if (cospsi < -1.0)
        return M_PI;

    return acos(cospsi);
}

vector sky_spherical_coordinates(vector dir)
{
    return vector(acos(dir[2]), atan2(dir[0], dir[1]), 0);
}

/* Preetham */
float sky_perez_function(float lam[9], float theta, float gamma)
{
    float ctheta = cos(theta);
    float cgamma = cos(gamma);

    return (1.0 + lam[0] * exp(lam[1] / ctheta)) * (1.0 + lam[2] * exp(lam[3] * gamma) + lam[4] * cgamma * cgamma);
}

color sky_radiance_old(normal dir,
                       float sunphi, float suntheta, color radiance,
                       float config_x[9], float config_y[9], float config_z[9])
{
    /* convert vector to spherical coordinates */
    vector spherical = sky_spherical_coordinates(dir);
    float theta = spherical[0];
    float phi = spherical[1];

    /* angle between sun direction and dir */
    float gamma = sky_angle_between(theta, phi, suntheta, sunphi);

    /* clamp theta to horizon */
    theta = min(theta, M_PI_2 - 0.001);

    /* compute xyY color space values */
    float x = radiance[1] * sky_perez_function(config_y, theta, gamma);
    float y = radiance[2] * sky_perez_function(config_z, theta, gamma);
    float Y = radiance[0] * sky_perez_function(config_x, theta, gamma);

    /* convert to RGB */
    color xyz = xyY_to_xyz(x, y, Y);
    return xyz_to_rgb(xyz[0], xyz[1], xyz[2]);
}

/* Hosek / Wilkie */
float sky_radiance_internal(float config[9], float theta, float gamma)
{
    float ctheta = cos(theta);
    float cgamma = cos(gamma);
    
    float expM = exp(config[4] * gamma);
    float rayM = cgamma * cgamma;
    float mieM = (1.0 + rayM) / pow((1.0 + config[8] * config[8] - 2.0 * config[8] * cgamma), 1.5);
    float zenith = sqrt(ctheta);

    return (1.0 + config[0] * exp(config[1] / (ctheta + 0.01))) *
            (config[2] + config[3] * expM + config[5] * rayM + config[6] * mieM + config[7] * zenith);
}

color sky_radiance_new(normal dir,
                       float sunphi, float suntheta, color radiance,
                       float config_x[9], float config_y[9], float config_z[9])
{
    /* convert vector to spherical coordinates */
    vector spherical = sky_spherical_coordinates(dir);
    float theta = spherical[0];
    float phi = spherical[1];

    /* angle between sun direction and dir */
    float gamma = sky_angle_between(theta, phi, suntheta, sunphi);

    /* clamp theta to horizon */
    theta = min(theta, M_PI_2 - 0.001);

    /* compute xyz color space values */
    float x = sky_radiance_internal(config_x, theta, gamma) * radiance[0];
    float y = sky_radiance_internal(config_y, theta, gamma) * radiance[1];
    float z = sky_radiance_internal(config_z, theta, gamma) * radiance[2];

    /* convert to RGB and adjust strength */
    return xyz_to_rgb(x, y, z) * (M_2PI / 683);
}

shader node_sky_texture(
    int use_mapping = 0,
    matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    vector Vector = P,
    string sky_model = "Hosek / Wilkie",
    float theta = 0.0,
    float phi = 0.0,
    color radiance = color(0.0, 0.0, 0.0),
    float config_x[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    float config_y[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    float config_z[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
    output color Color = color(0.0, 0.0, 0.0))
{
    vector p = Vector;

    if (use_mapping)
        p = transform(mapping, p);
    
    if (sky_model == "Hosek / Wilkie")
        Color = sky_radiance_new(p, phi, theta, radiance, config_x, config_y, config_z);
    else
        Color = sky_radiance_old(p, phi, theta, radiance, config_x, config_y, config_z);
}


Has anyone successfully used the osl sky texture?

Hi!

I kind of gave it a shot to fix some broken stuff about the shader, check the screen below:


the main trouble was that the:

<b>float config_x[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
float config_y[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
float config_z[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},</b>

had anything assigned so in some functions 0.0 was multiplied by something and returned 0 (a black color)
since this settings are the base color settings it returned black!

The second trouble was the placement, if you turned that on it would apply a matrix:

matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) to the point P,

I is not ideal and i tried somehow to fix this with:

<b>if (use_mapping)
    p = transform("object", abs(p));</b>

I hope i could help! The full modified code is below:


/*
 * Copyright 2011-2013 Blender Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

#include "stdosl.h"
#include "node_color.h"

float sky_angle_between(float thetav, float phiv, float theta, float phi)
{
    float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta);

    if (cospsi &gt; 1.0)
        return 0.0;
    if (cospsi &lt; -1.0)
        return M_PI;

    return acos(cospsi);
}

vector sky_spherical_coordinates(vector dir)
{
    return vector(acos(dir[2]), atan2(dir[0], dir[1]), 0);
}

/* Preetham */
float sky_perez_function(float lam[9], float theta, float gamma)
{
    float ctheta = cos(theta);
    float cgamma = cos(gamma);

    return (1.0 + lam[0] * exp(lam[1] / ctheta)) * (1.0 + lam[2] * exp(lam[3] * gamma) + lam[4] * cgamma * cgamma);
}

color sky_radiance_old(normal dir,
                       float sunphi, float suntheta, color radiance,
                       float config_x[9], float config_y[9], float config_z[9])
{
    /* convert vector to spherical coordinates */
    vector spherical = sky_spherical_coordinates(dir);
    float theta = spherical[0];
    float phi = spherical[1];

    /* angle between sun direction and dir */
    float gamma = sky_angle_between(theta, phi, suntheta, sunphi);

    /* clamp theta to horizon */
    theta = min(theta, M_PI_2 - 0.001);

    /* compute xyY color space values */
    float x = radiance[1] * sky_perez_function(config_y, theta, gamma);
    float y = radiance[2] * sky_perez_function(config_z, theta, gamma);
    float Y = radiance[0] * sky_perez_function(config_x, theta, gamma);

    /* convert to RGB */
    color xyz = xyY_to_xyz(x, y, Y);
    return xyz_to_rgb(xyz[0], xyz[1], xyz[2]);
}

/* Hosek / Wilkie */
float sky_radiance_internal(float config[9], float theta, float gamma)
{
    float ctheta = cos(theta);
    float cgamma = cos(gamma);
    
    float expM = exp(config[4] * gamma);
    float rayM = cgamma * cgamma;
    float mieM = (1.0 + rayM) / pow((1.0 + config[8] * config[8] - 2.0 * config[8] * cgamma), 1.5);
    float zenith = sqrt(ctheta);

    return (1.0 + config[0] * exp(config[1] / (ctheta + 0.01))) *
            (config[2] + config[3] * expM + config[5] * rayM + config[6] * mieM + config[7] * zenith);
}

color sky_radiance_new(normal dir,
                       float sunphi, float suntheta, color radiance,
                       float config_x[9], float config_y[9], float config_z[9])
{
    /* convert vector to spherical coordinates */
    vector spherical = sky_spherical_coordinates(dir);
    float theta = spherical[0];
    float phi = spherical[1];

    /* angle between sun direction and dir */
    float gamma = sky_angle_between(theta, phi, suntheta, sunphi);

    /* clamp theta to horizon */
    theta = min(theta, M_PI_2 - 0.001);

    /* compute xyz color space values */
    float x = sky_radiance_internal(config_x, theta, gamma) * radiance[0];
    float y = sky_radiance_internal(config_y, theta, gamma) * radiance[1];
    float z = sky_radiance_internal(config_z, theta, gamma) * radiance[2];

    /* convert to RGB and adjust strength */
    return xyz_to_rgb(x, y, z) * (M_2PI / 683);
}

shader node_sky_texture(
    int use_mapping = 0,
    matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
    vector Vector = P,
    string sky_model = "Hosek / Wilkie",
    float theta = 0.0,
    float phi = 0.0,
    float config_x[9] = {0.25,0.25,0.25,0.25,0.25,0.25,0.25,0.25,0.25},
    float config_y[9] = {0.25,0.25,0.25,0.25,0.25,0.25,0.25,0.25,0.25},
    float config_z[9] = {0.25,0.25,0.25,0.25,0.25,0.25,0.25,0.25,0.25},
    color radiance = color(0.0, 0.0, 0.0),
    output color Color = color(0.0, 0.0, 0.0))
{

    vector p = Vector;

    if (use_mapping)
        p = transform("object", abs(p));
    
    if (sky_model == "Hosek / Wilkie")
        Color = sky_radiance_new(p, phi, theta, radiance, config_x, config_y, config_z);
    else
        Color = sky_radiance_old(p, phi, theta, radiance, config_x, config_y, config_z);
}

Thank you, at least now I can see something on the screen, even if it does not act as a normal sky texture node. I will spend some time to figure out the osl syntax and the math involved.

Hello!

When i did my check yesterday i had the feeling that all values where good to go, the key must be the config settings, take a look at the screen below:


Curiously this is “closer” to the sky texture effect, but only from this particular angle, that’s because of the setting i used:

float config_x[9] = {I[0],I[1],I[2],P[0],P[1],P[2],N[0],N[1],N[2]},
float config_y[9] = {I[0],I[1],I[2],P[0],P[1],P[2],N[0],N[1],N[2]},
float config_z[9] = {I[0],I[1],I[2],P[0],P[1],P[2],N[0],N[1],N[2]},

So, each config_ takes 9 values 3,3,3 (3D coordinates?) my only guessing is that the settings or the combination of settings must exist as normals, vectors, points, colors any 3D variables present in the shader space!

It think I will be a while working my way through this, it has been many, many years since I took an algebra class.

Also, I notice you are using it connected to a material shader, it is intended to be used with the background shader in the world node.