konstantin magnus Posted June 21, 2021 Share Posted June 21, 2021 (edited) A basic ray marching / sphere tracing renderer written in VEX inside COPs. 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 June 21, 2021 by konstantin magnus added ambient occlusion 5 Quote Link to comment Share on other sites More sharing options...
animatrix Posted June 22, 2021 Share Posted June 22, 2021 Very cool Konstantin! Quote Link to comment Share on other sites More sharing options...
konstantin magnus Posted June 24, 2021 Author Share Posted June 24, 2021 Thank you @animatrix. Currently expanding it into a constructive solid geometry (CSG) stack tool. It can even write to a 3d volume while it creates a really crisp rendering. 3 Quote Link to comment Share on other sites More sharing options...
flcc Posted June 25, 2021 Share Posted June 25, 2021 (edited) Basically you reconstruct houdini inside houdini ! Edited June 25, 2021 by flcc 1 Quote Link to comment Share on other sites More sharing options...
konstantin magnus Posted July 3, 2021 Author Share Posted July 3, 2021 Just found a great presentation on Ray Marching: 1 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.