コード例 #1
0
ファイル: Grid.cpp プロジェクト: maddy-z/Grid-Acceleration
void Grid::rasterizeSphere(Vec3f center, float radius)
{
	Vec3f coord;

	for (int i = 0; i < num_x; ++i) 
	{
		for (int j = 0; j < num_y; ++j) 
		{
			for (int k = 0; k < num_z; ++k) 
			{
				coord.Set ( min_coor[0] + (i + 0.5f) * del_x, 
							min_coor[1] + (j + 0.5f) * del_y,
							min_coor[2] + (k + 0.5f) * del_z );

				if ( (coord - center).Length() <= radius ) 
				{
					voxels[num_y * num_z * i + num_z * j + k] = true;
				}
				else 
				{
					voxels[num_y * num_z * i + num_z * j + k] = false;
				}
			}
		}
	}

	return;
}
コード例 #2
0
ファイル: draw.C プロジェクト: doctorpangloss/Roto
bool Draw::QtpickColor(Vec3f& col) {
  QColor qcol = QColorDialog::getColor(getCurrColor());
  if (!qcol.isValid()) return false;
  col.Set(float(qcol.red())/255., 
	  float(qcol.green())/255., 
	  float(qcol.blue())/255.);
  return true;
}
コード例 #3
0
ファイル: scene.cpp プロジェクト: TomDunn/Proj3
Vec3f scene::rayTrace(Vec3f eye, Vec3f dir, int recurseDepth)
{
    //start with black, add color as we go
    Vec3f answer(0,0,0);

    //test for intersection against all our objects
    float dist = myObjGroup->testIntersections(eye, dir);
    //if we saw nothing, return the background color of our scene
    if (dist==9999999)
        return bgColor;

    Vec3f textureColor;

    //get the material index and normal vector(at the point we saw) of the object we saw
    int matIndex = myObjGroup->getClosest()->getMatIndex();
    Vec3f normal = myObjGroup->getClosest()->getNormal(eye, dir * dist);

    //determine texture color

    if (myMaterials.at(matIndex).texture==NULL)
        //this is multiplicative, rather than additive
        //so if there is no texture, just use ones
        textureColor.Set(1,1,1);
    else
    {
        //if there is a texture image, ask the object for the image coordinates (between 0 and 1)
        Vec3f coords = myObjGroup->getClosest()->getTextureCoords(eye, dir * dist);

        //get the color from that image location
        textureColor.Set(
            PIC_PIXEL(myMaterials.at(matIndex).texture,(int)(myMaterials.at(matIndex).texture->nx*coords.x()),(int)(myMaterials.at(matIndex).texture->ny*coords.y()),0),
            PIC_PIXEL(myMaterials.at(matIndex).texture,(int)(myMaterials.at(matIndex).texture->nx*coords.x()),(int)(myMaterials.at(matIndex).texture->ny*coords.y()),1),
            PIC_PIXEL(myMaterials.at(matIndex).texture,(int)(myMaterials.at(matIndex).texture->nx*coords.x()),(int)(myMaterials.at(matIndex).texture->ny*coords.y()),2));
        textureColor = textureColor*(1/255.0);
    }

    // add ambient light/color to our answer
    answer += multiplyColorVectors(ambLight, myMaterials.at(matIndex).diffuseCol);

    // set point slightly above the actual surface, prevents
    // issues with that point intersecting itself
    Vec3f point = eye + (dir * dist) + (normal * .0001);
    Vec3f real_point = eye + (dir * dist);

    // get the diffuse color of our material
    Vec3f diffuseColor = myMaterials.at(matIndex).diffuseCol;

    // iterate through lights
    for (int iter = 0; iter < myLights.size(); iter++) {

        Vec3f lightPos = myLights.at(iter).position;
        Vec3f direction= lightPos - point;

        direction.Normalize();
        float distance = myObjGroup->testIntersections(point, direction);

        // if nothing between point and light
        if (distance == 9999999) {
            Vec3f color = multiplyColorVectors(diffuseColor, myLights.at(iter).color);
            float nl    = abs(direction.Dot3(normal));

            answer += (color * nl);

            // now do the specular
            // we need vector that goes from point to eye
            Vec3f backDir = dir * -1.0f;

            Vec3f h		= (backDir + direction);
            h.Normalize();

            Vec3f Cp	=  myMaterials.at(matIndex).specularCol;
            float p		= myMaterials.at(matIndex).shininess;
            float nh	= abs(normal.Dot3(h));

            nh			= pow(nh, p);
            answer		+= multiplyColorVectors(myLights.at(iter).color, Cp) * nh;
        }
    }
    //if the light can see the surface point,
    //add its diffuse color to a total diffuse for the point (using our illumination model)
    //use testIntersection to help decide this

    //add the diffuse light times the accumulated diffuse light to our answer

    if (recurseDepth < 3) {
        Vec3f e = dir * -1.0f;
        e.Normalize();
        Vec3f r = dir + normal * 2.0f * e.Dot3(normal);
        r.Normalize();

        Vec3f bounced = rayTrace(point, r, recurseDepth + 1);
        answer += (multiplyColorVectors(bounced, myMaterials.at(matIndex).reflectiveCol));

        // refraction
        Vec3f transparentColor	= myMaterials.at(matIndex).transparentCol;
        float transpar			= transparentColor.Dot3(transparentColor);

        if (transpar > 0.0f) {
            float exitAngle, entryAngle;

            if (dir.Dot3(normal) < 0.0f) {
                entryAngle = acos(dir.Dot3(normal * -1.0f));
                exitAngle = entryAngle * myMaterials.at(matIndex).refractionIndex;
            } else {
                entryAngle = acos(dir.Dot3(normal));
                exitAngle = entryAngle / myMaterials.at(matIndex).refractionIndex;
            }

            Vec3f b = (dir + (normal * cos(entryAngle))) * (1.0f /sin(entryAngle));
            b.Normalize();
            Vec3f refracted = (b * sin(exitAngle)) - (normal * cos(exitAngle));
            refracted.Normalize();

            answer += multiplyColorVectors(rayTrace(real_point, refracted, recurseDepth + 1), myMaterials.at(matIndex).transparentCol);
        }
    }
    //put a limit on the depth of recursion
    //if (recurseDepth<3)
    //{
    //reflect our view across the normal
    //recusively raytrace from the surface point along the reflected view
    //add the color seen times the reflective color


    //if going into material (dot prod of dir and normal is negative), bend toward normal
    //find entry angle using inverse cos of dot product of dir and -normal
    //multiply entry angle by index of refraction to get exit angle
    //else, bend away
    //find entry angle using inverse cos of dot product of dir and normal
    //divide entry angle by index of refraction to get exit angle
    //recursively raytrace from the other side of the object along the new direction
    //add the color seen times the transparent color
    //}

    //multiply whatever color we have found by the texture color
    answer=multiplyColorVectors(answer,textureColor);
    return answer;
}
コード例 #4
0
ファイル: primitives.cpp プロジェクト: shihongzhi/RayTracing
void Grid::initialRayMarch(MarchingInfo &mi, const Ray &r, float tmin) const
{
	Vec3f rayOri = r.getOrigin();
	Vec3f rayDir = r.getDirection();

	float tbottom,ttop,tfront,tback,tleft,tright,tc;

	float dtx,dty,dtz;
	int celli,cellj,cellk;
	float tnext_x,tnext_y,tnext_z;
	int signx,signy,signz;
	signx = (rayDir.x()>=0) ? 1 : -1;
	signy = (rayDir.y()>=0) ? 1 : -1;
	signz = (rayDir.z()>=0) ? 1 : -1;
	
	//需要求绝对值  这里rayDir.x()等于0没有处理
	dtx = abs(dx / rayDir.x());
	dty = abs(dy / rayDir.y());
	dtz = abs(dz / rayDir.z());

	Vec3f normal;
	Vec3f rayOriTmin = rayOri + rayDir * tmin;
	//这里临界值要注意
	//inside;
	if(max.x()>rayOriTmin.x()&&min.x()<rayOriTmin.x()&&max.y()>rayOriTmin.y()&&min.y()<rayOriTmin.y()&&max.z()>rayOriTmin.z()&&min.z()<rayOriTmin.z())  //忽略了tmin的作用
	{
		celli = (int)((rayOriTmin.x()-min.x())/dx);
		cellj = (int)((rayOriTmin.y()-min.y())/dy);
		cellk = (int)((rayOriTmin.z()-min.z())/dz);

		if(Utility::isZero(rayDir.x()))
			tnext_x = 10000;
		else if(signx == -1)  //如果反方向的话,求tnext不需要加signx  谢谢大师提醒
			tnext_x = (min.x()+celli*dx-rayOri.x())/rayDir.x();
		else
			tnext_x = (min.x()+(celli+signx)*dx-rayOri.x())/rayDir.x();
		if(Utility::isZero(rayDir.y()))
			tnext_y = 10000;
		else if(signy == -1)
			tnext_y = (min.y()+cellj*dy-rayOri.y())/rayDir.y();
		else
			tnext_y = (min.y()+(cellj+signy)*dy-rayOri.y())/rayDir.y();
		if(Utility::isZero(rayDir.z()))
			tnext_z = 10000;
		else if(signz == -1)
			tnext_z = (min.z()+cellk*dz-rayOri.z())/rayDir.z();
		else
			tnext_z = (min.z()+(cellk+signz)*dz-rayOri.z())/rayDir.z();
		//这里tmin如何修改
		mi.Set(0,celli,cellj,cellk,tnext_x,tnext_y,tnext_z,dtx,dty,dtz,signx,signy,signz,normal);
	}
	else //outside
	{
		float t1x,t1y,t1z;
		float t2x,t2y,t2z;
		float tnear,tfar;
		
		if(Utility::isZero(rayDir.x()))
		{
			tleft = 0;
			tright = 10000;
		}
		else
		{
			tleft = (min.x()-rayOri.x())/rayDir.x();
			tright = (max.x()-rayOri.x())/rayDir.x();
		}
		if(Utility::isZero(rayDir.y()))
		{
			tbottom = 0;
			ttop = 10000;
		}
		else
		{
			tbottom = (min.y()-rayOri.y())/rayDir.y();
			ttop = (max.y()-rayOri.y())/rayDir.y();
		}
		if(Utility::isZero(rayDir.z()))
		{
			tback = 0;
			tfront = 10000;
		}
		else
		{
			tback = (min.z()-rayOri.z())/rayDir.z();
			tfront = (max.z()-rayOri.z())/rayDir.z();
		}
		t1x = (signx == 1) ? tleft : tright;
		t2x = (signx == 1) ? tright : tleft;
		t1y = (signy == 1) ? tbottom : ttop;
		t2y = (signy == 1) ? ttop : tbottom;
		t1z = (signz == 1) ? tback : tfront;
		t2z = (signz == 1) ? tfront : tback;

		tnear = Utility::getMax(t1x,t1y,t1z);
		tfar = Utility::getMin(t2x,t2y,t2z);

		if(tnear>tfar) //miss
		{}
		else if(tfar<tmin) //behind
		{}
		else  //hit
		{
			tc = tnear;

			//求i,j,k
			if(rayOri.x()+rayDir.x()*tc+tmin < min.x())   //要加上0.0001
				celli = -1;
			else
				celli = (int)((rayOri.x()+rayDir.x()*tc-min.x()-tmin)/dx);  //减去0.0001是为了使边界也算交
			if(rayOri.y()+rayDir.y()*tc+tmin < min.y())
				cellj = -1;
			else
				cellj = (int)((rayOri.y()+rayDir.y()*tc-min.y()-tmin)/dy);
			if(rayOri.z()+rayDir.z()*tc+tmin < min.z())
				cellk = -1;
			else
				cellk = (int)((rayOri.z()+rayDir.z()*tc-min.z()-tmin)/dz);


			//求tnext
			if(Utility::isZero(rayDir.x()))
				tnext_x = 10000;
			else if(signx == -1)  //如果反方向的话,求tnext不需要加signx  谢谢大师提醒
				tnext_x = (min.x()+celli*dx-rayOri.x())/rayDir.x();
			else
				tnext_x = (min.x()+(celli+signx)*dx-rayOri.x())/rayDir.x();
			if(Utility::isZero(rayDir.y()))
				tnext_y = 10000;
			else if(signy == -1)
				tnext_y = (min.y()+cellj*dy-rayOri.y())/rayDir.y();
			else
				tnext_y = (min.y()+(cellj+signy)*dy-rayOri.y())/rayDir.y();
			if(Utility::isZero(rayDir.z()))
				tnext_z = 10000;
			else if(signz == -1)
				tnext_z = (min.z()+cellk*dz-rayOri.z())/rayDir.z();
			else
				tnext_z = (min.z()+(cellk+signz)*dz-rayOri.z())/rayDir.z();


			if(Utility::isEqual(tc,tleft))
				normal.Set(-1,0,0);
			else if(Utility::isEqual(tc,tright))
				normal.Set(1,0,0);
			else if(Utility::isEqual(tc,tbottom))
				normal.Set(0,-1,0);
			else if(Utility::isEqual(tc,ttop))
				normal.Set(0,1,0);
			else if(Utility::isEqual(tc,tfront))
				normal.Set(0,0,1);
			else if(Utility::isEqual(tc,tback))
				normal.Set(0,0,-1);

			mi.Set(tc,celli,cellj,cellk,tnext_x,tnext_y,tnext_z,dtx,dty,dtz,signx,signy,signz,normal);
			//printf("celli: %d  cellj: %d  cellk: %d \n",celli,cellj,cellk);
		}
	}
}