Description
Changelog
Reviews

This is an addon for Godot 4.4+ that adds the Full-Oren-Nayar node to the visual shader system. This node outputs the Diffuse Light based on the Oren–Nayar Reflectance Model.

Full-Oren-Nayar Diffuse Reflectance Model (Node).

GDSL:

shader_type spatial;

const float PI2 = 9.86960440108935799230;
const float INV_PI = 0.31830988618379067154;

group_uniforms _FullOrenNayar;
uniform vec3 _DiffuseColor : source_color = vec3(1.0);
uniform float _Sigma : hint_range(0.0, 90.0, 1e-3) = 30.0;

vec3 diffuse_full_oren_nayar(
    in vec3 n,
    in vec3 l,
    in vec3 v,
    in vec3 rho,
    in float sigma
)
{
    float NdotL = dot(n, l); // cos(theta_l) == cos(theta_i).

    if(NdotL < 0.0)
    {
        return vec3(0.0);
    }

    float NdotV = min(max(dot(n, v), 1e-3), 1.0); // cos(theta_v) == cos(theta_r).

    sigma = sigma * PI / 180.0;
    float sigma2 = sigma * sigma;

    float theta_i = acos(NdotL);
    float theta_r = acos(NdotV);

    vec3 l_proj = normalize(l - n * NdotL);
    vec3 v_proj = normalize(v - n * NdotV);

    float cos_phi = dot(v_proj, l_proj);

    float alpha = max(theta_i, theta_r);
    float beta = min(theta_i, theta_r);

    float C1 = 1.0 - 0.5 * sigma2 / (sigma2 + 0.33);

    float C2 = 0.45 * sigma2 / (sigma2 + 0.09);
    if(cos_phi >= 0.0)
    {
        C2 *= sin(alpha);
    }
    else
    {
        C2 *= sin(alpha) - pow( 2.0 * beta / PI, 3.0);
    }

    float C3 = 0.125 * sigma2 / (sigma2 + 0.09) * pow((4.0 * alpha * beta) / PI2, 2.0);

    vec3 L1 = vec3(INV_PI * (C1 + cos_phi * C2 * tan(beta) + (1.0 - abs(cos_phi)) * C3 * tan((alpha + beta) / 2.0)));
    vec3 L2 = 0.17 * rho * INV_PI * sigma2 / (sigma2 + 0.13) * (1.0 - cos_phi * (4.0 * beta * beta) / PI2);

    return (L1 + L2) * NdotL;
}

void fragment() {
    ALBEDO = _DiffuseColor;
}

void light() {
    vec3 n = normalize(NORMAL);
    vec3 l = normalize(LIGHT);
    vec3 v = normalize(VIEW);

    /* Full-Oren-Nayar */
    // https://dl.acm.org/doi/pdf/10.1145/192161.192213
    vec3 fd = diffuse_full_oren_nayar(n, l, v, ALBEDO, _Sigma);

    // To compare with the Slice-Image.
    //vec3 radiance = (LIGHT_COLOR / PI) * ATTENUATION;

    // In PI light units.
    vec3 radiance = LIGHT_COLOR * ATTENUATION;

    DIFFUSE_LIGHT += radiance * fd;
}

[ Support Email: [email protected] ]

Changelog for version v2.0.2

No changelog provided for this version.

Reviews (0)

Visual Shader Full-Oren-Nayar Light Model Node has no reviews yet.

Login to write a review.