Jump to content

Ray marching in COPs


Recommended Posts

A basic ray marching / sphere tracing renderer written in VEX inside COPs.

rm_sshot.thumb.jpg.6f5fac4d19c944e02abbbc0100586f41.jpg

Entirely based on a shader toy-tutorial by Martijn Steinrucken / @The_ArtOfCode:
https://odysee.com/@TheArtOfCode:b/ray-marching-for-dummies:f

// SCENE
function float get_dist(vector pos){
    vector pos_sphere = set(sin(TIME), 1.55, 6.0);
    float radius_sphere = 0.75;
    float dist_sphere = length(pos - pos_sphere) - radius_sphere;
    float height_plane = noise(pos * 2.75) * 0.2;
    float dist_plane = pos.y - height_plane;
    float dist_min = min(dist_sphere, dist_plane);
    return dist_min;
}

// TRACING
function float raymarch(vector pos_cam, dir_cam){
    float dist_orig = 0.0;
    float dist_srf = 1e-3;
    float dist_max = 1e1;
    int steps_max = 200;
    for(int i = 0; i < steps_max; i++){
        vector pos = pos_cam + dir_cam * dist_orig;
        float dist_scene = get_dist(pos);
        dist_orig += dist_scene;
        if(dist_scene < dist_srf || dist_scene > dist_max){
            break;
        }
    }
    return dist_orig;
}

// NORMALS
function vector get_normal(vector pos){
    vector offset = {0.01, 0.0, 0.0};
    float dist = get_dist(pos);
    float dx = get_dist(pos - offset.xyy);
    float dy = get_dist(pos - offset.yxy);
    float dz = get_dist(pos - offset.yyx);
    vector nml = normalize(dist - set(dx, dy, dz));
    return nml;
}

// LIGHTING
function float get_light(vector pos){
    vector pos_light = set(1.0, 4.0, 3.0);
    pos_light.x += sin(TIME*8);
    pos_light.z += cos(TIME*8);
    vector dir_light = normalize(pos_light - pos);
    vector nml_srf = get_normal(pos);
    float amount = max(dot(nml_srf, dir_light), 0.0);
    float dist = raymarch(pos + nml_srf * 1e-1, dir_light);
    if(dist < length(pos_light - pos)){
        amount *= 0.2;
    }
    return amount;
}

// CANVAS
float aspect = XRES / float(YRES);
vector uvw = set(X - 0.5, (Y - 0.5) / aspect, 0.0);

// CAMERA
vector pos_cam = {0.0, 1.5, 0.0};
vector dir_cam = normalize(set(uvw.x, uvw.y, 1.0));

// PROCESS
float dist_field = raymarch(pos_cam, dir_cam);
vector pos_world = pos_cam + dir_cam * dist_field;
float diffuse = get_light(pos_world);
float mask_clip = dist_field < 55.0;

// OUTPUT
vector color = diffuse * mask_clip;
assign(R, G, B, color);

ray_marching.hipnc

Edited by konstantin magnus
added ambient occlusion
  • Like 5
Link to comment
Share on other sites

  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...