std::vector<Ray*>& Ray::reflect(const Vector4f& norm){ //norm.Print(); assert(norm[3]==0); if(m_pIntersectionProperties != NULL && m_iRecursiveTime > 1){ float reflectance = Ray::CalculateReflectance(norm,this->m_RayLine.m_Direction,NULL, this->m_pIntersectionProperties->m_Material); Vector4f dir = this->m_RayLine.m_Direction - (norm * 2.0 * norm.dot(this->m_RayLine.m_Direction)); Line ref_dir; ref_dir.m_Direction = dir; ref_dir.m_StartPoint = this->m_pIntersectionProperties->m_IntersectionPoint + (float)0.001 * norm; // Mirror reflection if(m_pIntersectionProperties->m_Material->m_eMaterialType == eMaterialType_opague){ Ray* newray = new Ray(this, ref_dir , this->m_iRecursiveTime-1); if(this->m_bShadowEnabled){ newray->enableShadow(this->m_iNumOfLighting); } else{ newray->disableShadow(); } newray->m_fReflectionIntensity = 1.0; newray->m_iID = -1; this->m_pReflectedRayList.push_back(newray); } // glossy reflection if(m_pIntersectionProperties->m_Material->m_eMaterialType == eMaterialType_glossy){ Vector4f horizontal = ref_dir.m_Direction.cross(this->m_pIntersectionProperties->m_PlanarNormal); Vector4f projection = this->m_pIntersectionProperties->m_PlanarNormal.cross(horizontal); horizontal.Normalize(); projection.Normalize(); for(unsigned int i = 0; i < m_pIntersectionProperties->m_Material->m_iGlossySamepleCount; i++){ Ray* newray = new Ray(this, ref_dir, this->m_iRecursiveTime-1); if(this->m_bShadowEnabled){ newray->enableShadow(this->m_iNumOfLighting); } else{ newray->disableShadow(); } Vector4f newdir = newray->jitter(horizontal,projection,this->m_pIntersectionProperties->m_PlanarNormal,0.6); newray->m_fReflectionIntensity = newdir.dot(ref_dir.m_Direction); newray->m_iID = -1; this->m_pReflectedRayList.push_back(newray); // TODO: add glossy reflection here. } } } return m_pReflectedRayList; }
void RayTracer::CalculateShadow(Ray* _ray){ // Assume ray has an intersection point; //std::cout<<"www"<<std::endl; for(unsigned int i =0 ; i < m_LightList.size(); i++){ std::vector<Vector4f> visiblesample = m_LightList[i]->getVisibleSamplePoint(); float lightintensity = 0.0; //std::cout<<visiblesample.size()<<std::endl; for(unsigned int j = 0; j < visiblesample.size();j++){ Vector4f ptolight = visiblesample[j] - _ray->m_pIntersectionProperties-> m_IntersectionPoint; //ptolight.Print(); ptolight.Normalize(); Line _testray; _testray.m_Direction = ptolight; _testray.m_StartPoint = _ray->m_pIntersectionProperties->m_IntersectionPoint + (float)0.0001 * _ray->m_pIntersectionProperties->m_PlanarNormal; bool intersect = checkIntersection(_testray); if(!intersect){ lightintensity+=1.0; } } lightintensity /= (float)(visiblesample.size()); //std::cout<<lightintensity<<" "<<visiblesample.size()<<std::endl; _ray->setBlockedLight(i,lightintensity); } }
void RayTracer::InitializeViewToWorldMatrix(){ assert(m_pRenderAttribute != NULL); Vector4f up = m_pRenderAttribute->m_ViewFrustrum->m_ViewUpDirection; Vector4f dir = m_pRenderAttribute->m_ViewFrustrum->m_ViewDirection; dir.Normalize(); up = up - (up.dot(dir)) * dir; up.Normalize(); Vector4f w = dir.cross(up); this->m_ViewToWorld[0] = w[0]; this->m_ViewToWorld[4] = w[1]; this->m_ViewToWorld[8] = w[2]; this->m_ViewToWorld[1] = up[0]; this->m_ViewToWorld[5] = up[1]; this->m_ViewToWorld[9] = up[2]; this->m_ViewToWorld[2] = -dir[0]; this->m_ViewToWorld[6] = -dir[1]; this->m_ViewToWorld[10] = -dir[2]; this->m_ViewToWorld[3] = m_pRenderAttribute->m_ViewFrustrum->m_ViewPoint[0]; this->m_ViewToWorld[7] = m_pRenderAttribute->m_ViewFrustrum->m_ViewPoint[1]; this->m_ViewToWorld[11] = m_pRenderAttribute->m_ViewFrustrum->m_ViewPoint[2]; }
Ray* Ray::refract(const Vector4f& norm, Material* _from){ if(m_pIntersectionProperties != NULL && m_iRecursiveTime > 1){ if(this->m_pIntersectionProperties->m_Material->m_eMaterialType==eMaterialType_opague) return NULL; float ni = 0.0; float nt = 0.0; if(_from == NULL){ // From Environment To Material; ni = 1.0; nt = m_pIntersectionProperties->m_Material->m_fRefractiveIndex; } else{ // From Material To Environment; ni = m_pIntersectionProperties->m_Material->m_fRefractiveIndex; nt = 1.0; } Vector4f vertical = this->m_pIntersectionProperties->m_InterpolatedNormal.dot(this->m_RayLine.m_Direction) * this->m_pIntersectionProperties->m_InterpolatedNormal; Vector4f horizontal = ni/nt * (this->m_RayLine.m_Direction - vertical); Vector4f dir = vertical + horizontal; dir.Normalize(); Line ref_dir; ref_dir.m_Direction = dir; ref_dir.m_StartPoint = this->m_pIntersectionProperties->m_IntersectionPoint; Ray* newray = new Ray(this,ref_dir,this->m_iRecursiveTime-1); newray->m_color = this->m_color; newray->m_iID = -1; this->m_pRefractedRay = newray; return newray; } else{ m_isDone = true; return NULL; } }
void RayTracer::InitializeRayList(){ assert(m_pRenderAttribute!=NULL); double factor = (double(this->m_pRenderAttribute->m_iScreenHeight)/2) /tan(this->m_pRenderAttribute->m_ViewFrustrum->m_fFieldOfView*M_PI/360.0); int _height = this->m_pRenderAttribute->m_iScreenHeight; int _width = this->m_pRenderAttribute->m_iScreenWidth; for (int i = 0; i < _height; i++) { for (int j = 0; j < _width; j++) { // Sets up ray origin and direction in view space, // image plane is at z = -1. /** ToDO: * Need to implement anti-aliasing, random sampling. */ if(antiAliasing){ for (int li = -1; li<2; li++) { if (li == 0) { Vector4f origin; Vector4f imagePlane; origin[3] = 1; imagePlane[0] = (-double(_width)/2 + 0.5+j)/factor; imagePlane[1] = (-double(_height)/2 + 0.5+i)/factor; imagePlane[2] = -1; Vector4f _dir (imagePlane[0],imagePlane[1],imagePlane[2]); Vector4f dir = this->m_ViewToWorld * _dir; origin = this->m_ViewToWorld * origin;; Line newrayline; newrayline.m_Direction = dir; newrayline.m_StartPoint = origin; Ray* newray = new Ray(NULL,newrayline,this->m_pRenderAttribute->m_iRayTracingDepth); newray->m_iID = i*_height + j; if(this->m_pRenderAttribute->m_bShadowEnable){ //std::cout<<this->m_LightList.size()<<std::endl; newray->enableShadow(this->m_LightList.size()); } else{ newray->disableShadow(); } m_RayBuffer.push(newray); m_RayList.push_back(newray); } else{ for (int zhuang = -1; zhuang<2; zhuang++) { if (zhuang != 0) { Vector4f origin; Vector4f imagePlane; origin[3] = 1; imagePlane[0] = (-double(_width)/2 + 0.5 +j+ li*0.25)/factor; imagePlane[1] = (-double(_height)/2 + 0.5 +i+ zhuang*0.25)/factor; imagePlane[2] = -1; Vector4f _dir (imagePlane[0],imagePlane[1],imagePlane[2]); Vector4f dir = this->m_ViewToWorld * _dir; origin = this->m_ViewToWorld * origin;; Line newrayline; newrayline.m_Direction = dir; newrayline.m_StartPoint = origin; dir.Normalize(); Ray* newray = new Ray(NULL,newrayline,this->m_pRenderAttribute->m_iRayTracingDepth); newray->m_iID = i*_height + j; if(this->m_pRenderAttribute->m_bShadowEnable){ //std::cout<<this->m_LightList.size()<<std::endl; newray->enableShadow(this->m_LightList.size()); } else{ newray->disableShadow(); } m_RayBuffer.push(newray); m_RayList.push_back(newray); } } } } } else{ Vector4f origin; Vector4f imagePlane; origin[3] = 1; imagePlane[0] = (-double(_width)/2 + 0.5 + j)/factor; imagePlane[1] = (-double(_height)/2 + 0.5 + i)/factor; imagePlane[2] = -1; Vector4f _dir (imagePlane[0],imagePlane[1],imagePlane[2]); Vector4f dir = this->m_ViewToWorld * _dir; origin = this->m_ViewToWorld * origin;; Line newrayline; newrayline.m_Direction = dir; newrayline.m_StartPoint = origin; dir.Normalize(); Ray* newray = new Ray(NULL,newrayline,this->m_pRenderAttribute->m_iRayTracingDepth); newray->m_iID = i*_height + j; if(this->m_pRenderAttribute->m_bShadowEnable){ //std::cout<<this->m_LightList.size()<<std::endl; newray->enableShadow(this->m_LightList.size()); } else{ newray->disableShadow(); } m_RayBuffer.push(newray); m_RayList.push_back(newray); } // } } std::cout<<"Ray List Initialize, Total Number Of Ray: "<<m_RayBuffer.size()<<std::endl; }