Esempio n. 1
0
void Light::SetIntensitySortValue(const BoundingBox& box)
{
    // When sorting lights for object's maximum light cap, give priority based on attenuation and intensity
    switch (lightType_)
    {
    case LIGHT_DIRECTIONAL:
        sortValue_ = 1.0f / GetIntensityDivisor();
        break;

    case LIGHT_SPOT:
        {
            Vector3 centerPos = box.Center();
            Vector3 lightPos = node_->GetWorldPosition();
            Vector3 lightDir = node_->GetWorldDirection();
            Ray lightRay(lightPos, lightDir);

            Vector3 centerProj = lightRay.Project(centerPos);
            float centerDistance = (centerProj - lightPos).Length();
            Ray centerRay(centerProj, centerPos - centerProj);
            float centerAngle = centerRay.HitDistance(box) / centerDistance;

            // Check if a corner of the bounding box is closer to the light ray than the center, use its angle in that case
            Vector3 cornerPos = centerPos + box.HalfSize() * Vector3(centerPos.x_ < centerProj.x_ ? 1.0f : -1.0f,
                centerPos.y_ < centerProj.y_ ? 1.0f : -1.0f, centerPos.z_ < centerProj.z_ ? 1.0f : -1.0f);
            Vector3 cornerProj = lightRay.Project(cornerPos);
            float cornerDistance = (cornerProj - lightPos).Length();
            float cornerAngle = (cornerPos - cornerProj).Length() / cornerDistance;

            float spotAngle = Min(centerAngle, cornerAngle);
            float maxAngle = tanf(fov_ * M_DEGTORAD * 0.5f);
            float spotFactor = Min(spotAngle / maxAngle, 1.0f);
            // We do not know the actual range attenuation ramp, so take only spot attenuation into account
            float att = Max(1.0f - spotFactor * spotFactor, M_EPSILON);
            sortValue_ = 1.0f / GetIntensityDivisor(att);
        }
        break;

    case LIGHT_POINT:
        {
            Vector3 centerPos = box.Center();
            Vector3 lightPos = node_->GetWorldPosition();
            Vector3 lightDir = (centerPos - lightPos).Normalized();
            Ray lightRay(lightPos, lightDir);
            float distance = lightRay.HitDistance(box);
            float normDistance = distance / range_;
            float att = Max(1.0f - normDistance * normDistance, M_EPSILON);
            sortValue_ = 1.0f / (Max(color_.SumRGB(), 0.0f) * att + M_EPSILON);
        }
        break;
    }
}
Esempio n. 2
0
bool ShadowTracer::hasOcclusion(const Vector light,  const Vector* point) {

  Vector origin = light;
  Vector direction = (origin - *point);
  Vector normalized = direction.normalize();
  
  Ray lightRay(*point, normalized);

  IntersectionPtr intersection = _scene->intersect(lightRay);
  
  if (intersection != nullptr) {
    return fabs((*point - intersection->getPoint()).length()) > 0.001;
  } else {
    return false;
  }
  
}
Esempio n. 3
0
int createLightPath(const RTScene& scene, 
	Rand& rand, 
	int maxVerts,
	PathVertex vertices[])
{
	const auto & light = *scene.light(0);
	ShadingCS lightPosShadingCS(light.normal);
	const float3 lightPos = light.samplePoint(rand);
	const float3 woWorldLight = lightPosShadingCS.world(sampleHemisphere(rand));
	Ray lightRay(lightPos, woWorldLight);
	vertices[0] = PathVertex(light.normal, float3(0), lightPos, &light.material,
		light.material.emission * light.area());
	float3 lightPdf = float3(1.f / (2 * PI * light.area()));
	float3 alpha = light.material.emission * dot(woWorldLight, light.normal) / lightPdf;
	//HACK: changed to intersect lights
	return 1 + createPath(scene, rand, maxVerts - 1, alpha, lightRay, false, &vertices[1]);
}
Esempio n. 4
0
void PointLight::shade( Ray3D& ray, Ray3D::intersection_func intersectCheck ) const {

    Material* mat = ray.intersection.mat;
    
    // compute direction towards light
    Vector3D lightDir = pos_ - ray.intersection.point;
    double distance = lightDir.normalize();
    ray.col += col_ambient_ * mat->ambient.at(ray.intersection.uv);

    // cos of angle from normal to lightDir
    double cosAngle = lightDir.dot(ray.intersection.normal);

    if (cosAngle < 0) {
        return;
    }
    // shadow check
    else {
        Ray3D lightRay(ray.intersection.point, lightDir);
        intersectCheck(lightRay);

        // if we intersect an object between the light and point
        // we are considering, then it is in shadow
        if (!lightRay.intersection.none && lightRay.intersection.t_value < distance ) {
            return;
        }
    }

    // diffuse
    ray.col += col_diffuse_ * mat->diffuse.at(ray.intersection.uv) * cosAngle;

    // direction of reflection of light ray
    Vector3D reflectDir = 2*cosAngle*ray.intersection.normal - lightDir;
    reflectDir.normalize();
    // cos of angle from reflection to ray back to viewer
    double rv = -reflectDir.dot(ray.dir);

    // specular
    if (rv > 0) {
        ray.col += col_specular_ * mat->specular.at(ray.intersection.uv)
                                 * pow(rv, mat->specular_exp);
    }
}
Esempio n. 5
0
RGBQUAD TraceOneRay(CRay ray, CSphere S[], CVector3D lightsArray[],int level, CBox sceneBox)
{
	int n;
	RGBQUAD currentColor;
	currentColor.rgbBlue=20;
	currentColor.rgbGreen=20;
	currentColor.rgbRed=20;
	CVector3D hit,light,lightdir,snormal;

	if(checkIntersection(ray,S,&hit,&n,sceneBox)) 
	{	
		currentColor.rgbBlue=0;
		currentColor.rgbGreen=0;
		currentColor.rgbRed=0;
		//Вычисляем нормаль
		snormal.x=(hit.x-S[n].center.x);
		snormal.y=(hit.y-S[n].center.y);
		snormal.z=(hit.z-S[n].center.z);
		snormal.NormalizeVector();		
		//Проверяем каждый источник света
		for (int lightIndex=0; lightIndex<LIGHT_COUNT; lightIndex++)
		{
			light=lightsArray[lightIndex];
			lightdir.x=light.x-hit.x;
			lightdir.y=light.y-hit.y;
			lightdir.z=light.z-hit.z;
			lightdir.NormalizeVector();

			bool inShadow=false;
			//Находим коэффициент освещения
			float coefLight=snormal*lightdir;
			//Если коэффициент больше 0 то свет попадает
			if(coefLight>0){
				//луч от источника света к месту пересечения с объектом
				CRay lightRay(hit,lightdir);
				//Проверяем не затенен ли данный объект другим объектом
				for (int index=0; index<SPHERE_COUNT; index++)
				{
					
					/*if(index==n) 
						continue;*/
					CVector3D lightHit;
					int num;
					if (checkIntersection(lightRay,S,&lightHit,&num,sceneBox))
					{
						inShadow=true;
						break;
					}
				}
				if(!inShadow)
				{		
					//Создаем отражающий луч
					CVector3D reflectionVector=(ray.vector-2*(((ray.vector*snormal))*snormal));
					CRay reflectionRay(hit,reflectionVector);
					RGBQUAD reflectionColor;
					float coef=1;
					for (int i=0; i<level; i++)
					{
						//coef*=reflectionVector*ray.vector;
						coef*=0.5;
					}
					reflectionColor.rgbBlue=0;
					reflectionColor.rgbGreen=0;
					reflectionColor.rgbRed=0;
					if(level<7)
					{
						reflectionColor=TraceOneRay(reflectionRay,S,lightsArray,++level,sceneBox);
					}
					
					//Свет по Ламберту
					if (reflectionColor.rgbRed==20 && reflectionColor.rgbGreen==20 && reflectionColor.rgbBlue==20)
					{
						reflectionColor.rgbBlue=0;
						reflectionColor.rgbGreen=0;
						reflectionColor.rgbRed=0;
					}
					else
					{
						int k=1;
					}
					if ((int)currentColor.rgbRed+coefLight*S[n].color.rgbRed*0.5+reflectionColor.rgbRed*coef>=255)
					{
						currentColor.rgbRed=255;
					}
					else
					{
						currentColor.rgbRed+=coefLight*S[n].color.rgbRed*0.5+reflectionColor.rgbRed*coef;
					}					
					if ((int)currentColor.rgbGreen+coefLight*S[n].color.rgbGreen*0.5+reflectionColor.rgbGreen*coef>=255)
					{
						currentColor.rgbGreen=255;
					}
					else
					{
						currentColor.rgbGreen+=coefLight*S[n].color.rgbGreen*0.5+reflectionColor.rgbGreen*coef;
					}
					if ((int)currentColor.rgbBlue+coefLight*S[n].color.rgbBlue*0.5+reflectionColor.rgbBlue*coef>=255)
					{
						currentColor.rgbBlue=255;
					}
					else
					{
						currentColor.rgbBlue+=coefLight*S[n].color.rgbBlue*0.5+reflectionColor.rgbBlue*coef;
					}
					
					//Блинн-Фонг взято с http://www.codermind.com/articles/Raytracer-in-C++-Part-II-Specularity-post-processing.html
					float fViewProjection=ray.vector*snormal;
					CVector3D blinnVector=lightRay.vector-ray.vector;
					float temp=blinnVector*blinnVector;
					if (temp!=0)
					{
						float blinn=1/sqrtSSE(temp) * max(coefLight-fViewProjection,0.0f);
						blinn=coef*powf(blinn,20);
						if ((int)currentColor.rgbRed+blinn*S[n].color.rgbRed>=255)
						{
							currentColor.rgbRed=255;
						}
						else
						{
							currentColor.rgbRed+=blinn*S[n].color.rgbRed;
						}
						if ((int)currentColor.rgbGreen+blinn*S[n].color.rgbGreen>=255)
						{
							currentColor.rgbGreen=255;
						}
						else
						{
							currentColor.rgbGreen+=blinn*S[n].color.rgbGreen;
						}
						if ((int)currentColor.rgbBlue+blinn*S[n].color.rgbBlue>=255)
						{
							currentColor.rgbBlue=255;
						}
						else
						{
							currentColor.rgbBlue+=blinn*S[n].color.rgbBlue;
						}						
					}
				}
			}
		}		
	}	
	return currentColor;
}
void GeometryTerrain::computeLightmap(Vector3 _vlightSource, bool update)
{
	bool bIntegrateNormals = false;
	std::vector<GLubyte> shadowMapTexture(GetWidth()*GetWidth()*4);
 
	float maxHeight = -99999.0f;

	for(int z =0; z <= GetLength(); ++z)
		for(int x = 0; x <= GetWidth(); ++x)
			maxHeight = max(getHeight(x,z), maxHeight);

	for(int z =0; z <= GetLength(); ++z)
	{
		for(int x = 0; x <= GetWidth(); ++x)
		{
			float ambientLight = 255;
			Ray lightRay(Vector3(x, getHeight(x, z), z), _vlightSource );
			Vector3 current_ray_pos(Vector3(x, getHeight(x, z), z));
			Vector3 direction_to_sun = lightRay.m_v3Direction.normalize();

			int numRayHits = 0;
			while(!(current_ray_pos.x <= 0 || current_ray_pos.x >= GetWidth() || current_ray_pos.z <= 0 || current_ray_pos.z >= GetWidth() ))
			{
				if(current_ray_pos.y > maxHeight) break;

				// Is the terrain blocking the ray at this point?
				if(getHeight((int)floor(current_ray_pos.x), (int)floor(current_ray_pos.z)) > current_ray_pos.y)
				{
					numRayHits++;
					break;
				}
				//light still traveling...
				current_ray_pos += direction_to_sun;	
			}

			float ambientLightNormals = 0;
			if(bIntegrateNormals)
			{
				Vector3 n(
					m_pNormals[x+z * (GetWidth()+1)].x, 
					m_pNormals[x+z * (GetWidth()+1)].y, 
					m_pNormals[x+z * (GetWidth()+1)].z
					);

				ambientLightNormals = 0.5*( 1.0f + dot(n.normalize(), direction_to_sun) );
				if(ambientLightNormals > 1.0f) ambientLightNormals = 1.0f;
				if(ambientLightNormals < 0.0f) ambientLightNormals = 0.0f;
			}

			if(numRayHits > 0)
			{
					//ambientLight = (current_ray_pos - Vector3(x,getHeight(x,z),z)).magnitude() - ambientLightNormals * 255;
					ambientLight = 170;
					if(ambientLight > 255) ambientLight = 255;
					if(ambientLight < 170) ambientLight = 170;
			}

			int index = (x + z * GetWidth()) * 3;
				for (int i = 0; i < 3; ++i) {

					shadowMapTexture[index + i] = (GLubyte)ambientLight;
				}
		}
	}
	
	for(int z =0; z <= GetLength(); ++z)
	{
		for(int x = 0; x <= GetWidth(); ++x)
		{
			int factor = 2;
			ColorOGL colCurrent;
			colCurrent.m_fRed = shadowMapTexture[(x + z * GetWidth()) * 3 + 0];
			colCurrent.m_fGreen = shadowMapTexture[(x + z * GetWidth()) * 3 + 1];
			colCurrent.m_fBlue = shadowMapTexture[(x + z * GetWidth()) * 3 + 2];

			ColorOGL colT;
			ColorOGL colD;
			ColorOGL colL;
			ColorOGL colR;

			if(shadowMapTexture.size() > ((x + (z+factor) * GetWidth()) * 3 + 0) &&
				shadowMapTexture.size() > ((x + (z+factor) * GetWidth()) * 3 + 1) &&
				shadowMapTexture.size() > ((x + (z+factor) * GetWidth()) * 3 + 2)
				)
			{
				colT.m_fRed = shadowMapTexture[(x + (z+factor) * GetWidth()) * 3 + 0];
				colT.m_fGreen = shadowMapTexture[(x + (z+factor) * GetWidth()) * 3 + 1];
				colT.m_fBlue = shadowMapTexture[(x + (z+factor) * GetWidth()) * 3 + 2];
			}

			if(shadowMapTexture.size() > ((x + (z-factor) * GetWidth()) * 3 + 0) &&
				shadowMapTexture.size() > ((x + (z-factor) * GetWidth()) * 3 + 1) &&
				shadowMapTexture.size() > ((x + (z-factor) * GetWidth()) * 3 + 2)
				)
			{
				colD.m_fRed = shadowMapTexture[(x + (z-factor) * GetWidth()) * 3 + 0];
				colD.m_fGreen = shadowMapTexture[(x + (z-factor) * GetWidth()) * 3 + 1];
				colD.m_fBlue = shadowMapTexture[(x + (z-factor) * GetWidth()) * 3 + 2];
			}

			if(shadowMapTexture.size() > ( (x+factor + z * GetWidth()) * 3 + 0) &&
				shadowMapTexture.size() > ((x+factor + z * GetWidth()) * 3 + 1) &&
				shadowMapTexture.size() > ((x+factor + z * GetWidth()) * 3 + 2)
				)
			{
				colL.m_fRed = shadowMapTexture[(x+factor + z * GetWidth()) * 3 + 0];
				colL.m_fGreen = shadowMapTexture[(x+factor + z * GetWidth()) * 3 + 1];
				colL.m_fBlue = shadowMapTexture[(x+factor + z * GetWidth()) * 3 + 2];
			}

			if(shadowMapTexture.size() > (( x-factor + z * GetWidth()) * 3 + 0) &&
				shadowMapTexture.size() > ((x-factor + z * GetWidth()) * 3 + 1) &&
				shadowMapTexture.size() > ((x-factor + z * GetWidth()) * 3 + 2)
				)
			{
				colR.m_fRed = shadowMapTexture[(x-factor + z * GetWidth()) * 3 + 0];
				colR.m_fGreen = shadowMapTexture[(x-factor + z * GetWidth()) * 3 + 1];
				colR.m_fBlue = shadowMapTexture[(x-factor + z * GetWidth()) * 3 + 2];
			}

			shadowMapTexture[(x + z * GetWidth()) * 3 + 0] = (colT.m_fRed+colD.m_fRed+colR.m_fRed+colL.m_fRed+colCurrent.m_fRed)/5;
			shadowMapTexture[(x + z * GetWidth()) * 3 + 1] = (colT.m_fGreen+colD.m_fGreen+colR.m_fGreen+colL.m_fGreen+colCurrent.m_fGreen)/5;
			shadowMapTexture[(x + z * GetWidth()) * 3 + 2] = (colT.m_fBlue+colD.m_fBlue+colR.m_fBlue+colL.m_fBlue+colCurrent.m_fBlue)/5;
			
		}
	}

	if(update)
	{
		ResourceManager::getInstance()->getTexture2D("resources/textures/lightmap.tga")->bind(2);
		glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, GetWidth(), GetWidth(), GL_RGBA, GL_UNSIGNED_BYTE, &shadowMapTexture[0]);
	}
	else
	{
		ilTexImage(GetWidth(),GetWidth(), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, &shadowMapTexture[0]);
		ilSetData(&shadowMapTexture[0]);
		ilSetInteger(IL_IMAGE_BITS_PER_PIXEL,32);
		ilEnable(IL_FILE_OVERWRITE);
		ilSave(IL_TGA, "resources/textures/lightmap.tga");
	}
}
D3DXCOLOR PhongMaterial::shade(vector<Light*>* lightList, vector<Mesh*>* objectList, Mesh* object, Camera* cam)
{
	float Idiff, Ispec;
	Idiff = 0.0f;
	Ispec = 0.0f;
	D3DXCOLOR returnColor = color;
	D3DXCOLOR specularColor = D3DXCOLOR(255.0f, 255.0f, 255.0f, 255.0f);
	D3DXVECTOR3 L, Lnorm, R, Rnorm, V, Vnorm;
	V = cam->position - object->info.intersectionPoint;
	D3DXVec3Normalize(&Vnorm, &V);
	bool inShadow = false;
	vector<Mesh*> objs = *objectList;
	vector<Light*> lights = *lightList;

	for(int l = 0; l < lights.size(); l++)
	{
		L = lights[l]->position - object->info.intersectionPoint;
		D3DXVec3Normalize(&Lnorm, &L);

		Ray lightRay(object->info.intersectionPoint, Lnorm);

		for(int i = 0; i < objs.size(); i++)
			if(objs[i]->testIntersection(&lightRay).hasIntersected)
				inShadow = true;

		if(!inShadow)
		{
			R = 2 * D3DXVec3Dot(&object->info.intersectionNormal, &Lnorm) * object->info.intersectionNormal- Lnorm;
			D3DXVec3Normalize(&Rnorm, &R);
			
			float dDot = D3DXVec3Dot(&object->info.intersectionNormal, &Lnorm);
			if(dDot < 0.0f)
				dDot = 0.0f;
			if(dDot > 1.0f)
				dDot = 1.0f;

			float sDot = D3DXVec3Dot(&Vnorm, &Rnorm);
			if(sDot < 0.0f)
				sDot = 0.0f;
			if(sDot > 1.0f)
				sDot = 1.0f;
			
			Ispec += ks * pow(sDot, kse);

			if(Ispec > 1.0f)
				Ispec = 1.0f;
			if(Ispec < 0.0f)
				Ispec = 0.0f;
		
			Idiff += kd * dDot;
			//I +=  ks * pow(sDot, kse);
		}
	}
	
	if(inShadow)
		Idiff = lights[0]->ambientIntensity.x;

	else
		Idiff += lights[0]->ambientIntensity.x;

	returnColor *= Idiff;
	specularColor *= Ispec;

	D3DXCOLOR addedColor;
	D3DXColorAdd(&addedColor, &returnColor, &specularColor);

	if(addedColor.r > 255.0f)
		addedColor.r = 255.0f;
	if(addedColor.g > 255.0f)
		addedColor.g = 255.0f;
	if(addedColor.b > 255.0f)
		addedColor.b = 255.0f;

	return addedColor;
}