/** * Computes the color corresponding to the ray intersection point (if any) * vec3 {x,y,z} ro ray origin * vec3 {u,v,w} rd ray direction */ vec4 computeColor(vec3 ro, vec3 rd) { int i; int k = 0; float t0; float tk0; vec3 ro2; vec4 color; raymarch(ro, rd, i, t0); vec3 p; // Surface point vec3 normal; // Surface normal float t; // Distance traveled by ray from eye if(i < g_rmSteps && t0 >= g_zNear && t0 <= g_zFar) { // Raymarching hit a surface t = t0; p = ro + rd * t0; int matIndex = int(floor(mod(min(min(p.x, p.y), p.z), 4.0))) + 1; for(int n = 0; n < maxMaterial; n++) { if(n == int(matIndex)) { color = u_materials[n]; // white box break; } } normal = getNormal(p); color = colorPass(color, t, p, normal); } else { return u_sky; } return color; }
vec3 calculate_color(const distance& dist, const vec3& p, const vec3& ray, const int userdata) { vec3 normal = get_normal(dist.field, p); const float eta = 0.3; const float sqf = (1 - eta) / (1 + eta); const float f = sqf * sqf; const float fresnel_power = 5; const float ratio = f + (1 - f) * pow(1 - dot(ray, normal), fresnel_power); vec3 diffuse = get_color(dist.object_id, p); if (dist.object_id == 2 && userdata < 3) { vec3 reflect_ray = glm::reflect(ray, normal); diffuse = mix(diffuse, raymarch(p + reflect_ray * 0.01f, reflect_ray, userdata + 1), ratio); } vec3 color(0.1); for (vec3 light : get_lights()) { const vec3 light_dir = normalize(p - light); const float light_dist = glm::distance(p, light); color += max(dot(normal, light_dir), 0.0f) * diffuse; const vec3 half = normalize(light_dir + ray); color += pow(max(dot(normal, half), 0.0f), 64.0f); color *= softshadow(p, -light_dir, 0.1, light_dist, 64) * 0.7 + 0.3; } //color *= mix(vec3(1), get_background_color(), 0.5 + 0.5 * dot(normal, vec3(0, -1, 0))); //color = pow(color, vec3(0.45f)); color = clamp(color, 0.0f, 1.0f); return color; }
extern "C" DLLEXPORT miBoolean mib_ray_marcher( miColor *result, miState *state, struct mrm *p) { struct mrm pe; miScalar scale; result->r = result->g = result->b = result->a = 0.0; /* * copy all parameters to a static structure to * avoid all the mi_eval_* calls in the code */ pe.s = *mi_eval_tag(&p->s); pe.distance = *mi_eval_scalar(&p->distance); pe.num = *mi_eval_integer(&p->num); pe.subdiv = *mi_eval_integer(&p->subdiv); pe.contrast = *mi_eval_color(&p->contrast); if (pe.num == 0.0) if (pe.distance > 0.0) pe.num = state->dist / pe.distance; else pe.num = 4; /* default #samples */ if (pe.num < 2) pe.num = 2; /* go! */ raymarch(result, state, &pe); /* normalize result */ scale = 1.0 / (miScalar)pe.num; result->r *= scale; result->g *= scale; result->b *= scale; result->a *= scale; return(miTRUE); }