void SceneLoader::ImportMaterial(Scene& scene, const aiMaterial* const material) { aiString ai_name; material->Get(AI_MATKEY_NAME, ai_name); aiColor4D diffuse_color(0.0f, 0.0f, 0.0f, 1.0f); material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse_color); aiColor4D specular_color(0.0f, 0.0f, 0.0f, 1.0f); material->Get(AI_MATKEY_COLOR_SPECULAR, specular_color); aiColor4D ambient_color(0.0f, 0.0f, 0.0f, 1.0f); material->Get(AI_MATKEY_COLOR_AMBIENT, ambient_color); aiColor4D emissive_color(0.0f, 0.0f, 0.0f, 1.0f); material->Get(AI_MATKEY_COLOR_EMISSIVE, emissive_color); float opacity = 0.0f; material->Get(AI_MATKEY_OPACITY, opacity); float reflectivity = 0.0f; material->Get(AI_MATKEY_REFLECTIVITY, reflectivity); float refractivity = 0.0f; material->Get(AI_MATKEY_REFRACTI, refractivity); float shininess = 0.0f; material->Get(AI_MATKEY_SHININESS, shininess); std::string name; name = std::string(ai_name.C_Str()); Material mat; mat.kd = glm::vec3(diffuse_color[0], diffuse_color[1], diffuse_color[2]); mat.ks = glm::vec3(specular_color[0], specular_color[1], specular_color[2]); mat.ka = glm::vec3(ambient_color[0], ambient_color[1], ambient_color[2]); mat.ke = glm::vec3(emissive_color[0], emissive_color[1], emissive_color[2]); mat.kr = reflectivity; mat.kt = refractivity; mat.tr = opacity; mat.ns = shininess; scene.AddMaterial(name, mat); }
t_color shade(t_env *e, t_obj object, t_vector3d inter, t_vector3d ray) { t_color final_color; t_vector3d n; t_obj *light; int i; t_list *cursor; i = 0; cursor = e->list_spot; final_color = set_rgb(0, 0, 0); while (cursor) { i++; light = (t_obj *)cursor->content; light_rotate(e, &object, &inter, light); n = calcul_normal(&object, &inter); final_color = add_rgb(final_color, diffuse_color(light, n, &object)); final_color = add_rgb(final_color, specular_color(light, n, &object, ray)); cursor = cursor->next; } if (i > 0) final_color = set_rgb(final_color.r / i, final_color.g / i, final_color.b / i); valid_rgb(&final_color); return (final_color); }
//------------------------------------------------------------------------------------------------ // zacatek 3d kresleni //------------------------------------------------------------------------------------------------ void ddx2StartRender2D(void) { set_matrix_2d(SCREEN_XRES, SCREEN_YRES); glColor4f(1, 1, 1, 1); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_LEQUAL, 0); specular_off(); specular_color(0, 0, 0); }
void testApp::setup(){ ofSetFrameRate(60); ofBackgroundHex(0xaaaaaa); easyCam.setDistance(22); ofSetLineWidth(3); ofSetVerticalSync(true); // this uses depth information for occlusion // rather than always drawing things on top of each other glEnable(GL_DEPTH_TEST); // ofBox uses texture coordinates from 0-1, so you can load whatever // sized images you want and still use them to texture your box // but we have to explicitly normalize our tex coords here ofEnableNormalizedTexCoords(); //create a bunch of custom nodes for(double z = 0; z > -36*M_PI; z +=zStep){ double x = -10; double y = tileLayoutFunction(z); double blueValue = fmod(-floor(z*2),255); CustomNode* node = new CustomNode(); node->setPosition(x, y, z); node->red = 0; node->green = 60; node->blue = blueValue; customNodes.push_back(node); } firstNodePosition = customNodes[0]->getPosition(); lastNodePosition = customNodes[customNodes.size()-1]->getPosition(); light.enable(); light.setPosition(0, 0, 150); light.setDirectional(); ofFloatColor ambient_color(1.0, 0.0, 0.0,1.0); ofFloatColor diffuse_color(1.0, 1.0, 1.0); ofFloatColor specular_color(0.0, 1.0, 0.0); light.setAmbientColor(ambient_color); light.setDiffuseColor(diffuse_color); light.setSpecularColor(specular_color); easyCam.disableMouseInput(); }
void Process(VertexData& vertex) { Vec3<int> mec = Vec3<int>(gstate.getMaterialEmissiveR(), gstate.getMaterialEmissiveG(), gstate.getMaterialEmissiveB()); Vec3<int> mac = (gstate.materialupdate&1) ? vertex.color0.rgb() : Vec3<int>(gstate.getMaterialAmbientR(), gstate.getMaterialAmbientG(), gstate.getMaterialAmbientB()); Vec3<int> final_color = mec + mac * Vec3<int>(gstate.getAmbientR(), gstate.getAmbientG(), gstate.getAmbientB()) / 255; Vec3<int> specular_color(0, 0, 0); for (unsigned int light = 0; light < 4; ++light) { // Always calculate texture coords from lighting results if environment mapping is active // TODO: specular lighting should affect this, too! // TODO: Not sure if this really should be done even if lighting is disabled altogether if (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP) { Vec3<float> L = Vec3<float>(getFloat24(gstate.lpos[3*light]&0xFFFFFF), getFloat24(gstate.lpos[3*light+1]&0xFFFFFF),getFloat24(gstate.lpos[3*light+2]&0xFFFFFF)); float diffuse_factor = Dot(L,vertex.worldnormal) / L.Length() / vertex.worldnormal.Length(); if (gstate.getUVLS0() == light) vertex.texturecoords.s() = (diffuse_factor + 1.f) / 2.f; if (gstate.getUVLS1() == light) vertex.texturecoords.t() = (diffuse_factor + 1.f) / 2.f; } } if (!gstate.isLightingEnabled()) return; for (unsigned int light = 0; light < 4; ++light) { if (!gstate.isLightChanEnabled(light)) continue; // L = vector from vertex to light source // TODO: Should transfer the light positions to world/view space for these calculations Vec3<float> L = Vec3<float>(getFloat24(gstate.lpos[3*light]&0xFFFFFF), getFloat24(gstate.lpos[3*light+1]&0xFFFFFF),getFloat24(gstate.lpos[3*light+2]&0xFFFFFF)); L -= vertex.worldpos; float d = L.Length(); float lka = getFloat24(gstate.latt[3*light]&0xFFFFFF); float lkb = getFloat24(gstate.latt[3*light+1]&0xFFFFFF); float lkc = getFloat24(gstate.latt[3*light+2]&0xFFFFFF); float att = 1.f; if (!gstate.isDirectionalLight(light)) { att = 1.f / (lka + lkb * d + lkc * d * d); if (att > 1.f) att = 1.f; if (att < 0.f) att = 0.f; } float spot = 1.f; if (gstate.isSpotLight(light)) { Vec3<float> dir = Vec3<float>(getFloat24(gstate.ldir[3*light]&0xFFFFFF), getFloat24(gstate.ldir[3*light+1]&0xFFFFFF),getFloat24(gstate.ldir[3*light+2]&0xFFFFFF)); float _spot = Dot(-L,dir) / d / dir.Length(); float cutoff = getFloat24(gstate.lcutoff[light]&0xFFFFFF); if (_spot > cutoff) { spot = _spot; float conv = getFloat24(gstate.lconv[light]&0xFFFFFF); spot = pow(_spot, conv); } else { spot = 0.f; } } // ambient lighting Vec3<int> lac = Vec3<int>(gstate.getLightAmbientColorR(light), gstate.getLightAmbientColorG(light), gstate.getLightAmbientColorB(light)); final_color.r() += (int)(att * spot * lac.r() * mac.r() / 255); final_color.g() += (int)(att * spot * lac.g() * mac.g() / 255); final_color.b() += (int)(att * spot * lac.b() * mac.b() / 255); // diffuse lighting Vec3<int> ldc = Vec3<int>(gstate.getDiffuseColorR(light), gstate.getDiffuseColorG(light), gstate.getDiffuseColorB(light)); Vec3<int> mdc = (gstate.materialupdate&2) ? vertex.color0.rgb() : Vec3<int>(gstate.getMaterialDiffuseR(), gstate.getMaterialDiffuseG(), gstate.getMaterialDiffuseB()); float diffuse_factor = Dot(L,vertex.worldnormal) / d / vertex.worldnormal.Length(); if (gstate.isUsingPoweredDiffuseLight(light)) { float k = getFloat24(gstate.materialspecularcoef&0xFFFFFF); diffuse_factor = pow(diffuse_factor, k); } if (diffuse_factor > 0.f) { final_color.r() += (int)(att * spot * ldc.r() * mdc.r() * diffuse_factor / 255); final_color.g() += (int)(att * spot * ldc.g() * mdc.g() * diffuse_factor / 255); final_color.b() += (int)(att * spot * ldc.b() * mdc.b() * diffuse_factor / 255); } if (gstate.isUsingSpecularLight(light)) { Vec3<float> E(0.f, 0.f, 1.f); Mat3x3<float> view_matrix(gstate.viewMatrix); Vec3<float> worldE = view_matrix.Inverse() * (E - Vec3<float>(gstate.viewMatrix[9], gstate.viewMatrix[10], gstate.viewMatrix[11])); Vec3<float> H = worldE / worldE.Length() + L / L.Length(); Vec3<int> lsc = Vec3<int>(gstate.getSpecularColorR(light), gstate.getSpecularColorG(light), gstate.getSpecularColorB(light)); Vec3<int> msc = (gstate.materialupdate&4) ? vertex.color0.rgb() : Vec3<int>(gstate.getMaterialSpecularR(), gstate.getMaterialSpecularG(), gstate.getMaterialSpecularB()); float specular_factor = Dot(H,vertex.worldnormal) / H.Length() / vertex.worldnormal.Length(); float k = getFloat24(gstate.materialspecularcoef&0xFFFFFF); specular_factor = pow(specular_factor, k); if (specular_factor > 0.f) { specular_color.r() += (int)(att * spot * lsc.r() * msc.r() * specular_factor / 255); specular_color.g() += (int)(att * spot * lsc.g() * msc.g() * specular_factor / 255); specular_color.b() += (int)(att * spot * lsc.b() * msc.b() * specular_factor / 255); } } } vertex.color0.r() = final_color.r(); vertex.color0.g() = final_color.g(); vertex.color0.b() = final_color.b(); if (gstate.isUsingSecondaryColor()) { vertex.color1 = specular_color; } else { vertex.color0.r() += specular_color.r(); vertex.color0.g() += specular_color.g(); vertex.color0.b() += specular_color.b(); vertex.color1 = Vec3<int>(0, 0, 0); } int maa = (gstate.materialupdate&1) ? vertex.color0.a() : gstate.getMaterialAmbientA(); vertex.color0.a() = gstate.getAmbientA() * maa / 255; if (vertex.color0.r() > 255) vertex.color0.r() = 255; if (vertex.color0.g() > 255) vertex.color0.g() = 255; if (vertex.color0.b() > 255) vertex.color0.b() = 255; if (vertex.color0.a() > 255) vertex.color0.a() = 255; if (vertex.color1.r() > 255) vertex.color1.r() = 255; if (vertex.color1.g() > 255) vertex.color1.g() = 255; if (vertex.color1.b() > 255) vertex.color1.b() = 255; if (vertex.color0.r() < 0) vertex.color0.r() = 0; if (vertex.color0.g() < 0) vertex.color0.g() = 0; if (vertex.color0.b() < 0) vertex.color0.b() = 0; if (vertex.color0.a() < 0) vertex.color0.a() = 0; if (vertex.color1.r() < 0) vertex.color1.r() = 0; if (vertex.color1.g() < 0) vertex.color1.g() = 0; if (vertex.color1.b() < 0) vertex.color1.b() = 0; }
void main(void *arg) { const color WHITE(1.0f); //----------------------------------------- const color Cs(i_color()); color diffuse_color(1.0f, 1.0f, 1.0f); scalar diffuse_weight = i_diffuse(); color specular_color(i_specularColor()); scalar specular_weight= 0.2f;//cosinePower scalar roughness = 0.0f; int specular_mode = 1;//[0,3] scalar glossiness = 1.0f; color reflection_color(i_reflectedColor()); scalar reflection_weight = 0.5f; color refraction_color(1.0f, 1.0f, 1.0f); scalar refraction_weight= 0.0f;//zero will lead a dark image scalar refraction_glossiness = 0.5f; scalar refraction_thickness= 2.0f;//surfaceThickness color translucency_color(i_transparency()); scalar translucency_weight = i_translucence(); scalar anisotropy = 1.0f; scalar rotation = 0.0f; scalar ior = 1.5f;//refractiveIndex bool fresnel_by_ior = eiTRUE; scalar fresnel_0_degree_refl = 0.2f; scalar fresnel_90_degree_refl = 1.0f; scalar fresnel_curve= 5.0f; bool is_metal = eiTRUE; int diffuse_samples = 8; int reflection_samples= 4; int refraction_samples= 4; scalar cutoff_threshold = LIQ_SCALAR_EPSILON; eiTag bump_shader = eiNULL_TAG; scalar bump_factor= 0.3f; if( liq_UserDefinedNormal() == 0 ) { i_normalCamera() = N; } //----------------------------------------- vector In = normalize( I ); normal Nn = normalize( i_normalCamera() ); normal Nf = ShadingNormal(Nn); vector V = -In; //----------------------------------------- // specular is the percentage of specular lighting // limit weights in range [0, 1] specular_weight = clamp(specular_weight, 0.0f, 1.0f); refraction_weight = clamp(refraction_weight, 0.0f, 1.0f); translucency_weight = clamp(translucency_weight, 0.0f, 1.0f); // automatically compute Kd, Ks, Kt in an energy conserving way diffuse_weight = clamp(diffuse_weight, 0.0f, 1.0f); reflection_weight = clamp(reflection_weight, 0.0f, 1.0f); // the energy balancing between reflection and refraction is // dominated by Fresnel law //color Kt(refraction_color * (spec * refr * (1.0f - trans)) * (is_metal?Cs:WHITE)); // this is a monolithic shader which also serves as shadow shader if (ray_type == EI_RAY_SHADOW) { main_shadow(arg, refraction_color * (specular_weight * refraction_weight * (1.0f - translucency_weight)), refraction_thickness, cutoff_threshold); return; } // for surface shader, we call bump shader eiTag shader = bump_shader; if (shader != eiNULL_TAG) { call_bump_shader(shader, bump_factor); } //color Kc(refraction_color * (spec * refr * trans) * (is_metal?Cs:WHITE)); // non-reflected energy is absorbed //color Ks(specular_color * spec * (1.0f - refl) * (is_metal?Cs:WHITE)); //color Kr(reflection_color * (spec * refl) * (is_metal?Cs:WHITE)); // surface color will impact specular for metal material //const color Cs(surface_color); // const color Kd( Cs *(1.0f - spec) * diff ); // const int spec_mode = clamp(specular_mode, 0, 3); computeSurface( i_color(),//outColor(),//out->Ci,// i_transparency(),//out->Oi,// i_matteOpacityMode(), i_matteOpacity(), o_outColor(),//out->Ci,// o_outTransparency()//out->Oi// ); out->Ci = o_outColor(); out->Oi = o_outTransparency(); // apply rotation scalar deg = rotation; if (deg != 0.0f) { dPdu = rotate_vector(dPdu, N, radians(deg)); dPdv = cross(dPdu, N); u_axis = normalize(dPdu); v_axis = normalize(dPdv); } // set the glossiness scale based on the chosen BSDF scalar glossiness_scale = 370.37f; if (specular_mode == 1) { glossiness_scale = 125.0f; } else if (specular_mode == 3) { // scale to make the same glossiness parameter // results in similar lobe for different BSDFs glossiness_scale = 22.88f; } // scalar aniso = anisotropy; int refl_samples = reflection_samples; int refr_samples = refraction_samples; // prepare outgoing direction in local frame const vector wo(normalize(to_local(V))); // construct BSDFs OrenNayar Rd(roughness); scalar shiny_u = glossiness; if (shiny_u < eiSCALAR_EPS) { shiny_u = eiSCALAR_EPS; refl_samples = 1; } shiny_u = max(0.0f, glossiness_scale / shiny_u); scalar shiny_v = max(0.0f, shiny_u * anisotropy); scalar IOR = ior; eiBool fresn_by_ior = fresnel_by_ior; scalar fresn_0_degree_refl = fresnel_0_degree_refl; scalar fresn_90_degree_refl = fresnel_90_degree_refl; scalar fresn_curve = fresnel_curve; union { eiByte by_ior[sizeof(FresnelByIOR)]; eiByte schlick[sizeof(FresnelSchlick)]; } F_storage; union { eiByte by_ior[sizeof(FresnelByIOR)]; eiByte schlick[sizeof(FresnelSchlick)]; } invF_storage; Fresnel *F = NULL; Fresnel *invF = NULL; if (fresn_by_ior) { F = new (F_storage.by_ior) FresnelByIOR(IOR); invF = new (invF_storage.by_ior) InvFresnelByIOR(IOR); } else { F = new (F_storage.schlick) FresnelSchlick( fresn_0_degree_refl, fresn_90_degree_refl, fresn_curve); invF = new (invF_storage.schlick) InvFresnelSchlick( fresn_0_degree_refl, fresn_90_degree_refl, fresn_curve); } union { eiByte ward[sizeof(Ward)]; eiByte phong[sizeof(StretchedPhong)]; eiByte blinn[sizeof(Blinn)]; eiByte cooktorrance[sizeof(CookTorrance)]; } Rs_storage; BSDF *Rs = NULL; switch (specular_mode) { case 0: Rs = new (Rs_storage.ward) Ward(F, shiny_u, shiny_v); break; case 1: Rs = new (Rs_storage.phong) StretchedPhong(F, shiny_u); break; case 2: Rs = new (Rs_storage.blinn) Blinn(F, shiny_u); break; case 3: Rs = new (Rs_storage.cooktorrance) CookTorrance(F, 1.0f / shiny_u); break; } SpecularReflection Rr(F); scalar refr_shiny_u = refraction_glossiness; if (refr_shiny_u < eiSCALAR_EPS) { refr_shiny_u = eiSCALAR_EPS; refr_samples = 1; } refr_shiny_u = max(0.0f, glossiness_scale / refr_shiny_u); scalar refr_shiny_v = max(0.0f, shiny_u * anisotropy); union { eiByte ward[sizeof(Ward)]; eiByte phong[sizeof(StretchedPhong)]; eiByte blinn[sizeof(Blinn)]; eiByte cooktorrance[sizeof(CookTorrance)]; } Rts_storage; BSDF *Rts = NULL; switch (specular_mode) { case 0: Rts = new (Rts_storage.ward) Ward(invF, refr_shiny_u, refr_shiny_v); break; case 1: Rts = new (Rts_storage.phong) StretchedPhong(invF, refr_shiny_u); break; case 2: Rts = new (Rts_storage.blinn) Blinn(invF, refr_shiny_u); break; case 3: Rts = new (Rts_storage.cooktorrance) CookTorrance(invF, 1.0f / refr_shiny_u); break; } scalar refr_thickness = refraction_thickness; // internal scale for refraction thickness, make it smaller BRDFtoBTDF Rt(Rts, IOR, refr_thickness * 0.1f, this); color Cdiffuse(0.0f); color Cspecular(0.0f); // don't integrate direct lighting if the ray hits the back face if (dot_nd < 0.0f) { // integrate direct lighting from the front side //out->Ci += integrate_direct_lighting(/*Kd*/diffuse(), Rd, wo); //out->Ci *= i_diffuse() * getDiffuse(Nf, eiFALSE, eiFALSE); Cdiffuse += i_diffuse() * getDiffuse(Nf, eiFALSE, eiFALSE); //out->Ci += integrate_direct_lighting(Ks, *Rs, wo); //out->Ci += i_specularColor() * getPhong (Nf, V, i_cosinePower(), eiFALSE, eiFALSE); Cspecular += i_specularColor() * getPhong (Nf, V, i_cosinePower(), eiFALSE, eiFALSE); } // integrate for translucency from the back side if (!almost_black( refraction_color * (specular_weight * refraction_weight * translucency_weight)*(is_metal?Cs:WHITE) ) && //almost_black(Kc) (refr_thickness > 0.0f || dot_nd > 0.0f)) { vector old_dPdu(dPdu); vector old_dPdv(dPdv); vector old_u_axis(u_axis); vector old_v_axis(v_axis); normal old_N(N); vector new_wo(wo); if (dot_nd < 0.0f) { dPdu = old_dPdv; dPdv = old_dPdu; u_axis = old_v_axis; v_axis = old_u_axis; N = -N; new_wo = vector(wo.y, wo.x, -wo.z); } // integrate direct lighting from the back side //out->Ci += Kc * integrate_direct_lighting(/*Kd*/i_diffuse(), Rd, new_wo); //out->Ci += i_diffuse() * getDiffuse(Nf, eiFALSE, eiFALSE); Cdiffuse += i_diffuse() * getDiffuse(Nf, eiFALSE, eiFALSE); //out->Ci += Kc * integrate_direct_lighting(Ks, *Rs, new_wo); //out->Ci += i_specularColor() * getPhong (Nf, V, i_cosinePower(), eiFALSE, eiFALSE); Cspecular += i_specularColor() * getPhong (Nf, V, i_cosinePower(), eiFALSE, eiFALSE); N = old_N; u_axis = old_u_axis; v_axis = old_v_axis; dPdu = old_dPdu; dPdv = old_dPdv; } scalar cutoff_thresh = cutoff_threshold; color CReflectSpecular(0.0f); // integrate indirect specular lighting if (!almost_black( specular_color * (specular_weight * (1.0f - reflection_weight))*(is_metal?Cs:WHITE) ) && dot_nd < 0.0f)//almost_black(Ks) { IntegrateOptions opt; opt.ray_type = EI_RAY_REFLECT_GLOSSY; opt.min_samples = opt.max_samples = refl_samples; opt.cutoff_threshold = cutoff_thresh; CReflectSpecular = integrate(wo, *Rs, opt); } color CSpecularReflection(0.0f); // integrate perfect specular reflection if (!almost_black(reflection_color * (specular_weight * reflection_weight) * (is_metal?Cs:WHITE)) && dot_nd < 0.0f)//almost_black(Kr) { IntegrateOptions opt; opt.ray_type = EI_RAY_REFLECT_GLOSSY; opt.min_samples = opt.max_samples = 1; // force one sample for reflection opt.cutoff_threshold = cutoff_thresh; // the direct lighting of this BRDF is not accounted, // so we trace lights here to compensate opt.trace_lights = eiTRUE; CSpecularReflection = integrate(wo, Rr, opt); } color CReflectDiffuse(0.0f); // integrate indirect diffuse lighting (color bleeding) if (!almost_black( Cs *(1.0f - specular_weight) * diffuse_weight ) && dot_nd < 0.0f)//almost_black(Kd) { IntegrateOptions opt; opt.ray_type = EI_RAY_REFLECT_DIFFUSE; opt.min_samples = opt.max_samples = diffuse_samples; opt.cutoff_threshold = cutoff_thresh; CReflectDiffuse = integrate(wo, Rd, opt); } color CRefraction(0.0f); // integrate refraction if ( !almost_black(refraction_color * specular_weight * refraction_weight * (1.0f-translucency_weight)*(is_metal?Cs:WHITE)) ) //almost_black(Kt) { IntegrateOptions opt; opt.ray_type = EI_RAY_REFRACT_GLOSSY; if (IOR == 1.0f) { opt.ray_type = EI_RAY_TRANSPARENT; } opt.min_samples = opt.max_samples = refr_samples; opt.cutoff_threshold = cutoff_thresh; // account for refractive caustics opt.trace_lights = eiTRUE; CRefraction = integrate(wo, Rt, opt); } out->Ci *= (Cdiffuse + CReflectDiffuse * Cs *(1.0f - specular_weight) * diffuse_weight//Kd ); out->Ci += (Cspecular + CReflectSpecular* specular_color * specular_weight * (1.0f - reflection_weight)*(is_metal?Cs:WHITE)//Ks + CSpecularReflection* reflection_color * specular_weight * reflection_weight * (is_metal?Cs:WHITE)//Kr + CRefraction* refraction_color * specular_weight * refraction_weight * (1.0f-translucency_weight) * (is_metal?Cs:WHITE)//Kt ); #ifdef USE_AOV_aov_ambient aov_ambient() += ( i_ambientColor() *(CReflectDiffuse * Cs *(1.0f - specular_weight) * diffuse_weight//Kd ) ) * (1.0f - o_outTransparency()); #endif #ifdef USE_AOV_aov_diffuse aov_diffuse() += ( Cdiffuse * i_color() ) * (1.0f - o_outTransparency()); #endif #ifdef USE_AOV_aov_specular aov_specular() += (Cspecular + CReflectSpecular* specular_color * specular_weight * (1.0f - reflection_weight)*(is_metal?Cs:WHITE)//Ks + CSpecularReflection* reflection_color * specular_weight * reflection_weight * (is_metal?Cs:WHITE)//Kr + CRefraction* refraction_color * specular_weight * refraction_weight * (1.0f-translucency_weight) * (is_metal?Cs:WHITE)//Kt ); #endif if ( ! less_than( &i_transparency(), LIQ_SCALAR_EPSILON ) ) {//transparent out->Ci = out->Ci * ( 1.0f - i_transparency() ) + trace_transparent() * i_transparency(); }//else{ opacity } Rs->~BSDF(); Rts->~BSDF(); }
color_t Shape::phong(const point3d_t p, const point2d_t tc, const point3d_t n, const ray_t *ray) const { const World *world = this->world(); color_t texture = material.texture == 0 ? material.color : material.texture(tc); if(!world) return texture; boost::numeric::ublas::vector<double> color = vector3d(0.0, 0.0, 0.0); boost::numeric::ublas::vector<double> vn = vector3d(n.x, n.y, n.z); boost::numeric::ublas::vector<double> vv = vector3d(-ray->d.x, -ray->d.y, -ray->d.z); double dvn = dot_prod(vv, vn); double nit = 1.0 / material.n; if (dvn < 0.0) { nit = material.n / 1.0; vn = -vn; dvn = dot_prod(vv, vn); } boost::numeric::ublas::vector<double> texture_color = vector3d(texture.r, texture.g, texture.b); boost::numeric::ublas::vector<double> specular_color = vector3d(material.specular.r, material.specular.g, material.specular.b); boost::numeric::ublas::vector<double> ambient_color = vector3d(world->ambient.r, world->ambient.g, world->ambient.b); // ambient color += material.ka * vector3d(ambient_color(0) * texture_color(0), ambient_color(1) * texture_color(1), ambient_color(2) * texture_color(2)); double kr = material.kr; // transmission if(ray->ttl > 0 && material.kt > 0.0 && material.n > 0.0) { double l = 1.0 + nit*nit*(dvn*dvn - 1.0); if(l >= 0.0) { boost::numeric::ublas::vector<double> d = -nit * vv; d += (nit*dvn - sqrt(l)) * vn; d = normalize(d); ray_t transmission_ray; transmission_ray.p = p; transmission_ray.d = POINT3D(d(0), d(1), d(2)); transmission_ray.near = 0.000000001; transmission_ray.far = DOUBLE_INF; transmission_ray.ttl = ray->ttl-1; color_t transmission_color = world->trace(&transmission_ray); color += material.kt * vector3d(transmission_color.r, transmission_color.g, transmission_color.b); } else kr += material.kt; } // reflection if(ray->ttl > 0 && kr > 0.0) { boost::numeric::ublas::vector<double> vr = 2.0 * dot_prod(vv, vn) * vn - vv; ray_t reflection_ray; reflection_ray.p = p; reflection_ray.d = POINT3D(vr(0), vr(1), vr(2)); reflection_ray.near = 0.000001; reflection_ray.far = DOUBLE_INF; reflection_ray.ttl = ray->ttl-1; color_t reflection_color = world->trace(&reflection_ray); color += kr * vector3d(reflection_color.r, reflection_color.g, reflection_color.b); } // lights for(std::vector<Light*>::const_iterator i = world->lights.begin(); i != world->lights.end(); i++) { // shadow ray point3d_t s = (*i)->getSource(); boost::numeric::ublas::vector<double> vs = vector3d(s.x - p.x, s.y - p.y, s.z - p.z); double light_distance = sqrt(dot_prod(vs, vs)); vs = normalize(vs); ray_t shadow_ray; shadow_ray.p = p; shadow_ray.d = POINT3D(vs(0), vs(1), vs(2)); shadow_ray.near = 0.00000001; shadow_ray.far = DOUBLE_INF; shadow_ray.ttl = 1; if(world->hit(&shadow_ray).t < light_distance) continue; light_t light = (*i)->getLight(); boost::numeric::ublas::vector<double> light_color = vector3d(light.color.r, light.color.g, light.color.b); // diffuse color += material.kd * dot_prod(vs, vn) * vector3d(light_color(0) * texture_color(0), light_color(1) * texture_color(1), light_color(2) * texture_color(2)); // specular boost::numeric::ublas::vector<double> vr = 2.0 * dot_prod(vs, vn) * vn - vs; double vra = dot_prod(vr, vv); if(vra >= 0.0) color += material.ks * pow(vra, material.ke) * vector3d(light_color(0) * specular_color(0), light_color(1) * specular_color(1), light_color(2) * specular_color(2)); } // keep color in range if(color(0) > 1.0) color(0) = 1.0; if(color(0) < 0.0) color(0) = 0.0; if(color(1) > 1.0) color(1) = 1.0; if(color(1) < 0.0) color(1) = 0.0; if(color(2) > 1.0) color(2) = 1.0; if(color(2) < 0.0) color(2) = 0.0; return COLOR(color(0), color(1), color(2)); }