Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
//------------------------------------------------------------------------------------------------
// 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);
}
Esempio n. 4
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();
    
    

}
Esempio n. 5
0
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();
	}
Esempio n. 7
0
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));
}