Esempio n. 1
0
Color World::runPhotonCache(vec origin, vec direction) const {
	HitInfo eyeInfo;
	objects->hit(&eyeInfo, origin, direction);
	
	if (!eyeInfo.hit)
		return Color(0,0,0);
	
	
	Color initc = eyeInfo.mat->getColor();
	Color accum;
	
	for (int d = 0; d < depth; d++) {
		HitInfo newI;
		newI.follow(eyeInfo);
		
		vec newDirection = eyeInfo.mat->sample(eyeInfo.incoming, eyeInfo.normal);
		
		objects->hit(&newI, eyeInfo.location, newDirection);
		
		if (newI.hit) {
			Color newc = initc * eyeInfo.mat->getColor() *
						Color(1.0, 1.0, 1.0) *
			eyeInfo.mat->sampledPdf(eyeInfo.incoming, newDirection, eyeInfo.normal);
			accum += newc * pc->seenValue(eyeInfo.location, newI.location, &newI, sampleRadius) * (1.0 / depth);
		}
	}
	
	return accum;
}
Esempio n. 2
0
void BeginRender()
{
	Color24 *temp;
	temp = renderImage.GetPixels();
	float *zBuffer = renderImage.GetZBuffer();
	Color materialColor;
	Color24 newColor;
	for (int i = 0; i < camera.imgWidth; i++)
	{
		for (int j = 0; j < camera.imgHeight; j++)
		{
			Ray currentRay = ComputeCameraRay(i, j);
			HitInfo hInfo;
			hInfo.Init();
			bool value = TraceRay(currentRay, hInfo, &rootNode);
			if (value) {
				hInfo.node->FromNodeCoords(hInfo);
				const Material *m = hInfo.node->GetMaterial();
				materialColor = m->Shade(currentRay, hInfo, lights);
				temp[camera.imgWidth*j + i].r = (materialColor.r)*255;
				temp[camera.imgWidth*j + i].g = (materialColor.g)*255;
				temp[camera.imgWidth*j + i].b = (materialColor.b)*255;
			}
			else {
				temp[camera.imgWidth*j + i].r = 0;
				temp[camera.imgWidth*j + i].g = 0;
				temp[camera.imgWidth*j + i].b = 0;
			}
			zBuffer[camera.imgWidth*j + i] = hInfo.z;
		}
	}
	renderImage.ComputeZBufferImage();
	renderImage.SaveImage("Output");
}
Esempio n. 3
0
ColorTimeCache World::runTimePhotonCache(vec origin, vec direction) const {
	ColorTimeCache ctc;
	HitInfo eyeInfo;
	objects->hit(&eyeInfo, origin, direction);
	
	if (!eyeInfo.hit)
		return ctc;
	
	
	Color initc = eyeInfo.mat->getColor();
	
	for (int d = 0; d < depth; d++) {
		HitInfo newI;
		newI.follow(eyeInfo);
		
		vec newDirection = eyeInfo.mat->sample(eyeInfo.incoming, eyeInfo.normal);
		
		objects->hit(&newI, eyeInfo.location, newDirection);
		
		if (newI.hit) {
			Color newc = initc * eyeInfo.mat->getColor() * (1.0/depth) *
			eyeInfo.mat->sampledPdf(eyeInfo.incoming, newDirection, eyeInfo.normal);
			
			ctc.addWeighted(newI.distance + eyeInfo.distance, newc,
							pc->seenTimeValue(eyeInfo.location, newI.location, &newI, sampleRadius));
		}
	}
	return ctc;
}
Esempio n. 4
0
void BeginRender()
{

    cout<<"\nBeginning Render...";
    
    float alpha = camera.fov;
    float l = 1.0;
    float h = l * tan(alpha/2.0 *(M_PI/180));
    float aspectRatio = (float)camera.imgWidth/camera.imgHeight;
    float s = aspectRatio * h;
    float dx = (2 * s)/camera.imgWidth;
    float dy = -(2 * h)/camera.imgHeight;
    float dxx = dx/2,dyy=dy/2;
    Point3 K(-s,h,-l);
    K.x += dxx;
    K.y += dyy;
    for(int i = 0; i< camera.imgHeight; i++){
        
        for(int j = 0; j<camera.imgWidth; j++){
            
            K.x += dx;
            Matrix3 RotMat;
            
            Point3 dvec = camera.dir - camera.pos;
            Point3 svec = camera.up.Cross(dvec);
            dvec.Normalize();
            svec.Normalize();
            camera.up.Normalize();
            RotMat.Set(svec,camera.up, dvec);
            Ray r(camera.pos, K);
            
            r.dir=r.dir*RotMat;
            
            r.dir.Normalize();
            
            HitInfo hInfo;
            hInfo.Init();
            if(rootNode.GetNumChild()>0){
//                for(int k=0; k < rootNode.GetNumChild(); ++k){
//                    RayTrace(rootNode.GetChild(k),r,i * camera.imgWidth + j);
//                }
                if(RayTrace_2(r, hInfo))
                {
                    renderImage.PutPixel(i *camera.imgWidth+j, white, hInfo.z);
                }
                else renderImage.PutPixel(i *camera.imgWidth+j, black, BIGFLOAT);
            }
            
            
        }
        K.x = -s;
        K.x += dxx;
        K.y += dy;
    }
    cout<<"Render Complete"<<endl;
    renderImage.ComputeZBufferImage();
    renderImage.SaveZImage("/Users/varunk/Desktop/RayTracerProj1/RayTracerProj1/zbuffer.ppm");
    renderImage.SaveImage("/Users/varunk/Desktop/RayTracerProj1/RayTracerProj1/renderimage.ppm");
    
}
Esempio n. 5
0
float GenLight::Shadow(Ray ray, float t_max)
{
	HitInfo hInfo;
	hInfo.Init();
	hInfo.z = t_max;
	if (TraceRay(&rootNode, ray, hInfo, HIT_FRONT))
		return 0.0f;
	return 1.0f;
}
Esempio n. 6
0
void Renderer::calculatePixelColor(Node &i_rootNode, LightList &i_lightList, int offsetAlongWidth, int offsetAlongHeight)
{
	HitInfo hitInfo;
	Color noHitPixelColor = { 0,0,0 };
	Color finalColor = { 0,0,0 };
	RandomSampler sampler = RandomSampler(MIN_SAMPLE_COUNT, MAX_SAMPLE_COUNT, MIN_VARIANCE, MAX_VARIANCE);

	while (sampler.needMoreSamples())
	{
		sampler.generateSamples(offsetAlongWidth, offsetAlongHeight);
		for (int k = 0; k < sampler.getSampleBucketSize(); ++k)
		{
			hitInfo.Init();
			Ray sampleRay = sampler.getSampleRay(k);
			if (TraceRay(&i_rootNode, sampleRay, hitInfo))
			{
				finalColor = hitInfo.node->GetMaterial()->Shade(sampleRay, hitInfo, 
					i_lightList, REFLECTION_BOUNCE_COUNT, GI_BOUNCE_COUNT);
				/*finalColor.r = pow(finalColor.r, 1/2.2);
				finalColor.g = pow(finalColor.g, 1/2.2);
				finalColor.b = pow(finalColor.b, 1/2.2);*/
				sampler.setSampleColor(k, finalColor);
				sampler.setIsSampleHit(k, true);				
			}
			else
			{				
				sampler.setSampleColor(k, background.Sample(sampleRay.dir));
			}
			sampler.setHitInfo(k, hitInfo);
		}
	}

	Color tempColor = sampler.getAveragedSampleListColor();
	tempColor.r = pow(tempColor.r, 1 / 2.2);
	tempColor.g = pow(tempColor.g, 1 / 2.2);
	tempColor.b = pow(tempColor.b, 1 / 2.2);
	float depth = sampler.getAveragedDepth();
	int sampleCount = sampler.getSampleBucketSize();
	int pixel = offsetAlongHeight * imageWidth + offsetAlongWidth;

	TCHAR* mutexName = __T("WritingMutex");
	static HANDLE mutexHandle = NULL;
	if( mutexHandle == NULL )
		mutexHandle = OpenMutex(MUTEX_ALL_ACCESS, FALSE, mutexName);
	DWORD dSuccess = WaitForSingleObject(mutexHandle, INFINITE);
	assert(dSuccess == WAIT_OBJECT_0);
	renderingImage[pixel] = tempColor; 
	operationCountImage[pixel] = Color(1.0f,0.0f,0.0f) * static_cast<float>(hitInfo.operationCount/BIGFLOAT);
	zBufferImage[pixel] = depth;
	sampleCountImage[pixel] = sampleCount;
	bool bSuccess = ReleaseMutex(mutexHandle);
	assert(bSuccess == true);
	sampler.resetSampler();
}
Esempio n. 7
0
bool RayTrace(HitInfo &hitInfo, Node* curnode, Ray ray, int PixIndex)
{
    Node* node = curnode;
    bool hitTest = false;
    
    const Object *obj = node->GetObject();
    ray = curnode->ToNodeCoords(ray);
    if(obj){
        //       cout<<"Transforming to..."<<endl;
        
        HitInfo tempHitInfo;
        tempHitInfo.Init();
        tempHitInfo.node = node;
        tempHitInfo.z = hitInfo.z;
        hitTest = obj->IntersectRay(ray, tempHitInfo);
        node->FromNodeCoords(tempHitInfo);
        if(hitTest && tempHitInfo.z < hitInfo.z){
            hitInfo = tempHitInfo;
            //cout<<hitInfo.z<<endl;
        }
        //else hitTest=false;
    }
    if(node->GetNumChild()>0)
    {
        //cout<<"Children "<<node->GetNumChild()<<endl;
        for(int i=0;i<curnode->GetNumChild();++i)
        {
//            cout<<"Child "<<i<<endl;
            node = curnode->GetChild(i);
            HitInfo temp;
            temp.Init();
            temp = hitInfo;
            if(RayTrace(hitInfo, node, ray, PixIndex)){
                curnode->FromNodeCoords(hitInfo);
                
//                cout<<"Transforming from "<<curnode->GetNumChild()<<endl;
                if(temp.z > hitInfo.z) hitTest = true;
                else{
                    // hitInfo = temp;
                    hitTest = false;
                    continue;
                }
            }
            
        }
    }
    
    
    if(hitTest) return true;
    else return false;
    
}
const Vector3 Lambert::shade(const unsigned int threadID, const Ray& ray, const HitInfo &hit, const Scene& scene, bool isSecondary) const
{
    Vector3 L		= Vector3(0.0f, 0.0f, 0.0f);
	Vector3 rayD	= Vector3(ray.d[0],ray.d[1],ray.d[2]);		// Ray direction
	Vector3 viewDir	= -rayD;									// View direction
	float u, v;
	Vector3 N, geoN, T, BT;
	Vector3 diffuseColor = m_kd;

	Vector3 P = ray.getPoint(hit.t);

	hit.getAllInfos(N, geoN, T, BT, u, v);

	if (m_colorMap != NULL) 
	{
		Vector4 texCol = m_colorMap->getLookup(u, v);
		diffuseColor = Vector3(texCol.x, texCol.y, texCol.z);
	}

    const Lights *lightlist = scene.lights();
    
    // loop over all of the lights
    Lights::const_iterator lightIter;
    for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++)
    {
		float discard;
		Vector3 lightPower = (*lightIter)->sampleLight(threadID, P, N, ray.time, scene, 0, discard);		
		L += lightPower * diffuseColor;								// Calculate Diffuse component
    }
    
    // add the ambient component
    L += m_ka;
    
    return L;
}
Esempio n. 9
0
void doRender(void* arg){
    
    RenderParams rarg = *((RenderParams *)arg);
    //cout<<"Do render...."<<endl;
            bool pixelHit=false;

    
            HitInfo hitInfo;
            hitInfo.Init();
            
            Point2 pixLoc = rarg.pixLocation;
            Ray r = rarg.ray;
            int PixIndex = rarg.pixIndex;
            Color shade(255,255,255);
            if(rootNode.GetNumChild()>0){
                
                if(RayTrace_2(r, hitInfo)) {
                    pixelHit=true;
//                    cout<<"Shading...."<<endl;
                    shade = hitInfo.node->GetMaterial()->Shade(r, hitInfo, lights, 5);
                }
                
                renderImage.PutPixel(PixIndex, shade, hitInfo.z);
                
                
            }
            
            if(!pixelHit){
                
                renderImage.PutPixel(PixIndex, black, BIGFLOAT);
            
            }
    
   
    
//    RenderParams renderArg = giveMeAPixelToRender();
//    if(renderArg.renderComplete != 1){
//            doRender(&renderArg);
//    }
//    
    

}
Esempio n. 10
0
Color MtlBlinn::Shade(const Ray &ray, const HitInfo &hInfo, const LightList &lights, int bounceCount) const{
    float bias = BIAS_SHADING;
    Color shade;
    Color rShade = Color(0,0,0);
    Color tShade = Color(0,0,0);
    const Material *mat;
    mat = hInfo.node->GetMaterial();
    const MtlBlinn* mb =static_cast<const MtlBlinn*>(mat);
//    cout<<"HInfo front: "<<hInfo.front<<endl;
    /* local copy */
    Point3 P;
    P.Set(hInfo.p.x,hInfo.p.y,hInfo.p.z);
    Ray iRay = ray;
    
    Color ambInt = mb->diffuse;
    Color allOther = Color(0,0,0);
    Color diffuse = mb->diffuse;;
    Color ambComponent = Color(0,0,0);
    
    for ( unsigned int i=0; i<lights.size(); i++ ) {
        if(lights[i]->IsAmbient()){
//            cout<<"ambient "<<endl;
            Color intensity = lights[i]->Illuminate(hInfo.p);
            ambComponent += (ambInt * intensity);
            continue;
        }
        else{
//            cout<<"other lighting  "<<endl;
            Point3 L = -lights[i]->Direction(P);
            L.Normalize();
            
            Point3 V = ray.p - P;
            V.Normalize();
            
            Point3 LplusV = L + V;
            Point3 H = (L+V)/LplusV.Length();
            H.Normalize();
            
            float alpha = mb->glossiness;
            Point3 N = hInfo.N;
            float S = H.Dot(N);
            S = pow(S,alpha);
            float costheta = L.Dot(N)/(L.Length() * N.Length());
            Color intensity = lights[i]->Illuminate(P);
//            cout<<"costheta "<<endl;
            allOther += intensity * (costheta>0?costheta:0) * (diffuse + S * (mb->specular)) ;
        }
        /* finally add inta*cola + intall*costheta*(cold + s* colS)*/
        shade = ambComponent  + allOther;
    }
    
    /* Calculate refraction */
    if(refraction.Grey()>0 && bounceCount>0){
        Color reflShade = Color(0,0,0);
        float R0, Refl = 0.0f, Trans = 0.0f;
        HitInfo temp;
        temp.Init();
        
        Point3 N = hInfo.N;
//        Point3 V = Point3(iRay.p.x -  hInfo.p.x, iRay.p.y - hInfo.p.y, iRay.p.z - hInfo.p.z);
        Point3 V = Point3(hInfo.p.x - iRay.p.x, hInfo.p.y - iRay.p.y, hInfo.p.z - iRay.p.z);
        V.Normalize();
        float n1 = 1, n2 = 1;
        if(hInfo.front){ /* Hitting from outside */
//            temp.front = false;
            n2 = ior;
//            cout<<"outside "<<endl;
        }
        else if(!hInfo.front){ /* Transmission from the inside */
//            temp.front = true;
            n1 = ior;
//            cout<<"intside... "<<endl;
            N = -hInfo.N;
        }
        float ratio_n = n1 / n2;
        
        float costheta_v = -V.Dot(N);        /* refer: http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf */

        float sin2theta_t = ratio_n * ratio_n * (1 - costheta_v * costheta_v);
        Point3 T =   ratio_n * V + (ratio_n * costheta_v - sqrtf(1 - sin2theta_t)) * N ;
//        cout<<ratio_n<<" "<<"cos_v "<<costheta_v<<" sin2theta_t "<<sin2theta_t<<endl;
        Ray tRay = Ray(hInfo.p,T);
        
        //tRay.dir.Normalize();
        tRay.p.x = tRay.p.x + bias *tRay.dir.x; /* add bias */
        tRay.p.y = tRay.p.y + bias *tRay.dir.y;
        tRay.p.z = tRay.p.z + bias *tRay.dir.z;
//        cout<<"B temp front: "<< temp.front<<endl;
        if(sin2theta_t <= 1){
            if(RayTrace_2(tRay, temp)){
//                bounceCount--;
//                cout<<"A temp front: "<< temp.front<<endl;
                tShade  =  temp.node->GetMaterial()->Shade(tRay,temp,lights,bounceCount);
                tShade.r *= exp(-absorption.r * temp.z);
                tShade.g *= exp(-absorption.g * temp.z);
                tShade.b *= exp(-absorption.b * temp.z);
//                shade = tShade; /* remove later */
//                return shade;
               
                
                /* Calculate Schlick's approximation */
                
                R0 = (n1 - n2)/(n1 + n2);
                R0 *= R0;
                double  X = 0.0;
//                if(n1 > n2){
//                    X = 1.0 - sqrtf(1.0 - sin2theta_t);
//                }
//                else{ X = 1.0 - costheta_v; }
                X = 1.0 - costheta_v;
                Refl = R0 + (1.0 - R0) *  X * X * X * X * X;
                Trans = 1.0 - Refl;
                
            }
        }
        else {/* Total internal reflection */
            Refl = 1.0f;
        }
        
        /* Calculate reflection due to reflectance */
        if(bounceCount >0){
            N = hInfo.N;
            Point3 V = Point3(iRay.p.x -  P.x, iRay.p.y - P.y, iRay.p.z - P.z);
            //V.Normalize();
            Point3 VR = 2 * V.Dot(N) * N - V;
            //VR.Normalize();
            Ray rRay = Ray(P, VR);
            //rRay.dir.Normalize();
            rRay.p.x = rRay.p.x + bias *rRay.dir.x;
            rRay.p.y = rRay.p.y + bias *rRay.dir.y;
            rRay.p.z = rRay.p.z + bias *rRay.dir.z;
            HitInfo temp1;
            temp1.Init();
            if(rootNode.GetNumChild()>0){
                if(RayTrace_2(rRay, temp1)){
                    bounceCount --;
                    reflShade =   temp1.node->GetMaterial()->Shade(rRay, temp1, lights, bounceCount);
                }
            }
        }
        
//        cout<<"Refl: "<<Refl<<"Trans "<<Trans<<endl;
        tShade = refraction * (Trans * tShade + Refl * reflShade);
        
        
    }
    





    /* calculate reflection*/
    if(reflection.Grey()>0 && bounceCount > 0){

        Point3 N = hInfo.N;
        Point3 V = Point3(iRay.p.x -  P.x, iRay.p.y - P.y, iRay.p.z - P.z);
       // V.Normalize();
        Point3 VR = 2 * V.Dot(N) * N - V;
        Ray rRay = Ray(hInfo.p, VR);
        //rRay.dir.Normalize();
        rRay.p.x = rRay.p.x + bias *rRay.dir.x;
        rRay.p.y = rRay.p.y + bias *rRay.dir.y;
        rRay.p.z = rRay.p.z + bias *rRay.dir.z;
        HitInfo temp;
        temp.Init();
        if(rootNode.GetNumChild()>0){
            if(RayTrace_2(rRay, temp)){
                bounceCount--;
                rShade = reflection * temp.node->GetMaterial()->Shade(rRay, temp, lights, bounceCount);
            }
        }
    }
    
  
    
    /* Add shade with reflected and refracted colors */
    shade += (rShade + tShade);
    return shade;
};
Esempio n. 11
0
Color World::runBiDi(vec origin, vec direction) const {
	Thing *emitter = emitters[Random::upto(emitters.size())];
	
	std::vector<Color> cumEmtWeight;
	std::vector<HitInfo> emtHits;
	
	std::vector<Color> cumEyeWeight;
	std::vector<HitInfo> eyeHits;
	std::vector<int> todo;
	
	cumEmtWeight.reserve(depth);
	emtHits.reserve(depth);
	
	cumEyeWeight.reserve(depth);
	eyeHits.reserve(depth);
	todo.reserve(depth);
	
	HitInfo emtInfo;
	vec emtN;
	vec source;
	source = emitter->randomSurfacePoint(emtN);
	emtInfo.hit = true;
	emtInfo.incoming = emtN;
	emtInfo.normal = emtN;
	emtInfo.location = source;
	emtInfo.mat = emitter->getMaterial();
	cumEmtWeight.push_back(emitter->getMaterial()->getColor());
	emtHits.push_back(emtInfo);
	bool done = false;
	for (int d = 1; d < depth && !done; d++) {
		HitInfo newI;
		newI.follow(emtHits[d-1]);
		
		vec newDirection = emtHits[d-1].mat->sample(emtHits[d-1].incoming, emtHits[d-1].normal);
		
		objects->hit(&newI, emtHits[d-1].location, newDirection);
		
		cumEmtWeight.push_back(emtHits[d-1].mat->combineColor(
							cumEmtWeight[d-1] * emtHits[d-1].mat->sampledPdf(
								emtHits[d-1].incoming, newDirection, emtHits[d-1].normal)));
		if (newI.hit)
			emtHits.push_back(newI);
		else
			done = true;
	}
	
	HitInfo eyeInfo;
	objects->hit(&eyeInfo, origin, direction);
	
	done = false;
	if (!eyeInfo.hit)
		return Color(0,0,0);
	cumEyeWeight.push_back(eyeInfo.mat->getColor());
	eyeHits.push_back(eyeInfo);
	/*for (int d = 1; d < depth && !done; d++) {
		HitInfo newI;
		newI.follow(eyeHits[d-1]);
		
		vec newDirection = eyeHits[d-1].mat->sample(eyeHits[d-1].incoming, eyeHits[d-1].normal);
		
		objects->hit(&newI, eyeHits[d-1].location, newDirection);
		
		cumEyeWeight.push_back(eyeHits[d-1].mat->combineColor(
							   cumEyeWeight[d-1] * eyeHits[d-1].mat->sampledPdf(
									eyeHits[d-1].incoming, newDirection, eyeHits[d-1].normal)));
		if (newI.hit)
			eyeHits.push_back(newI);
		else
			done = true;
	}*/
	
	for (int d = 1; d < depth && !todo.empty(); d++) {
		HitInfo newI;
		int index = todo.back();
		todo.pop_back();
		newI.follow(eyeHits[index]);
		
		vec newDirection = eyeHits[index].mat->sample(eyeHits[index].incoming, eyeHits[index].normal);
		
		objects->hit(&newI, eyeHits[index].location, newDirection);
		
		if (newI.hit) {
			Color newc = eyeHits[index].mat->combineColor(
				cumEyeWeight[index] * eyeHits[index].mat->sampledPdf(
					eyeHits[index].incoming, newDirection, eyeHits[index].normal));
			int ints = 1;//newc.intensity() * 5 + 1;
			for (int x=0; x<ints; x++)
				todo.push_back(eyeHits.size());
			eyeHits.push_back(newI);
			cumEyeWeight.push_back(newc * (1.0/ints));
		}
		else
			done = true;
	}
	
	Color accum;
	for (int x=0; x<emtHits.size(); x++)
		for (int y=0; y<eyeHits.size(); y++) {
			vec dir = eyeHits[y].location - emtHits[x].location;
			double dist = dir.magnitude();
			dir.normalize();
			HitInfo inf;
			inf.distanceOnly = true;
			inf.distance = dist;
			objects->hit(&inf, emtHits[x].location, dir);
			if (inf.distance >= dist - EPSILON || !inf.hit) {
				//hit
				accum += cumEyeWeight[y] * cumEmtWeight[x] *
				eyeHits[y].mat->pdf(eyeHits[y].incoming, dir * -1, eyeHits[y].normal) * 
					emtHits[x].mat->pdf(emtHits[x].incoming, dir, emtHits[x].normal);
			}
		}
	return accum;
	/*if (eyeInfo.hit) {
		vec newn;
		vec dtl = eyeInfo.location - emitter->randomSurfacePoint(newn);
		return emitter->getMaterial()->getColor() * eyeInfo.mat->pdf(direction*-1, dtl, eyeInfo.normal);
	}
	else
		return Color(0,0,0);*/
}
Esempio n. 12
0
Colour SceneNode::get_colour(Point3D origin, Vector3D dir, const Colour& ambient, 
							 const Colour& bg, const std::list<Light*>& lights, 
							 int num_glossy_rays, int limit) {
  HitInfo info = intersects(origin, dir);
  if (!info.empty() && limit > 0) {
	Hit closest = info.get_closest();
	Material* close_mat = closest.material;
	Colour c(0.0, 0.0, 0.0); 
	for (std::list<Light*>::const_iterator it = lights.begin(); it != lights.end(); ++it) {
	  Vector3D shadow_ray = (*it)->position - closest.intersection;
	  HitInfo shadow_info = intersects(closest.intersection, shadow_ray);
	  closest = close_mat->apply_material(-dir, *it, closest);

	  if (!shadow_info.empty()) {
		std::vector<Hit> all_hits = shadow_info.get_all_hits();
		int num_translucent = 0;
		Colour shadow(0.0, 0.0, 0.0);
		for (unsigned int i = 0; i < all_hits.size(); i++) {
		  Hit h = all_hits.at(i);
		  if (!h.in_shadow) {
			if (num_translucent == 0) {
			  shadow = shadow + closest.diffuse;
			  num_translucent = 1;
			}
			break;
		  } else {
			if ((h.material)->get_transparency() > 0.0) {
			  shadow = shadow + (h.material)->get_transparency() * closest.diffuse;
			  num_translucent++;
			} else {
			  num_translucent = 0;
			  break;
			}
		  }
		}
		if (num_translucent > 0) {
		  c = c + (1.0 / num_translucent) * shadow;
		  c = c + closest.specular;
		}
	  } else {
		c = c + closest.diffuse;
		c = c + closest.specular;
	  }
	}

	if ((closest.material)->should_reflect()) {
	  Vector3D V = dir, N = closest.normal; 
	  V.normalize(); N.normalize();
	  Vector3D reflected = V - (2 * V.dot(N) * N);
	  Colour r = get_colour(closest.intersection, reflected, ambient, bg, lights, 
							num_glossy_rays, limit - 1);

	  if (num_glossy_rays > 0) {
		Vector3D w = reflected;
		w.normalize();
		Vector3D u = w.cross(Vector3D(1.0, 0.0, 0.0));
		u.normalize();
		Vector3D v = w.cross(Vector3D(0.0, 1.0, 0.0));
		v.normalize();
		for (int i = 0; i < num_glossy_rays; i++) {
		  double dx = 0.0;
		  double dy = 0.0;
		  while (dx == 0.0 && dy == 0.0) {
			dx = ((double)(rand() % 100) / 100.0) * 0.125;
			dy = ((double)(rand() % 100) / 100.0) * 0.125;
		  }
		  Vector3D refi = reflected + dx * u + dy * v;
		  if (refi.dot(closest.normal) < 0) {
			refi = -refi;
		  }
		  Colour ri = get_colour(closest.intersection, refi, ambient, bg, lights, 
								 num_glossy_rays, limit - 1);
		  r = r + ri;
		}
		r = (double) (1.0 / (num_glossy_rays + 1)) * r;
	  }
	  c = 0.7 * c + 0.3 * close_mat->get_reflect(r);
	}

	Vector3D refracted;
	if (close_mat->should_refract() && close_mat->get_transmit_ray(refracted, dir, closest)) {
	  Colour refr = get_colour(closest.intersection, refracted, ambient, bg, lights, 
							   num_glossy_rays, limit + 1);
	  c = c + close_mat->get_transparency() * refr;
	}
	c = c + (1.0 - close_mat->get_transparency()) * close_mat->get_ambient(ambient);
	return c;
  } else {
	return bg;
  }
}
Esempio n. 13
0
        void PhotonTracer::traceSinglePhoton(IPhotonMap& photonMap, int photonCount) const {
            float randomVector[RANDOM_DIMENSION];

            randomSet_->nextf(randomVector);

            Spectrum power;

            ray3f ray(light_->samplePhoton(
                power,
                vec2f(
                    Lcg::global().nextf(),
                    Lcg::global().nextf()),
                vec2f(
                    randomAt(randomVector, 0), 
                    randomAt(randomVector, 1))));

            power /= static_cast<float>(photonCount); // split power

            HitInfo hit = HitInfo::createUninitialized();

            float currentRefractiveIndex = 1;

            int bounceCount = 0;

            while( scene_->raytrace(ray, hit) ) {
                if(bounceCount > 0) {
                    Photon photon(
                        hit.position(),
                        hit.normal(),
                        power);

                    photonMap.add(photon);
                }

                Material const& material = hit.material();

                if(material.getType() == Material::MATERIAL_DIFFUSE) {
                    float u = Lcg::global().nextf();

                    // Russian roulette.
                    if(u <= material.getReflectance().average()) {
                        power *= material.getReflectance() 
                            / material.getReflectance().average();

                        ray = ray3f(
                            hit.position(),
                            Hemisphere::cosineWeightedDirection(
                                hit.normal(),
                                randomAt(randomVector, 2+2*bounceCount),
                                randomAt(randomVector, 3+2*bounceCount)));
                    } else {
                        break;
                    }
                } else if(material.getType() == Material::MATERIAL_SPECULAR) {
                    float u = Lcg::global().nextf();

                    // Russian roulette.
                    if(u <= material.getReflectance().average()) {
                        power *= material.getReflectance() 
                            / material.getReflectance().average();

                        ray = ray3f(
                            hit.position(),
                            Hemisphere::mirrorReflection(
                                hit.normal(),
                                ray.getDirection()));
                    } else {
                        break;
                    }
                } else if(material.getType() == Material::MATERIAL_DIELECTRIC) {
                    float fresnel = Hemisphere::fresnelCoefficient(
                        hit.normal(), ray.getDirection(),
                        currentRefractiveIndex,
                        material.getRefractiveIndex());

                    float u = Lcg::global().nextf();

                    if(u < 1 - fresnel) {
                        // refraction

                        vec3f excitantDirection;

                        if( Hemisphere::computeRefraction(
                                hit.normal(), ray.getDirection(),
                                currentRefractiveIndex,
                                material.getRefractiveIndex(),
                                excitantDirection) ) {
                            ray = ray3f(
                                hit.position(),
                                excitantDirection);

                            currentRefractiveIndex = material.getRefractiveIndex();
                        } else {
                            // total internal reflection

                            ray = ray3f(
                                hit.position(),
                                Hemisphere::mirrorReflection(
                                    hit.normal(),
                                    ray.getDirection()));
                        }
                    } else {
                        // reflection

                        ray = ray3f(
                            hit.position(),
                            Hemisphere::mirrorReflection(
                                hit.normal(),
                                ray.getDirection()));
                    }
                } else {
                    break;
                }

                ++bounceCount;
            }
        }
Esempio n. 14
0
void World::createCache() {
	Thing *emitter;
	HitInfo c;
	int length =0;
	int resetcount = 1;
	HitInfo emtInfo;
	vec emtN;
	vec source;
	emitter = emitters[Random::upto(emitters.size())];
	source = emitter->randomSurfacePoint(emtN);
	emtInfo.hit = true;
	emtInfo.incoming = emtN;
	emtInfo.normal = emtN;
	emtInfo.location = source;
	emtInfo.mat = emitter->getMaterial();
	colorcache.push_back(emitter->getMaterial()->getColor());
	hicache.push_back(emtInfo);
	bool done = false;
	for (int d = 1; d < cacheSize; d++) {
		int i = d - 1;
		double ints = colorcache[i].intensity();
		if (ints < .01 || length > 60 || done) {
			emitter = emitters[Random::upto(emitters.size())];
			source = emitter->randomSurfacePoint(emtN);
			emtInfo.distance = 0;
			emtInfo.previousDistances = 0;
			emtInfo.hit = true;
			emtInfo.incoming = emtN;
			emtInfo.normal = emtN;
			emtInfo.location = source;
			emtInfo.mat = emitter->getMaterial();
			int intes = 1;//emitter->getMaterial()->getColor().intensity() + 1;
			for (int x=0; x<intes; x++)	{
				colorcache.push_back(emitter->getMaterial()->getColor() * (1.0/intes));
				hicache.push_back(emtInfo);
			}
			resetcount++;
			d += intes-1;
			done = false;
			length = 0;
			continue;
		}
		length++;
		HitInfo newI;
		newI.follow(hicache[d-1]);
		
		vec newDirection = hicache[d-1].mat->sample(hicache[d-1].incoming, hicache[d-1].normal);
		
		objects->hit(&newI, hicache[d-1].location, newDirection);
		
		if (newI.hit) {
			Color newc = hicache[d-1].mat->combineColor(colorcache[d-1] *
				hicache[d-1].mat->sampledPdf(hicache[d-1].incoming, newDirection, hicache[d-1].normal));
			int intes = 1;//newc.intensity()*3 + 1;
			for (int x=0; x<intes; x++) {
				hicache.push_back(newI);
				colorcache.push_back(newc * (1.0/intes));
			}
			d += intes-1;
		}
		else {
			done = true;
			d--;
		}
	}
	cacheweight = (cacheSize * 1.0 / resetcount);
}
Esempio n. 15
0
ColorTimeCache World::runCache(vec origin, vec direction) const {
	ColorTimeCache accum;
	std::vector<Color> cumEyeWeight;
	std::vector<HitInfo> eyeHits;
	std::vector<int> todo;
	std::vector<double> mult;
	todo.reserve(depth);
	cumEyeWeight.reserve(depth); //8s without, 8s with, but should make a difference.
	eyeHits.reserve(depth);
	mult.reserve(depth);
	HitInfo eyeInfo;
	objects->hit(&eyeInfo, origin, direction);
	
	bool done = false;
	if (!eyeInfo.hit)
		return accum;
	
	Color newc = eyeInfo.mat->getColor();
	int ints = 1;//newc.intensity() * (depth/2) + 1;
	for (int x=0; x<ints; x++)
		todo.push_back(eyeHits.size());
	cumEyeWeight.push_back(newc);
	eyeHits.push_back(eyeInfo);
	mult.push_back(1.0/ints);
	
	for (int d = 1; d < depth && !todo.empty(); d++) {
		HitInfo newI;
		int index = todo.back();
		todo.pop_back();
		newI.follow(eyeHits[index]);
		
		vec newDirection = eyeHits[index].mat->sample(eyeHits[index].incoming, eyeHits[index].normal);
		
		objects->hit(&newI, eyeHits[index].location, newDirection);
		
		if (newI.hit) {
			Color newc = newI.mat->combineColor(
				cumEyeWeight[index] * eyeHits[index].mat->sampledPdf(
					eyeHits[index].incoming, newDirection, eyeHits[index].normal));
//			newc *= mult[index];
			int ints = 1;//newc.intensity() * (depth/2) + 1;
			for (int x=0; x<ints; x++)
				todo.push_back(eyeHits.size());
			eyeHits.push_back(newI);
			cumEyeWeight.push_back(newc);
			mult.push_back(1.0/ints);
		}
		else
			done = true;
	}
	
	for (int x=0; x<depth; x++) {
		for (int y=0; y<eyeHits.size(); y++) {
			int index = Random::upto(cacheSize);
			vec dir = eyeHits[y].location - hicache[index].location;
			double dist = dir.magnitude();
			if (dist < EPSILON)
				continue;
			dir.normalize();
			HitInfo inf;
			inf.distanceOnly = true;
			inf.distance = dist;
			objects->hit(&inf, hicache[index].location, dir);
			if (inf.distance >= dist - EPSILON || !inf.hit) {
				//hit
				Color result = cumEyeWeight[y] * colorcache[index] * cacheweight *
				eyeHits[y].mat->pdf(eyeHits[y].incoming, dir * -1, eyeHits[y].normal) * 
				hicache[index].mat->pdf(hicache[index].incoming, dir, hicache[index].normal) * (1/BOUNCE_MULT);
				accum.addSample(hicache[index].distance + hicache[index].previousDistances
								+ eyeHits[y].distance + eyeHits[y].previousDistances + inf.distance, result);
			}
		}
	}
	return accum;
}
Esempio n. 16
0
Color MtlBlinn::Shade(const Ray &ray, const HitInfo &hInfo, const LightList &lights, int reflection_bounceCount, int gi_bounceCount) const
{
	Color ambientComp, diffuseComp, specularComp, reflectiveComp, refractiveComp, reflectionTotal, refractionTotal, noColor, diffuseReflection;
	diffuseReflection = ambientComp = diffuseComp = specularComp = reflectiveComp = refractiveComp  = noColor = reflectionTotal = refractionTotal = Color(0.0f, 0.0f, 0.0f);
	Color fromReflection = Color(0.0f, 0.0f, 0.0f);
	Color fromRefraction = Color(0.0f, 0.0f, 0.0f);
	Point3 viewDirection = -ray.dir;
	float schlicksConstant, ratioOfRefraction;
	Color kd = diffuse.Sample(hInfo.uvw);

	int hitside = HIT_FRONT;
	float n1 = 1;
	float n2 = ior;

	for (int i = 0; i < lights.size(); i++)
	{
		Color lightColor = lights[i]->Illuminate(hInfo.p, hInfo.N);
		/*if (lightColor != noColor)
		{*/
			if (lights[i]->IsAmbient())
			{
				ambientComp = ambientComponent(lights[i], lightColor, hInfo, diffuse.Sample(hInfo.uvw));
			}
			else
			{
				//lightColor.ClampMinMax();
				Point3 rayDir = ray.dir;
				globalPhotonMap.EstimateIrradiance<50>(lightColor, rayDir, 2.0f, hInfo.p, &hInfo.N);
				diffuseComp = diffuseComponent(lights[i], lightColor, hInfo, diffuse.Sample(hInfo.uvw));
				specularComp = specularComponent(lights[i], lightColor, viewDirection, hInfo, specular.Sample(hInfo.uvw), glossiness);
			}
		//}
	}
			/************************Refraction************************************************************/
	if(refraction.Sample(hInfo.uvw) != noColor && reflection_bounceCount > 0)
	{
		Ray refractionRay;
		HitInfo refractionRayHit;
		refractionRayHit.Init();
		refractionRay.p = hInfo.p;
		if (hInfo.front == HIT_FRONT)
		{
			refractionRay.dir = getRefractionVector(viewDirection, getPerturbedNormal(hInfo.N, hInfo.p, refractionGlossiness), n1, n2);
		}
		else
		{
			refractionRay.dir = getRefractionVector(viewDirection, getPerturbedNormal( -hInfo.N, hInfo.p, refractionGlossiness), n2, n1);
		}
				
		if(TraceRay(&rootNode, refractionRay, refractionRayHit, hitside))
		{
			Point3 refractionDir = refractionRay.dir;
			refractiveComp += refractionRayHit.node->GetMaterial()->Shade(refractionRay, refractionRayHit, 
				lights, --reflection_bounceCount);
			refractiveComp *= refraction.Sample(hInfo.uvw);
		}
		else
		{
			refractiveComp =  environment.SampleEnvironment(refractionRay.dir);
		}				
	}


	/********************Schlick's Approximation - Fresnel Reflection***************************/
	schlicksConstant = pow(((n1 - n2) / (n1 + n2)), 2);
	ratioOfRefraction = schlicksConstant + (1 - schlicksConstant) * pow((1 - viewDirection.Dot(hInfo.N)), 5);
	reflectionTotal = ratioOfRefraction*refraction.Sample(hInfo.uvw);
	refractionTotal = (1 - ratioOfRefraction)*refraction.Sample(hInfo.uvw);
	///*******************************************************************************************/
	//refractiv    eComp *= refractionTotal; //It = (1-R) * KT'
	reflectionTotal += reflection.Sample(hInfo.uvw); //Doing outside in case refraction didn't occured at all
	/*********************************************************************************************/

	/**********************Reflection*************************************************************/
	if(reflectionTotal != noColor && reflection_bounceCount > 0)
	{
		Ray reflectionViewVector;
		reflectionViewVector.dir = getReflectionVector(viewDirection, 
			getPerturbedNormal(hInfo.N, hInfo.p, reflectionGlossiness));
		reflectionViewVector.p = hInfo.p;
		HitInfo reflectionRayHit;
		reflectionRayHit.Init();
		//--reflection_bounceCount;
		if (TraceRay(&rootNode, reflectionViewVector, reflectionRayHit, HIT_FRONT))
		{
			fromReflection += reflectionRayHit.node->GetMaterial()->Shade(reflectionViewVector, 
				reflectionRayHit, lights, --reflection_bounceCount);
			reflectiveComp = reflectionTotal * fromReflection;
		}
		else
		{
			reflectiveComp = environment.SampleEnvironment(reflectionViewVector.dir);
		}
	}
	/****************************************************************************************************/
	if(GI_ALGO)
	{
		if (kd != noColor && gi_bounceCount > 0)
		{
			HemiSphereSampler giHemiSampler = HemiSphereSampler(__gi_sampleCount, __gi_sampleCount, 1);
			giHemiSampler.generateSamples();
			Point3 randomDirectionAtHitPoint = Point3(0.0f, 0.0f, 0.0f);
			HitInfo diffuseReflectionHitInfo;
			Ray diffuseReflectionRay;
			for (int i = 0; i < giHemiSampler.getCurrentSampleCount(); ++i)
			{
				randomDirectionAtHitPoint = giHemiSampler.getSample(getRandomNumber(0, giHemiSampler.getCurrentSampleCount())).getOffset();
				diffuseReflectionRay.p = hInfo.p;
				Point3 u = Point3(0.0f, 0.0f, 0.0f);
				Point3 v = Point3(0.0f, 0.0f, 0.0f);
				Point3 w = Point3(0.0f, 0.0f, 0.0f);
				w = hInfo.N;
				getOrthoNormalBasisVector(w, u, v);
				diffuseReflectionRay.dir = randomDirectionAtHitPoint.x * u +
					randomDirectionAtHitPoint.y * v +
					randomDirectionAtHitPoint.z *w;
				diffuseReflectionHitInfo.Init();
				if (TraceRay(&rootNode, diffuseReflectionRay, diffuseReflectionHitInfo, HIT_FRONT))
				{
					diffuseReflection = diffuseReflectionHitInfo.node->GetMaterial()->Shade(diffuseReflectionRay,
						diffuseReflectionHitInfo, lights, 0, gi_bounceCount - 1);					
				}
				else
				{
					diffuseReflection = environment.SampleEnvironment(diffuseReflectionRay.dir);
				}
				giHemiSampler.setSampleColor(i, diffuseReflection);
				giHemiSampler.setIsSampleHit(i, true);
			}

			diffuseReflection = giHemiSampler.getAveragedSampleListColor() * diffuseReflection * kd * M_PI;
		}
	}
	else
	{
		if (kd != noColor && gi_bounceCount > 0)
		{
			HemiSphereSampler giHemiSampler = HemiSphereSampler(__gi_sampleCount, __gi_sampleCount, 1);
			giHemiSampler.generateSamples();
			Point3 randomDirectionAtHitPoint = Point3(0.0f, 0.0f, 0.0f);
			HitInfo diffuseReflectionHitInfo;
			Ray diffuseReflectionRay;
			
			randomDirectionAtHitPoint = giHemiSampler.getSample(getRandomNumber(0, giHemiSampler.getCurrentSampleCount())).getOffset();
			diffuseReflectionRay.p = hInfo.p;
			Point3 u = Point3(0.0f, 0.0f, 0.0f);
			Point3 v = Point3(0.0f, 0.0f, 0.0f);
			Point3 w = Point3(0.0f, 0.0f, 0.0f);
			w = hInfo.N;
			getOrthoNormalBasisVector(w, u, v);
			diffuseReflectionRay.dir = randomDirectionAtHitPoint.x * u +
				randomDirectionAtHitPoint.y * v +
				randomDirectionAtHitPoint.z *w;
			
			diffuseReflectionHitInfo.Init();
			if (TraceRay(&rootNode, diffuseReflectionRay, diffuseReflectionHitInfo, HIT_FRONT))
			{
				diffuseReflection += diffuseReflectionHitInfo.node->GetMaterial()->Shade(diffuseReflectionRay,
					diffuseReflectionHitInfo, lights, 0, gi_bounceCount - 1);	
				diffuseReflection = diffuseReflection * kd;
			}
			else
			{
				diffuseReflection = environment.SampleEnvironment(diffuseReflectionRay.dir);
			}			
		}
	}
			
	return (ambientComp + diffuseComp + specularComp+ reflectiveComp + refractiveComp + diffuseReflection);
}
Esempio n. 17
0
Color MtlBlinn::Shade(const Cone &ray, const HitInfo &hInfo, const LightList &lights, int bounceCount) const{
    float bias = BIAS_SHADING;
    Color shade;
    Color rShade = Color(0,0,0);
    Color tShade = Color(0,0,0);
    const Material *mat;
    mat = hInfo.node->GetMaterial();
    const MtlBlinn* mb =static_cast<const MtlBlinn*>(mat);
//    cout<<"HInfo front: "<<hInfo.front<<endl;
    /* local copy */
    Point3 P;
    P.Set(hInfo.p.x,hInfo.p.y,hInfo.p.z);
    Cone iRay = ray;
    
    Color ambInt = mb->diffuse.Sample(hInfo.uvw, hInfo.duvw);
    Color allOther = Color(0,0,0);
    Color diffuse = mb->diffuse.Sample(hInfo.uvw, hInfo.duvw);
    Color ambComponent = Color(0,0,0);
    Point3 newN = hInfo.N;
    
    
    for ( unsigned int i=0; i<lights.size(); i++ ) {
        if(lights[i]->IsAmbient()){
//            cout<<"ambient "<<endl;
            Color intensity = lights[i]->Illuminate(hInfo.p);
            ambComponent += (ambInt * intensity);
            continue;
        }
        else{
//            cout<<"other lighting  "<<endl;
            Point3 L = -lights[i]->Direction(P);
            L.Normalize();
            
            Point3 V = ray.p - P;
            V.Normalize();
            
            Point3 LplusV = L + V;
            Point3 H = (L+V)/LplusV.Length();
            H.Normalize();
            
            float alpha = mb->glossiness;
//            Point3 N = hInfo.N;
            Point3 N = newN;
            float S = H.Dot(N);
            S = pow(S,alpha);
            float costheta = L.Dot(N)/(L.Length() * N.Length());
            Color intensity = lights[i]->Illuminate(P);
//            cout<<"costheta "<<endl;
            allOther += intensity * (costheta>0?costheta:0) * (diffuse + S * (mb->specular.Sample(hInfo.uvw, hInfo.duvw))) ;
        }
        /* finally add inta*cola + intall*costheta*(cold + s* colS)*/
        shade = ambComponent  + allOther;
    }
    
    /* Calculate refraction */
    if(refraction.GetColor().r>0 && bounceCount>0){
        //compute new jittered normal
        float gloss = refractionGlossiness;
        if(gloss){
            float random = rand()/(float)RAND_MAX;
            float rRadius = sqrtf(random) * gloss;
            random = rand()/(float)RAND_MAX;
            float rAngle =  random * 2.0 * M_PI;
            float x = rRadius * cos(rAngle);
            float y = rRadius * sin(rAngle);
            Point3 xAxis(1,0,0), yAxis(0,1,0), v1, v2, normalDir;
            normalDir = hInfo.N;
            //    normalDir.Normalize();
            if(normalDir.Dot(xAxis) > 0.7)  v1 = normalDir.Cross(yAxis);
            else v1 = normalDir.Cross(xAxis);
            v2 = v1.Cross(normalDir);
            v1.Normalize(); v2.Normalize();
            v1 *= x;
            v2 *= y;
            
            newN = hInfo.N + v1.Length() + v2.Length();
            newN.Normalize();
        }
        else{
            newN = hInfo.N;
        }
        //-------------------------------------
        
        Color reflShade = Color(0,0,0);
        float R0, Refl = 0.0f, Trans = 0.0f;
        HitInfo temp;
        temp.Init();
        
//        Point3 N = hInfo.N;
        Point3 N = newN;
//        Point3 V = Point3(iRay.p.x -  hInfo.p.x, iRay.p.y - hInfo.p.y, iRay.p.z - hInfo.p.z);
        Point3 V = Point3(hInfo.p.x - iRay.p.x, hInfo.p.y - iRay.p.y, hInfo.p.z - iRay.p.z);
        V.Normalize();
        float n1 = 1, n2 = 1;
        if(hInfo.front){ /* Hitting from outside */
//            temp.front = false;
            n2 = ior;
//            cout<<"outside "<<endl;
        }
        else if(!hInfo.front){ /* Transmission from the inside */
//            temp.front = true;
            n1 = ior;
//            cout<<"intside... "<<endl;
//            N = -hInfo.N;
            N *= -1;
        }
        float ratio_n = n1 / n2;
        
        float costheta_v = -V.Dot(N);        /* refer: http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf */

        float sin2theta_t = ratio_n * ratio_n * (1 - costheta_v * costheta_v);
        Point3 T =   ratio_n * V + (ratio_n * costheta_v - sqrtf(1 - sin2theta_t)) * N ;
//        cout<<ratio_n<<" "<<"cos_v "<<costheta_v<<" sin2theta_t "<<sin2theta_t<<endl;
        Cone tRay = Cone(hInfo.p,T);
        
        //tRay.dir.Normalize();
        tRay.p.x = tRay.p.x + bias *tRay.dir.x; /* add bias */
        tRay.p.y = tRay.p.y + bias *tRay.dir.y;
        tRay.p.z = tRay.p.z + bias *tRay.dir.z;
//        cout<<"B temp front: "<< temp.front<<endl;
        temp.timeInstance = hInfo.timeInstance;
        if(sin2theta_t <= 1){
            if(RayTrace_2(tRay, temp)){ /* ray tracing after refraction */
//                bounceCount--;
                tShade  =  temp.node->GetMaterial()->Shade(tRay,temp,lights,bounceCount);
            }
            else{ /* no hit after refraction */
                tShade = environment.SampleEnvironment(tRay.dir);
                
            }
            /* Calculate Schlick's approximation */
            
            R0 = (n1 - n2)/(n1 + n2);
            R0 *= R0;
            double  X = 0.0;
            //                if(n1 > n2){
            //                    X = 1.0 - sqrtf(1.0 - sin2theta_t);
            //                }
            //                else{ X = 1.0 - costheta_v; }
            X = 1.0 - costheta_v;
            Refl = R0 + (1.0 - R0) *  X * X * X * X * X;
            Trans = 1.0 - Refl;
            
            tShade.r *= exp(-absorption.r * temp.z);
            tShade.g *= exp(-absorption.g * temp.z);
            tShade.b *= exp(-absorption.b * temp.z);
        }
        else {/* Total internal reflection */
            Refl = 1.0f;
        }
        
            
        
        
        /* Calculate reflection due to reflectance */
        if(bounceCount >0){
//            N = hInfo.N;
            N = newN;
            Point3 V = Point3(iRay.p.x -  P.x, iRay.p.y - P.y, iRay.p.z - P.z);
            //V.Normalize();
            Point3 VR = 2 * V.Dot(N) * N - V;
            //VR.Normalize();
            Cone rRay = Cone(P + BIAS_SHADING * VR, VR);
            rRay.dir.Normalize();
            HitInfo temp1;
            temp1.Init();
            temp.timeInstance = hInfo.timeInstance;
            if(rootNode.GetNumChild()>0){
                if(RayTrace_2(rRay, temp1)){
                    bounceCount --;
                    reflShade = temp1.node->GetMaterial()->Shade(rRay, temp1, lights, bounceCount);
                }
                else{
                    reflShade = environment.SampleEnvironment(rRay.dir);
//                    reflShade = Color(1,100,1);
                }
            }
        }
        
//        cout<<"Refl: "<<Refl<<"Trans "<<Trans<<endl;
        tShade = refraction.GetColor().r * (Trans * tShade + Refl * reflShade);
        
        
    }

    /* calculate reflection*/
    if(reflection.GetColor().r>0 && bounceCount > 0){
        //compute new jittered normal
        float gloss = reflectionGlossiness;
        if(gloss){
            float random = rand()/(float)RAND_MAX;
            float rRadius = sqrtf(random) * gloss;
            random = rand()/(float)RAND_MAX;
            float rAngle =  random * 2.0 * M_PI;
            float x = rRadius * cos(rAngle);
            float y = rRadius * sin(rAngle);
            Point3 xAxis(1,0,0), yAxis(0,1,0), v1, v2, normalDir;
            normalDir = hInfo.N;
            //    normalDir.Normalize();
            if(normalDir.Dot(xAxis) > 0.7)  v1 = normalDir.Cross(yAxis);
            else v1 = normalDir.Cross(xAxis);
            v2 = v1.Cross(normalDir);
            v1.Normalize(); v2.Normalize();
            v1 *= x;
            v2 *= y;
            
            newN = hInfo.N + v1+ v2;
            newN.Normalize();
        }
        else{
            newN = hInfo.N;
        }
        //-------------------------------------
        
        Point3 N = newN;//hInfo.N;
        Point3 V = Point3(iRay.p.x -  P.x, iRay.p.y - P.y, iRay.p.z - P.z);
       // V.Normalize();
        Point3 VR = 2 * V.Dot(N) * N - V;
        Cone rRay = Cone(P + BIAS_SHADING * VR, VR);
        rRay.dir.Normalize();
        HitInfo temp;
        temp.Init();
        temp.timeInstance=hInfo.timeInstance;
        if(rootNode.GetNumChild()>0){
            if(RayTrace_2(rRay, temp)){
                bounceCount--;
                rShade = reflection.GetColor().r * temp.node->GetMaterial()->Shade(rRay, temp, lights, bounceCount);
            }
            else{
                rShade =  reflection.GetColor().r *environment.SampleEnvironment(rRay.dir);
//                rShade = Color(1,111,1);
            }
        }
    }
    
  
    
    /* Add shade with reflected and refracted colors */
    shade += (rShade + tShade);
    return shade;
};
Esempio n. 18
0
void doRender(void* arg){
    
    RenderParams rarg = *((RenderParams *)arg);
    //cout<<"Do render...."<<endl;
            bool pixelHit=false;

    
            HitInfo hitInfo;
            hitInfo.Init();
            
            Point2 pixLoc = rarg.pixLocation;
            Cone r = rarg.ray;
            int PixIndex = rarg.pixIndex;
            Color shade(0,0,0);
    
    vector<Point2> haltonXY;
    float dx = rarg.PixParams.x;
    float dy = rarg.PixParams.y;
    float x=0;
    float y=0;
    _f.Normalize();
    _s.Normalize();
    const float pts[9]={_s.x,_u.x,-_f.x,_s.y,_u.y,-_f.y,_s.z,_u.z,-_f.z};

    Matrix3 RotMat;
    RotMat.Set(pts);
    for(int i=0; i < MIN_N_SAMPLES; i++){
        
        x = dx * Halton(i+1, H_BASE_1);
        y = dy * Halton(i+1, H_BASE_2);
        
        if(x > dx * 0.5) { x -= dx; }
        if(y < dy * 0.5) { y -= dy; }
       
        x += rarg.K.x;
        y += rarg.K.y;
        
        Point2 sampleLoc = Point2(x,y);
        haltonXY.push_back(sampleLoc);
    }
    
    vector<Color> shades;
            if(rootNode.GetNumChild()>0){
                for(int i=0; i< MIN_N_SAMPLES;i++){
                    
                    Point3 sampleDir = Point3(haltonXY.at(i).x, haltonXY.at(i).y, rarg.K.z);
                    
                    int rindex = rand() % MAX_N_SAMPLES; //rindex = i;
                    Point3 randPos = rarg.ConfCirclePts.at(rindex);
                    Cone sampleRay = Cone(randPos, sampleDir);
                    sampleRay.dir = sampleRay.dir * RotMat;
                    sampleRay.dir -= randPos - camera.pos;
                    sampleRay.dir.Normalize();
                    sampleRay.radius = r.radius;
                    sampleRay.tanAngle = r.tanAngle;
                    r = sampleRay;
                    
                    if(RayTrace_2(r, hitInfo)) {
                        pixelHit=true;
                        shade = hitInfo.node->GetMaterial()->Shade(r, hitInfo, lights, 8);
                        shades.push_back(shade);
                    }
                    hitInfo.Init();
                }

                if(VarianceOverThreshold(shades)){
                    renderImage.SetSampleCountPixel(PixIndex, 255);
                    
                    hitInfo.Init();
                    
                    for(int i=MIN_N_SAMPLES; i < MAX_N_SAMPLES; i++){
                        
                        x = dx * Halton(i+1, H_BASE_1);
                        y = dy * Halton(i+1, H_BASE_2);
    
                        if(x > dx * 0.5) { x -= dx;}
                        if(y < dy * 0.5) { y -= dy;}
                        
                        x += rarg.K.x;
                        y += rarg.K.y;
                        
                        Point2 sampleLoc = Point2(x,y);
                        haltonXY.push_back(sampleLoc);
                        
                        Point3 sampleDir = Point3(haltonXY.at(i).x, haltonXY.at(i).y, rarg.K.z);
                        
                        int rindex = rand() %  MAX_N_SAMPLES; //rindex = i;
                        Point3 randPos = rarg.ConfCirclePts.at(rindex);
                        Cone sampleRay = Cone(randPos, sampleDir);
                        sampleRay.dir = sampleRay.dir * RotMat;
                        sampleRay.dir -= randPos - camera.pos;
                        
                        sampleRay.dir.Normalize();
                        sampleRay.radius = r.radius;
                        sampleRay.tanAngle = r.tanAngle;
                        r = sampleRay;
                        
                        if(RayTrace_2(r, hitInfo)) {
                            pixelHit=true;
                            shade = hitInfo.node->GetMaterial()->Shade(r, hitInfo, lights, 5);
                            shades.push_back(shade);
                        }
                        hitInfo.Init();
                    }
                    shade = AverageShades(shades, (int)shades.size());
                }
                else{
                    shade = AverageShades(shades, (int)shades.size());
                    renderImage.SetSampleCountPixel(PixIndex, 0);
                }
                renderImage.PutPixel(PixIndex, shade, hitInfo.z);
            }
            
            if(!pixelHit){
                Point3 uvw(pixLoc.x/ camera.imgWidth,pixLoc.y/camera.imgHeight,0);
                shade = background.Sample(uvw);
                renderImage.PutPixel(PixIndex, shade, BIGFLOAT);
            
            }
    pthread_mutex_lock(&setPix_mutex);
    renderImage.IncrementNumRenderPixel(1);
    pthread_mutex_unlock(&setPix_mutex);

}
Esempio n. 19
0
HitInfo CSGNode::intersects(Point3D origin, Vector3D dir) const {
  HitInfo info;
  origin = get_inverse() * origin;
  dir = get_inverse() * dir;
  bool first = true;

  for (ChildList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) {
	HitInfo h = (*it)->intersects(origin, dir);
	for (unsigned int i = 0; i < h.hits.size(); i++) {
 	  h.hits.at(i).intersection = get_transform() * h.hits.at(i).intersection;
	  h.hits.at(i).normal = get_inverse().transpose() * h.hits.at(i).normal;
	}
	for (unsigned int i = 0; i < h.lines.size(); i++) {
	  h.lines.at(i).first.intersection = get_transform() * 
	  	h.lines.at(i).first.intersection;
	  h.lines.at(i).second.intersection = get_transform() * 
	  	h.lines.at(i).second.intersection;	
	  h.lines.at(i).first.normal = get_inverse().transpose() * 
	  	h.lines.at(i).first.normal;
	  h.lines.at(i).second.normal = get_inverse().transpose() * 
	  	h.lines.at(i).second.normal;
	}

	switch(m_type) {
	  case UNION: {
		info = HitInfo::merge_info(info, h);
		break;
	  }
	  case INTERSECTION: {
		if (first) {
		  info = h;
		} else if (h.empty()) {
		  info.clear();
		  return info;
		} else {
		  std::vector<HitInfo::LineSegment> lines;
		  for (unsigned int i = 0; i < info.lines.size(); i++) {
			HitInfo::LineSegment line = info.lines.at(i);
			for (unsigned int j = 0; j < h.lines.size(); j++) {
			  HitInfo::LineSegment sub = h.lines.at(j);

			  if (line.first.t >= sub.first.t && line.second.t <= sub.second.t) {
				// subtracting line contains the first line
				lines = HitInfo::insert_line_in_order(lines, line);
			  } else if (line.first.t < sub.first.t && line.second.t > sub.second.t) {
				// first line contains subtracting line
				lines = HitInfo::insert_line_in_order(lines, sub);
			  } else if (line.first.t > sub.first.t && line.first.t < sub.second.t && 
						 line.second.t > sub.second.t) {
				// tail end of line overlaps with subtracting line.
				double len = (sub.second.intersection-line.first.intersection).length();
				if (len > EPSILON) {
				  lines = HitInfo::insert_line_in_order(lines, 
				    std::make_pair(line.first, sub.second));				
				}
			  } else if (line.first.t < sub.first.t && line.second.t > sub.first.t && 
						 line.second.t < sub.second.t) {
				// head end of line overlaps with subtracting line
				double len = (line.second.intersection-sub.first.intersection).length();
				if (len > EPSILON) {
				  lines = HitInfo::insert_line_in_order(lines,
				    std::make_pair(sub.first, line.second));				
				}
			  } else {
				// no overlap, do nothing
				continue;
			  }
			}
		  }
		  info.lines = lines;
		  std::vector<Hit> hits;
		  for (unsigned i = 0; i < info.hits.size(); i++) {
			Hit hit = info.hits.at(i);
			for (unsigned j = 0; j < h.lines.size(); j++) {
			  HitInfo::LineSegment sub = h.lines.at(j);
			  if (hit.t > sub.first.t && hit.t < sub.second.t) {
				hits.push_back(hit);
				break;
			  }
			}
		  }
		  info.hits = hits;
		}
		break;
	  }
	  case DIFFERENCE: {
		if (first && h.empty()) {
		  return info;
		} else if (first && !h.empty()) {
		  info = HitInfo::merge_info(info, h);
		} else if (!h.empty()) {
		  std::vector<HitInfo::LineSegment> lines;
		  for (unsigned int i = 0; i < info.lines.size(); i++) {
			HitInfo::LineSegment line = info.lines.at(i);
			for (unsigned int j = 0; j < h.lines.size(); j++) {
			  HitInfo::LineSegment sub = h.lines.at(j);

			  if (line.first.t >= sub.first.t && line.second.t <= sub.second.t) {
				// subtracting line contains the first line
				continue;
			  } else if (line.first.t < sub.first.t && line.second.t > sub.second.t) {
				// first line contains subtracting line; divide into two lines.
				sub.first.normal = -sub.first.normal;
				sub.second.normal = -sub.second.normal;
				double len1 = (sub.first.intersection - 
				line.first.intersection).length();
				double len2 = (line.second.intersection-
				sub.second.intersection).length();
				if (len1 > EPSILON) {
				  lines = HitInfo::insert_line_in_order(lines,
					std::make_pair(line.first, sub.first));
				}

				if (len2 > EPSILON) {
				  lines = HitInfo::insert_line_in_order(lines,
					std::make_pair(sub.second, line.second));
				}
			  } else if (line.first.t > sub.first.t && line.first.t < sub.second.t && 
						 line.second.t > sub.second.t) {
				// head end of line overlaps with subtracting line.
				sub.second.normal = -sub.second.normal;
				double len = (line.second.intersection-sub.second.intersection).length();
				if (len > EPSILON) {
				  lines = HitInfo::insert_line_in_order(lines, 
				    std::make_pair(sub.second, line.second));				
				}
			  } else if (line.first.t < sub.first.t && line.second.t > sub.first.t && 
						 line.second.t < sub.second.t) {
				// tail end of line overlaps with subtracting line
				sub.first.normal = -sub.first.normal;
				double len = (line.first.intersection-
				sub.first.intersection).length();
				if (len > EPSILON) {
				  lines = HitInfo::insert_line_in_order(lines,
				    std::make_pair(line.first, sub.first));				
				  }
			  } else {
				// no overlap, line remains unchanged.
				lines = HitInfo::insert_line_in_order(lines, line);
			  }
			}
		  }
		  info.lines = lines;
		  std::vector<Hit> hits;
		  for (unsigned i = 0; i < info.hits.size(); i++) {
			Hit hit = info.hits.at(i);
			bool insert = true;
			for (unsigned j = 0; j < h.lines.size(); j++) {
			  HitInfo::LineSegment sub = h.lines.at(j);
			  if (hit.t > sub.first.t && hit.t < sub.second.t) {
				insert = false;
			  }
			}
			if (insert) {
			  hits.push_back(hit);
			}
		  }
		  info.hits = hits;
		}
		break;
	  }
	}
	first = false;
  }
  return info;
}
Esempio n. 20
0
int main(void)
{
	myEngine::Timing::Clock *clock = myEngine::Timing::Clock::createAndStart();
	int temp = LoadScene(LOAD_FILE);
	Point3 cameraRight = (camera.dir ^ camera.up).GetNormalized();
	double aspectRatio = static_cast<double>(camera.imgWidth) / static_cast<double>(camera.imgHeight);
	float camera_l = 1 / (tan((camera.fov / 2) * (M_PI/ 180)));
	
	Point3 Sx = cameraRight;
	Point3 Sy = (-1.0f) * camera.up;
	
	Point3 pixel;
	Point3 k = camera.pos + camera_l* camera.dir;// -cameraRight + camera.up;

	HitInfo hitInfo;
	

	//Color24 hitPixelColor = { 255,255,255 };
	Color noHitPixelColor = { 0,0,0 };
	Color24* temp_image = renderImage.GetPixels();

	float* temp_zBuffer = renderImage.GetZBuffer();

	
	for (int i = 0;i < camera.imgHeight; i++)
	{
		//printf("%d\n",i);
		for (int j = 0; j < camera.imgWidth; j++)
		{
			hitInfo.Init();
			float flipped_i = camera.imgHeight - i - 1;
			pixel = k + (((2.0f*aspectRatio * (j + 0.5f)) / camera.imgWidth) - aspectRatio)*Sx + ((((flipped_i + 0.5) * 2) / camera.imgHeight) - 1)* Sy;
			pixelRay.p = camera.pos;
			pixelRay.dir = (pixel - camera.pos).GetNormalized();
			
			if (TraceRay(&rootNode, pixelRay, hitInfo))
			{
#ifdef  RELEASE_DEBUG
				temp_image[i*camera.imgWidth + j] = normalColor(hitInfo);
#else
				temp_image[i*camera.imgWidth + j] = hitInfo.node->GetMaterial()->Shade(pixelRay, hitInfo, lights, 7);
#endif
				temp_zBuffer[i*camera.imgWidth + j] = hitInfo.z;
			}
			else
			{

				temp_image[i*camera.imgWidth + j] = noHitPixelColor;
				temp_zBuffer[i*camera.imgWidth + j] = hitInfo.z;
			}
		}
	}

	renderImage.SaveImage("RayCasted.ppm");
	renderImage.ComputeZBufferImage();
	renderImage.SaveZImage("RayCastWithZ.ppm");
	
	clock->updateDeltaTime();
	double time = clock->getdeltaTime();
	printf("Time to render ray casting  %f", clock->getdeltaTime());
	printf("Time to render zBuffer Image  %f", clock->getdeltaTime());

	ShowViewport();
	
}
const Vector3 RectangleLight::sampleLight(const unsigned int threadID, const Vector3 &from, const Vector3 &normal, const float time, const Scene &scene, const Vector3 &rVec, float &outSpec, bool isSecondary) const
{
	Ray sampleRay(threadID);
	HitInfo sampleHit;
	Vector3 randDir = 0, tmpResult = 0;
	float e1, e2, tmpSpec = 0;
	bool cutOff = false;
	int samplesDone = 0;
	float samplesDoneRecip = 1.0f;
	ALIGN_SSE float falloff = 1.0f;

	do
	{
		// Get a random vector into the light
		e1 = Scene::getRand(threadID);
		e2 = Scene::getRand(threadID);
		e2 = (e2 > 0.99) ? 0.99 : e2;
		randDir = ((m_v1 + e1*(m_v2-m_v1) + e2*(m_v3-m_v1)) - from);

		float nDotL = dot(normal, randDir);
		Vector3 E   = 0;
		float attenuate = 1.0f;

		if (nDotL > epsilon)															// Only do work if light can be hit
		{
			// the inverse-squared falloff
			falloff = randDir.length2();
			ALIGN_SSE float distanceRecip, distance;
#ifndef NO_SSE
			fastrsqrtss(setSSE(falloff), distanceRecip);
			recipss(setSSE(falloff), falloff);
			recipss(setSSE(distanceRecip), distance);
#else
			distance      = sqrtf(falloff);
			distanceRecip = 1.0f / distance;
			falloff       = 1.0f / falloff;
#endif
			randDir *= distanceRecip;
			nDotL   *= distanceRecip;

			if (m_castShadows)
			{
				sampleHit.t = distance - epsilon;									// We need this to account for the fact that we CAN hit geometry, to avoid false positives.
				if (m_fastShadows)
				{
					sampleRay.set(threadID, from, randDir, time, 1.001f, 0, 0, IS_SHADOW_RAY);		// Create shadow ray
					if (scene.trace(threadID, sampleHit, sampleRay, epsilon))					// Quick method, returns any hit
					{
						attenuate = 0.0f;
					}
				}
				else																// Full method, accounts for transparency effects
				{
					float distanceTraversed = 0.0f;
					sampleRay.set(threadID, from, randDir, time, 1.001f, 0, 0, IS_PRIMARY_RAY);		// Create primary ray
					while (distanceTraversed < distance && attenuate > epsilon)
					{
						if (scene.trace(threadID, sampleHit, sampleRay, epsilon))				
						{
							Vector3 hitN; sampleHit.getInterpolatedNormal(hitN);
							float nDL = dot(hitN, -randDir);
							if (nDL > 0.0)											// Only attenuate on incoming direction
							{
								attenuate *= sampleHit.obj->m_material->refractAmt();
							}
							Vector3 newP = Vector3(sampleRay.o[0], sampleRay.o[1], sampleRay.o[2]) + sampleHit.t * randDir;
							sampleRay.set(threadID, newP, randDir, time, 1.001f, 0, 0, IS_PRIMARY_RAY);
							distanceTraversed += sampleHit.t;
						}
						else
						{
							distanceTraversed = distance;
						}
					}
				}
			}
		}
		else
		{
			attenuate = 0.0f;														
		}

		E = m_power * falloff * _1_4PI;										// Light irradiance for this sample
		samplesDone++;
		samplesDoneRecip = 1.0f / (float)samplesDone;

		cutOff = (E * samplesDoneRecip).average() < m_noiseThreshold;		// Stop sampling if contribution is below the noise threshold

		tmpResult += E * attenuate;
		tmpSpec   += max(0.f, dot(rVec, randDir)) * attenuate;

	}  while (samplesDone < m_numSamples && !cutOff);

	outSpec = tmpSpec * samplesDoneRecip;
	return tmpResult * samplesDoneRecip;
}