Light rendering in a SDF

calendar_today

05.02.2023

label

VEX, Rendering

mouse

Houdini 19.5

Description

Monte Carlo integration and ray marching in a signed distance field (SDF) to render emissive circles.

1 Code

// Use Monte Carlo integration and ray marching
// of signed distance field (SDF) to render emissive circles.
// Source: https://github.com/miloyip/light2d/blob/master/basic.c

int samples = chi('samples');

function float sd_circle(vector2 uv, pos; float radius){
    float dist = distance(uv, pos) - radius;
    return dist;
}

function float sd_scene(vector2 uv){
    float d_0 = sd_circle(uv, {0.3, 0.18}, 0.12);
    float d_1 = sd_circle(uv, {0.25, 0.18}, 0.12);
    float d_2 = sd_circle(uv, {-0.3, -0.2}, 0.02);
    float dist = min( max(d_0, -d_1), d_2);
    return max(dist);
}

function float trace(vector2 uv, dist){
    float t = 0.0;
    for(int i = 0; i < 100 && t < 2.0; i++){
        float sd = sd_scene(uv + dist * t);
        if(sd < 1e-5) return 1.5;
        t += sd;
    }
    return 0.0;
}

function float sample(vector2 uv; int samples){
    float sum = 0.0;
    for(int i = 0; i < samples; i++){
        float a = 2.0 * PI * ((rand(uv) + i) / float(samples));
        sum += trace(uv, set(cos(a), sin(a)));
    }
    return sum / float(samples); 
}

vector2 uv = set(v@P.x, v@P.y);

f@d = sample(uv, samples);

2 Source

download

Downloads