void MinusRefraction(double *H) { double h1=*H,h2,h3,h4,h5; h2=*H-refraction(M_PI/2-h1,DAVLENIE,TEMPERATURA); h3=*H-refraction(M_PI/2-h2,DAVLENIE,TEMPERATURA); h4=*H-refraction(M_PI/2-h3,DAVLENIE,TEMPERATURA); h5=*H-refraction(M_PI/2-h4,DAVLENIE,TEMPERATURA); *H=h5; //PlusRefraction(&h5); }
t_vec raytracer(t_rayparams *params) { t_raytracer *ray; ray = init_ray(params->over.l); first_loop(ray, params->dir, params->o); if (!ray->ret) return (ray->color); *(params->distance) = ray->ret2; if (ray->ret->light == TRUE) return (set_vec(1, 1, 1)); ray->pi = add_vec(params->o, mul_vec(params->dir, ray->ret2)); ray->tmp = params->over.l; while (ray->tmp) { if (ray->tmp->light == TRUE) { set_nray(ray, params->over.l, params->dir, params->o); shade(ray, params->dir); } ray->tmp = ray->tmp->next; } reflexion(ray, params); refraction(ray, params); return (ray->color); }
Spectrum DirectLightingIntegrator::Li(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Intersection &isect, const Sample *sample, RNG &rng, MemoryArena &arena) const { Spectrum L(0.f); // Evaluate BSDF at hit point BSDF *bsdf = isect.GetBSDF(ray, arena); Vector wo = -ray.d; const Point &p = bsdf->dgShading.p; const Normal &n = bsdf->dgShading.nn; // Compute emitted light if ray hit an area light source L += isect.Le(wo); // Compute direct lighting for _DirectLightingIntegrator_ integrator if (scene->lights.size() > 0) { // Apply direct lighting strategy switch (strategy) { case SAMPLE_ALL_UNIFORM: L += UniformSampleAllLights(scene, renderer, arena, p, n, wo, isect.rayEpsilon, ray.time, bsdf, sample, rng, lightSampleOffsets, bsdfSampleOffsets); break; case SAMPLE_ONE_UNIFORM: L += UniformSampleOneLight(scene, renderer, arena, p, n, wo, isect.rayEpsilon, ray.time, bsdf, sample, rng, lightNumOffset, lightSampleOffsets, bsdfSampleOffsets); break; } } if (ray.depth + 1 < maxDepth) { Vector wi; // Trace rays for specular reflection and refraction Spectrum reflection(0.f); Spectrum refraction(0.f); reflection = SpecularReflect(ray, bsdf, rng, isect, renderer, scene, sample,arena); refraction = SpecularTransmit(ray, bsdf, rng, isect, renderer, scene, sample, arena); L += reflection; L += refraction; } //printf("Size %i \n", NaiadFoam::cur->FoamPlane().size()); return L*bsdf->dgShading.mult; }
Vector3D Ray::Refract(Intersection &inter, Environment &env, int recursion) { Vector3D position = source + direction * inter.dist; double n1, n2; if(ior - 1.0 < 1.0e-6) { n1 = 1.0; n2 = inter.obj->surface().refracao; } else { n1 = inter.obj->surface().refracao; n2 = 1.0; } Vector3D refract_direction = refract(inter.obj->Normal(position), direction, n1, n2); if(refract_direction[0] <= -499) { return BACKGROUND_COLOR; } Ray refraction(position, refract_direction.Normalize()); refraction.ior = n2; return refraction.Trace(env, recursion + 1); }
static unsigned int ray_color(const point3 e, double t, const point3 d, idx_stack *stk, const rectangular_node rectangulars, const sphere_node spheres, const light_node lights, color object_color, int bounces_left) { rectangular_node hit_rec = NULL, light_hit_rec = NULL; sphere_node hit_sphere = NULL, light_hit_sphere = NULL; double diffuse, specular; point3 l, _l, r, rr; object_fill fill; color reflection_part; color refraction_part; /* might be a reflection ray, so check how many times we've bounced */ if (bounces_left == 0) { SET_COLOR(object_color, 0.0, 0.0, 0.0); return 0; } /* check for intersection with a sphere or a rectangular */ intersection ip= ray_hit_object(e, d, t, MAX_DISTANCE, rectangulars, &hit_rec, spheres, &hit_sphere); if (!hit_rec && !hit_sphere) return 0; /* pick the fill of the object that was hit */ fill = hit_rec ? hit_rec->element.rectangular_fill : hit_sphere->element.sphere_fill; void *hit_obj = hit_rec ? (void *) hit_rec : (void *) hit_sphere; /* assume it is a shadow */ SET_COLOR(object_color, 0.0, 0.0, 0.0); for (light_node light = lights; light; light = light->next) { /* calculate the intersection vector pointing at the light */ subtract_vector(ip.point, light->element.position, l); multiply_vector(l, -1, _l); normalize(_l); /* check for intersection with an object. use ignore_me * because we don't care about this normal */ ray_hit_object(ip.point, _l, MIN_DISTANCE, length(l), rectangulars, &light_hit_rec, spheres, &light_hit_sphere); /* the light was not block by itself(lit object) */ if (light_hit_rec || light_hit_sphere) continue; compute_specular_diffuse(&diffuse, &specular, d, l, ip.normal, fill.phong_power); localColor(object_color, light->element.light_color, diffuse, specular, &fill); } reflection(r, d, ip.normal); double idx = idx_stack_top(stk).idx, idx_pass = fill.index_of_refraction; if (idx_stack_top(stk).obj == hit_obj) { idx_stack_pop(stk); idx_pass = idx_stack_top(stk).idx; } else { idx_stack_element e = { .obj = hit_obj, .idx = fill.index_of_refraction }; idx_stack_push(stk, e); } refraction(rr, d, ip.normal, idx, idx_pass); double R = (fill.T > 0.1) ? fresnel(d, rr, ip.normal, idx, idx_pass) : 1.0; /* totalColor = localColor + mix((1-fill.Kd) * fill.R * reflection, T * refraction, R) */ if (fill.R > 0) { /* if we hit something, add the color */ int old_top = stk->top; if (ray_color(ip.point, MIN_DISTANCE, r, stk, rectangulars, spheres, lights, reflection_part, bounces_left - 1)) { multiply_vector(reflection_part, R * (1.0 - fill.Kd) * fill.R, reflection_part); add_vector(object_color, reflection_part, object_color); } stk->top = old_top; } /* calculate refraction ray */ if ((length(rr) > 0.0) && (fill.T > 0.0) && (fill.index_of_refraction > 0.0)) { normalize(rr); if (ray_color(ip.point, MIN_DISTANCE, rr, stk,rectangulars, spheres, lights, refraction_part, bounces_left - 1)) { multiply_vector(refraction_part, (1 - R) * fill.T, refraction_part); add_vector(object_color, refraction_part, object_color); } } protect_color_overflow(object_color); return 1; } /* @param background_color this is not ambient light */ void raytracing(void* args) { arg *data = (arg*) args; point3 u, v, w, d; color object_color = { 0.0, 0.0, 0.0 }; const viewpoint *view = (*data).View; color back = { 0.0 , 0.1 , 0.1 }; uint8_t *pixels = data->pixels; int start_j,end_j; /* Separate to count the pixels */ if(pthread_equal(pthread_self(),THREAD[0])) { start_j = 0; end_j = 128; } else if(pthread_equal(pthread_self(),THREAD[1])) { start_j = 128; end_j = 256; } else if(pthread_equal(pthread_self(),THREAD[2])) { start_j = 256; end_j = 384; } else if(pthread_equal(pthread_self(),THREAD[3])) { start_j = 384; end_j = 512; } /* calculate u, v, w */ calculateBasisVectors(u, v, w, view); idx_stack stk; int factor = sqrt(SAMPLES); #pragma omp parallel for num_threads(64) \ private(stk), private(d), \ private(object_color) for (int j = start_j ; j < end_j; j++) { for (int i = 0 ; i < (*data).row; i++) { double r = 0, g = 0, b = 0; /* MSAA */ for (int s = 0; s < SAMPLES; s++) { idx_stack_init(&stk); rayConstruction(d, u, v, w, i * factor + s / factor, j * factor + s % factor, view, (*data).row * factor, (*data).col * factor); if (ray_color(view->vrp, 0.0, d, &stk,(*data).rectangulars, (*data).spheres, (*data).lights, object_color, MAX_REFLECTION_BOUNCES)) { r += object_color[0]; g += object_color[1]; b += object_color[2]; } else { r += back[0]; g += back[1]; b += back[2]; } pixels[((i + (j * (*data).row)) * 3) + 0] = r * 255 / SAMPLES; pixels[((i + (j * (*data).row)) * 3) + 1] = g * 255 / SAMPLES; pixels[((i + (j * (*data).row)) * 3) + 2] = b * 255 / SAMPLES; } } } }
void PlusRefraction(double *H) { *H+=refraction(M_PI/2-(*H),DAVLENIE,TEMPERATURA); }
/************************************************************************ * This is the recursive ray tracer - you need to implement this! * You should decide what arguments to use. ************************************************************************/ vec3 recursive_ray_trace(vec3 eye, vec3 ray, int num, bool inobj) { // // do your thing here // if(num>step_max) return null_clr; vec3 hit; int isplane; void *sph = intersect_scene(eye, ray, scene, &hit, &isplane); vec3 color = null_clr; if(sph==NULL) { return background_clr; } vec3 lightvec = light1 - hit; vec3 lightvec_normal = normalize(lightvec); vec3 lighthit; int lightisplane; void * light_sph = intersect_scene(hit, lightvec_normal, scene, &lighthit, &lightisplane); vec3 surf_normal = isplane?vec3(0,1,0):sphere_normal(hit, (Spheres*)sph); if(light_sph==NULL) { color += phong(-1*ray, lightvec, surf_normal, sph, hit, isplane); } else { if(!shadow_on) { color += phong(-1*ray, lightvec, surf_normal, sph, hit, isplane); } else { color += get_shadow(-1*ray, lightvec, surf_normal, sph, hit, isplane); } } if(reflect_on) { vec3 reflect_vector = 2*dot(-1*ray, surf_normal)*surf_normal + ray; reflect_vector = normalize(reflect_vector); if(isplane) { color += ((struct plane*)sph)->reflectance * recursive_ray_trace(hit, reflect_vector,num+1, inobj); } else if(!isplane) color += ((Spheres *)sph)->reflectance * recursive_ray_trace(hit, reflect_vector, num+1, inobj); } if(refract_on) { vec3 outlightvector; if(refraction(hit, -1*ray, sph, isplane, inobj, &outlightvector)) { if(!isplane) { // printf("refraction point\n"); Spheres * refractsph = (Spheres *)sph; color += refractsph->refr*recursive_ray_trace(hit, outlightvector, num+1, !inobj); } } } if(diffuse_reflection_on && num<2) { int i; for (i=0;i<DIFFUSE_REFLECTION;i++) { float xtheta = 2.0 * static_cast <float> (rand()) / static_cast <float> (RAND_MAX) - 1.0; float ytheta = 2.0 * static_cast <float> (rand()) / static_cast <float> (RAND_MAX) - 1.0; float ztheta = 2.0 * static_cast <float> (rand()) / static_cast <float> (RAND_MAX) - 1.0; vec3 dfray; dfray = rotateX(xtheta*M_PI,surf_normal); dfray = rotateY(ytheta*M_PI,dfray); dfray = rotateZ(ztheta*M_PI,dfray); color += (0.1/DIFFUSE_REFLECTION)*recursive_ray_trace(hit, dfray, num+1, inobj); } } return color; }
void EnvironmentRender::render(kgmIGraphics::INode* n) { if (!n || n->getNodeType() != kgmIGraphics::NodeMesh) return; kgmMesh* mesh = (kgmMesh*) n->getNodeObject(); if (!mesh) return; kgmMaterial* mtl = n->getNodeMaterial(); if (!mtl) return; mtx4 m = n->getNodeTransform(); vec3 p = vec3(m.m[12], m.m[13], m.m[14]); box3 b = mesh->bound(); vec3 nr = mesh->normal(); vec4 col = mtl->color(); vec4 spec = mtl->specular(); kgmShader* sh = null; gchandle tx = null; if (mtl->envMapping() == kgmMaterial::EnvironmentMappingCube) { m_discard = n; reflection(p, b, m_tx_cube); sh = m_sd_cube; tx = m_tx_cube; //if (mtl->transparency() > 0.01) // refraction(p, b, m_tx_refraction); } else if (mtl->envMapping() == kgmMaterial::EnvironmentMappingPlane) { m_discard = n; reflection(p, nr, gr->m_camera->mPos.z, m_tx_plane); sh = m_sd_plane; tx = m_tx_plane; if (mtl->transparency() > 0.01) refraction(p, nr, m_tx_refraction); } else { return; } if (!sh) { return; } gc->gcSetViewport(0, 0, gr->m_viewport.width(), gr->m_viewport.height(), gr->m_camera->mNear, gr->m_camera->mFar); if (mtl->getTexNormal()) gc->gcSetTexture(1, mtl->getTexNormal()->texture()); else gc->gcSetTexture(1, gr->m_tex_gray->texture()); if (mtl->transparency() > 0.01) gc->gcSetTexture(2, m_tx_refraction); else gc->gcSetTexture(2, gr->m_tex_white->texture()); gc->gcSetTexture(3, tx); m.m[0] += 0.001; m.m[5] += 0.001; m.m[10] += 0.001; vec3 cn = gr->m_camera->mPos - vec3(m.m[12], m.m[13], m.m[14]); cn.normalize(); m.m[12] += 0.001 * cn.x; m.m[13] += 0.001 * cn.y; m.m[14] += 0.001 * cn.z; move.x += 0.001 * mtl->move().x; move.y += 0.001 * mtl->move().y; f32 force = mtl->envIntensity(); f32 random = (f32) rand() / (f32) RAND_MAX; f32 fresnel = mtl->fresnel(); f32 distortion = 0.02 + mtl->distortion(); gc->gcBlend(true, 0, gcblend_srcalpha, gcblend_srcialpha); //gc->gcBlend(true, 0, gcblend_dstcol, gcblend_zero); //gc->gcBlend(true, 0, gcblend_one, gcblend_one); sh->start(); sh->set("g_mProj", gr->m_camera->mProj); sh->set("g_mView", gr->m_camera->mView); sh->set("g_mTran", m); sh->set("g_vUp", gr->m_camera->mUp); sh->set("g_vEye", gr->m_camera->mPos); sh->set("g_vLook", gr->m_camera->mDir); sh->set("g_vColor", col); sh->set("g_vMove", move); sh->set("g_fRandom", random); sh->set("g_fFresnel", fresnel); sh->set("g_fForce", force); sh->set("g_fDistort", distortion); sh->set("g_txNormal", 1); sh->set("g_txSpecular", 2); sh->set("g_txEnvironment", 3); gc->gcBegin(); gr->render(mesh); gc->gcEnd(); sh->stop(); gc->gcBlend(false, 0, 0, 0); }
static unsigned int ray_color(const point3 e, double t, const point3 d, idx_stack *stk, const rectangular_node rectangulars, const sphere_node spheres, const light_node lights, color object_color, int bounces_left) { rectangular_node hit_rec = NULL, light_hit_rec = NULL; sphere_node hit_sphere = NULL, light_hit_sphere = NULL; double diffuse, specular; point3 l, _l, r, rr; object_fill fill; color reflection_part; color refraction_part; /* might be a reflection ray, so check how many times we've bounced */ if (bounces_left == 0) { SET_COLOR(object_color, 0.0, 0.0, 0.0); return 0; } /* check for intersection with a sphere or a rectangular */ intersection ip= ray_hit_object(e, d, t, MAX_DISTANCE, rectangulars, &hit_rec, spheres, &hit_sphere); if (!hit_rec && !hit_sphere) return 0; /* pick the fill of the object that was hit */ fill = hit_rec ? hit_rec->element.rectangular_fill : hit_sphere->element.sphere_fill; void *hit_obj = hit_rec ? (void *) hit_rec : (void *) hit_sphere; /* assume it is a shadow */ SET_COLOR(object_color, 0.0, 0.0, 0.0); for (light_node light = lights; light; light = light->next) { /* calculate the intersection vector pointing at the light */ subtract_vector(ip.point, light->element.position, l); multiply_vector(l, -1, _l); normalize(_l); /* check for intersection with an object. use ignore_me * because we don't care about this normal */ ray_hit_object(ip.point, _l, MIN_DISTANCE, length(l), rectangulars, &light_hit_rec, spheres, &light_hit_sphere); /* the light was not block by itself(lit object) */ if (light_hit_rec || light_hit_sphere) continue; compute_specular_diffuse(&diffuse, &specular, d, l, ip.normal, fill.phong_power); localColor(object_color, light->element.light_color, diffuse, specular, &fill); } reflection(r, d, ip.normal); double idx = idx_stack_top(stk).idx, idx_pass = fill.index_of_refraction; if (idx_stack_top(stk).obj == hit_obj) { idx_stack_pop(stk); idx_pass = idx_stack_top(stk).idx; } else { idx_stack_element e = { .obj = hit_obj, .idx = fill.index_of_refraction }; idx_stack_push(stk, e); } refraction(rr, d, ip.normal, idx, idx_pass); double R = (fill.T > 0.1) ? fresnel(d, rr, ip.normal, idx, idx_pass) : 1.0; /* totalColor = localColor + mix((1-fill.Kd) * fill.R * reflection, T * refraction, R) */ if (fill.R > 0) { /* if we hit something, add the color */ int old_top = stk->top; if (ray_color(ip.point, MIN_DISTANCE, r, stk, rectangulars, spheres, lights, reflection_part, bounces_left - 1)) { multiply_vector(reflection_part, R * (1.0 - fill.Kd) * fill.R, reflection_part); add_vector(object_color, reflection_part, object_color); } stk->top = old_top; } /* calculate refraction ray */ if ((length(rr) > 0.0) && (fill.T > 0.0) && (fill.index_of_refraction > 0.0)) { normalize(rr); if (ray_color(ip.point, MIN_DISTANCE, rr, stk,rectangulars, spheres, lights, refraction_part, bounces_left - 1)) { multiply_vector(refraction_part, (1 - R) * fill.T, refraction_part); add_vector(object_color, refraction_part, object_color); } } protect_color_overflow(object_color); return 1; } static void *parallel (void* range1) { Thread_range *range = (Thread_range *)range1; point3 d; idx_stack stk; color object_color = { 0.0, 0.0, 0.0 }; for (int j = range->height1; j < range->height2; j++) { for (int i = 0; i < range->ptr->width; i++) { double r = 0, g = 0, b = 0; /* MSAA */ for (int s = 0; s < SAMPLES; s++) { idx_stack_init(&stk); rayConstruction(d, range->ptr->u, range->ptr->v, range->ptr->w, i * range->ptr->factor + s / range->ptr->factor, j * range->ptr->factor + s % range->ptr->factor, range->ptr->view, range->ptr->width * range->ptr->factor, range->ptr->height * range->ptr->factor); if (ray_color(range->ptr->view->vrp, 0.0, d, &(stk), range->ptr->rectangulars, range->ptr->spheres, range->ptr->lights, object_color, MAX_REFLECTION_BOUNCES)) { r += object_color[0]; g += object_color[1]; b += object_color[2]; } else { r += range->ptr->background_color[0]; g += range->ptr->background_color[1]; b += range->ptr->background_color[2]; } range->ptr->pixels[((i + (j * range->ptr->width)) * 3) + 0] = r * 255 / SAMPLES; range->ptr->pixels[((i + (j * range->ptr->width)) * 3) + 1] = g * 255 / SAMPLES; range->ptr->pixels[((i + (j * range->ptr->width)) * 3) + 2] = b * 255 / SAMPLES; } } } return NULL; }