⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graytrace.cpp

📁 一个非常有用的开源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	if(pDistance)		m_pBoundingBoxTree->FindClosestIntersection(m_pCamera->GetLookFromPoint(), &directionVector, pDistance);	return pRay->m_color.GetGColor();}#define SQRT_RAYS_PER_PIXEL 12GColor GRayTraceScene::RenderPixelAntiAliassed(GRayTraceRay* pRay, GRayTraceVector* pScreenPoint, GRayTraceReal* pDistance){	GRayTraceVector jitter;	int x, y;	GRayTraceColor col;	GRayTraceReal focalDistance = m_pCamera->GetFocalDistance();	GRayTraceReal r1, r2;	for(y = 0; y < SQRT_RAYS_PER_PIXEL; y++)	{		for(x = 0; x < SQRT_RAYS_PER_PIXEL; x++)		{			GRayTraceVector directionVector(pScreenPoint);			// Jitter in X direction			jitter.Copy(&m_pixDX);			jitter.Multiply((GRayTraceReal)(((double)x + GBits::GetRandomDouble()) / SQRT_RAYS_PER_PIXEL - .5));			directionVector.Add(&jitter);			// Jitter in Y direction			jitter.Copy(&m_pixDY);			jitter.Multiply((GRayTraceReal)(((double)y + GBits::GetRandomDouble()) / SQRT_RAYS_PER_PIXEL - .5));			directionVector.Add(&jitter);			// Cast the ray			directionVector.Subtract(m_pCamera->GetLookFromPoint());			if(focalDistance > 0)			{				// Use focus lens -- Start from a random point on the lens and fire at the focal point				while(true)				{					r1 = (GRayTraceReal)(GBits::GetRandomDouble() - .5);					r2 = (GRayTraceReal)(GBits::GetRandomDouble() - .5);					if(r1 * r1 + r2 * r2 <= .25)						break;				}				GRayTraceVector dx(m_pCamera->GetViewSideVector());				dx.Multiply(r1 * m_pCamera->GetLensDiameter());				GRayTraceVector dy(m_pCamera->GetViewUpVector());				dy.Multiply(r2 * m_pCamera->GetLensDiameter());				directionVector.Multiply(focalDistance);				directionVector.Subtract(&dx);				directionVector.Subtract(&dy);				directionVector.Normalize();				GRayTraceVector lensPoint(m_pCamera->GetLookFromPoint());				lensPoint.Add(&dx);				lensPoint.Add(&dy);				pRay->Cast(this, &lensPoint, &directionVector, m_pCamera->GetMaxDepth());			}			else			{				// Perfect focus -- just fire straight				directionVector.Normalize();				pRay->Cast(this, m_pCamera->GetLookFromPoint(), &directionVector, m_pCamera->GetMaxDepth());			}			// Make sure the color doesn't exceed pure white since it will be added with other measurements			pRay->m_color.Clip();			col.Add(&pRay->m_color);		}	}	col.Multiply((GRayTraceReal)1 / (SQRT_RAYS_PER_PIXEL * SQRT_RAYS_PER_PIXEL));	if(pDistance)	{		GRayTraceVector directionVector(pScreenPoint);		directionVector.Subtract(m_pCamera->GetLookFromPoint());		directionVector.Normalize();		m_pBoundingBoxTree->FindClosestIntersection(m_pCamera->GetLookFromPoint(), &directionVector, pDistance);	}	return col.GetGColor();}GColor GRayTraceScene::RenderPixelPathTrace(GRayTraceRay* pRay, GRayTraceVector* pScreenPoint){	GRayTraceVector jitter;	int x, y;	GRayTraceColor col;	GRayTraceReal focalDistance = m_pCamera->GetFocalDistance();	GRayTraceReal r1, r2;	for(y = 0; y < SQRT_RAYS_PER_PIXEL; y++)	{		for(x = 0; x < SQRT_RAYS_PER_PIXEL; x++)		{			GRayTraceVector directionVector(pScreenPoint);			// Jitter in X direction			jitter.Copy(&m_pixDX);			jitter.Multiply((GRayTraceReal)(((double)x + GBits::GetRandomDouble()) / SQRT_RAYS_PER_PIXEL - .5));			directionVector.Add(&jitter);			// Jitter in Y direction			jitter.Copy(&m_pixDY);			jitter.Multiply((GRayTraceReal)(((double)y + GBits::GetRandomDouble()) / SQRT_RAYS_PER_PIXEL - .5));			directionVector.Add(&jitter);			// Cast the ray			directionVector.Subtract(m_pCamera->GetLookFromPoint());			if(focalDistance > 0)			{				// Use focus lens -- Start from a random point on the lens and fire at the focal point				while(true)				{					r1 = (GRayTraceReal)(GBits::GetRandomDouble() - .5);					r2 = (GRayTraceReal)(GBits::GetRandomDouble() - .5);					if(r1 * r1 + r2 * r2 <= .25)						break;				}				GRayTraceVector dx(m_pCamera->GetViewSideVector());				dx.Multiply(r1 * m_pCamera->GetLensDiameter());				GRayTraceVector dy(m_pCamera->GetViewUpVector());				dy.Multiply(r2 * m_pCamera->GetLensDiameter());				directionVector.Multiply(focalDistance);				directionVector.Subtract(&dx);				directionVector.Subtract(&dy);				directionVector.Normalize();				GRayTraceVector lensPoint(m_pCamera->GetLookFromPoint());				lensPoint.Add(&dx);				lensPoint.Add(&dy);				pRay->Trace(this, &lensPoint, &directionVector, m_pCamera->GetMaxDepth(), true);			}			else			{				// Perfect focus -- just fire straight				directionVector.Normalize();				pRay->Trace(this, m_pCamera->GetLookFromPoint(), &directionVector, m_pCamera->GetMaxDepth(), true);			}			col.Add(&pRay->m_color);		}	}	col.Multiply((GRayTraceReal)1 / (SQRT_RAYS_PER_PIXEL * SQRT_RAYS_PER_PIXEL));	// Apply tone mapping constant	GRayTraceReal luminance = col.r * (GRayTraceReal)0.299 + col.g * (GRayTraceReal)0.587 + col.b * (GRayTraceReal)0.114;	GRayTraceReal desiredLuminance = (m_toneMappingConstant * luminance) / ((GRayTraceReal)1.0 + m_toneMappingConstant * luminance);	col.Multiply(desiredLuminance / luminance);	return col.GetGColor();}bool GRayTraceScene::RenderLine(){	if(m_nY < 0)		return false;	GRayTraceRay ray;	int x;	GRayTraceVector screenPoint(&m_pixSide);	screenPoint.Copy(&m_pixSide);	m_pixSide.Add(&m_pixDY);	int nWidth = m_pImage->GetWidth();	GRayTraceReal distance;	GRayTraceReal* pDistance = m_pDistanceMap ? &distance : NULL;	GColor col = 0;	for(x = nWidth - 1; x >= 0; x--)	{		switch(m_eMode)		{			case FAST_RAY_TRACE:				col = RenderPixel(&ray, &screenPoint, pDistance);				break;			case QUALITY_RAY_TRACE:				col = RenderPixelAntiAliassed(&ray, &screenPoint, pDistance);				break;			case PATH_TRACE:				col = RenderPixelPathTrace(&ray, &screenPoint);				break;			default:				GAssert(false, "unrecognized case");		}		m_pImage->SetPixel(x, m_nY, col);		if(pDistance)			m_pDistanceMap[nWidth * m_nY + x] = distance;		screenPoint.Add(&m_pixDX);	}	if(--m_nY >= 0)		return true;	else		return false;}void GRayTraceScene::Render(){	RenderBegin();	while(RenderLine())	{	}}GColor GRayTraceScene::RenderSinglePixel(int x, int y){	// Init the rendering	RenderBegin();	// Compute the screen point	GRayTraceVector screenPoint(&m_pixSide);	m_pixDY.Multiply((GRayTraceReal)(m_pImage->GetHeight() - 1 - y));	screenPoint.Add(&m_pixDY);	m_pixDX.Multiply((GRayTraceReal)(m_pImage->GetWidth() - 1 - x));	screenPoint.Add(&m_pixDX);	// Cast the ray	GRayTraceRay ray;	GColor c = RenderPixel(&ray, &screenPoint, NULL);	return c;}// -----------------------------------------------------------------------------GRayTraceLight::GRayTraceLight(GRayTraceReal r, GRayTraceReal g, GRayTraceReal b): m_color(1, r, g, b){}/*virtual*/ GRayTraceLight::~GRayTraceLight(){}// -----------------------------------------------------------------------------GRayTraceDirectionalLight::GRayTraceDirectionalLight(GRayTraceReal dx, GRayTraceReal dy, GRayTraceReal dz, GRayTraceReal r, GRayTraceReal g, GRayTraceReal b, GRayTraceReal jitter): GRayTraceLight(r, g, b), m_direction(dx, dy, dz), m_jitter(jitter){}/*virtual*/ GRayTraceDirectionalLight::~GRayTraceDirectionalLight(){}/*virtual*/ void GRayTraceDirectionalLight::ComputeColorContribution(GRayTraceScene* pScene, GRayTraceRay* pRay, GRayTraceMaterial* pMaterial, bool bSpecular){	GRayTraceVector direction(&m_direction);	if(m_jitter > 0)		GRayTraceRay::JitterRay(&direction, m_jitter);	// Check if the point is in a shadow	GRayTraceReal distance;	if(pScene->GetBoundingBoxTree()->FindClosestIntersection(&pRay->m_collisionPoint, &direction, &distance))		return;	// Compute diffuse component of the color	GRayTraceColor diffuse(pMaterial->GetColor(GRayTraceMaterial::Diffuse, pRay));	diffuse.Multiply(MAX((GRayTraceReal)0, direction.DotProduct(&pRay->m_normalVector)));	// Compute specular component of the color	if(bSpecular)	{		GRayTraceReal mag = (GRayTraceReal)pow(MAX((GRayTraceReal)0, pRay->m_reflectionVector.DotProduct(&direction)), pMaterial->GetSpecularExponent());		GRayTraceColor specular(pMaterial->GetColor(GRayTraceMaterial::Specular, pRay));		specular.Multiply(mag);		diffuse.Add(&specular);	}	// Multiply by light intensity	diffuse.Multiply(&m_color);	pRay->m_color.Add(&diffuse);}// -----------------------------------------------------------------------------GRayTracePointLight::GRayTracePointLight(GRayTraceReal x, GRayTraceReal y, GRayTraceReal z, GRayTraceReal r, GRayTraceReal g, GRayTraceReal b, GRayTraceReal jitter): GRayTraceLight(r, g, b), m_position(x, y, z), m_jitter(jitter){}/*virtual*/ GRayTracePointLight::~GRayTracePointLight(){}/*virtual*/ void GRayTracePointLight::ComputeColorContribution(GRayTraceScene* pScene, GRayTraceRay* pRay, GRayTraceMaterial* pMaterial, bool bSpecular){	GRayTraceVector lightDirection(&m_position);	if(m_jitter > 0)	{		// Jitter light position (to create soft shadows)		lightDirection.m_vals[0] += (GRayTraceReal)(m_jitter * 2 * GBits::GetRandomDouble() - m_jitter);		lightDirection.m_vals[1] += (GRayTraceReal)(m_jitter * 2 * GBits::GetRandomDouble() - m_jitter);		lightDirection.m_vals[2] += (GRayTraceReal)(m_jitter * 2 * GBits::GetRandomDouble() - m_jitter);	}	// Check if the point is in a shadow	lightDirection.Subtract(&pRay->m_collisionPoint);	double distsqared = lightDirection.GetMagnitudeSquared();	lightDirection.Normalize();	GRayTraceReal distance;	if(pScene->GetBoundingBoxTree()->FindClosestIntersection(&pRay->m_collisionPoint, &lightDirection, &distance))	{		if(distance * distance < distsqared)			return;	}	// Compute diffuse component of the color	GRayTraceColor diffuse(pMaterial->GetColor(GRayTraceMaterial::Diffuse, pRay));	diffuse.Multiply(MAX((GRayTraceReal)0, lightDirection.DotProduct(&pRay->m_normalVector)));	// Compute specular component of the color	if(bSpecular)	{		GRayTraceReal mag = (GRayTraceReal)pow(MAX((GRayTraceReal)0, pRay->m_reflectionVector.DotProduct(&lightDirection)), pMaterial->GetSpecularExponent());		GRayTraceColor specular(pMaterial->GetColor(GRayTraceMaterial::Specular, pRay));		specular.Multiply(mag);		diffuse.Add(&specular);	}	// Multiply by light intensity	diffuse.Multiply(&m_color);	diffuse.Multiply((GRayTraceReal)(1.0 / distsqared));	pRay->m_color.Add(&diffuse);}// -----------------------------------------------------------------------------GRayTraceAreaLight::GRayTraceAreaLight(GRayTraceObject* pObject, GRayTraceReal r, GRayTraceReal g, GRayTraceReal b): GRayTraceLight(r, g, b), m_pObject(pObject){}/*virtual*/ GRayTraceAreaLight::~GRayTraceAreaLight(){}/*virtual*/ void GRayTraceAreaLight::ComputeColorContribution(GRayTraceScene* pScene, GRayTraceRay* pRay, GRayTraceMaterial* pMaterial, bool bSpecular){	GRayTraceVector lightDirection;	if(m_pObject->GetType() == GRayTraceObject::Triangle)	{		// Pick a random point on the triangle		GRayTraceTriangle* pTri = (GRayTraceTriangle*)m_pObject;		GRayTraceVector u(pTri->GetVertex(1));		u.Subtract(pTri->GetVertex(0));		GRayTraceVector v(pTri->GetVertex(2));		v.Subtract(pTri->GetVertex(0));		double a = GBits::GetRandomDouble() * 2 - 1;		double b = GBits::GetRandomDouble() * 2 - 1;		if(a + b > 1)		{			a = 1 - a;			b = 1 - b;		}		u.Multiply((GRayTraceReal)a);		v.Multiply((GRayTraceReal)b);		lightDirection.Copy(pTri->GetVertex(0));		lightDirection.Add(&u);		lightDirection.Add(&v);	}	else if(m_pObject->GetType() == GRayTraceObject::Sphere)	{		// Pick a random point on a disc facing the point of collision		GRayTraceSphere* pSphere = (GRayTraceSphere*)m_pObject;		GRayTraceVector u, v;		GRayTraceVector N(pSphere->GetCenter());		N.Subtract(&pRay->m_collisionPoint);		N.Normalize();		if(ABS(N.m_vals[0]) < 0.5)		{			v.m_vals[0] = 1;			u.CrossProduct(&N, &v);		} 		else 		{ 			v.m_vals[1] = 1;			u.CrossProduct(&N, &v);		}		u.Normalize();		v.CrossProduct(&u, &N);		double a, b;		while(true)		{			a = GBits::GetRandomDouble() * 2 - 1;			b = GBits::GetRandomDouble() * 2 - 1;			if(a * a + b * b < 1)				break;		}		u.Multiply((GRayTraceReal)a);		v.Multiply((GRayTraceReal)b);		lightDirection.Copy(pSphere->GetCenter());		lightDirection.Add(&u);		lightDirection.Add(&v);	}	else	{		GAssert(false, "Unrecognized object type");	}	// Check if the point is in a shadow	lightDirection.Subtract(&pRay->m_collisionPoint);	double distsqared = lightDirection.GetMagnitudeSquared();	lightDirection.Normalize();	GRayTraceReal distance;	GRayTraceObject* pObj = pScene->GetBoundingBoxTree()->FindClosestIntersection(&pRay->m_collisionPoint, &lightDirection, &distance);	if(pObj != m_pObject && pObj && distance * distance < distsqared)		return;	GRayTraceColor diffuse(&m_color);	diffuse.Multiply(pMaterial->GetColor(GRayTraceMaterial::Diffuse, pRay));	if(m_pObject->GetType() == GRayTraceObject::Triangle)	{		GRayTraceTriangle* pTri = (GRayTraceTriangle*)m_pObject;		GRayTraceVector u(pTri->GetVertex(1));		u.Subtract(pTri->GetVertex(0));		GRayTraceVector v(pTri->GetVertex(2));		v.Subtract(pTri->GetVertex(0));		GRayTraceVector t;		t.CrossProduct(&u, &v);		GRayTraceReal triangleArea = (GRayTraceReal)sqrt(t.GetMagnitudeSquared()) / 2;		GRayTraceVector triangleNormal;		triangleNormal.ComputeTriangleNormal(pTri->GetVertex(0), pTri->GetVertex(1), pTri->GetVertex(2));		diffuse.Multiply(ABS(pRay->m_normalVector.DotProduct(&lightDirection) * triangleNormal.DotProduct(&lightDirection) * triangleArea / (GRayTraceReal)(PI * distsqared)));	}	else	{		GRayTraceSphere* pSphere = (GRayTraceSphere*)m_pObject;		diffuse.Multiply(pRay->m_normalVector.DotProduct(&lightDirection)  * pSphere->GetRadius() * pSphere->GetRadius() / (GRayTraceReal)distsqared);	}	pRay->m_color.Add(&diffuse);}// -----------------------------------------------------------------------------GRayTraceMaterial::GRayTraceMaterial(){	SetColor(Diffuse, (GRayTraceReal).5, (GRayTraceReal).5, (GRayTraceReal).5);	SetColor(Specular, 1, 1, 1);	SetColor(Reflective, 1, 1, 1);	SetColor(Transmissive, 0, 0, 0);	SetColor(Ambient, (GRayTraceReal).1, (GRayTraceReal).1, (GRayTraceReal).1);	SetColor(Emissive, 0, 0, 0);	m_indexOfRefraction = 1;	m_specularExponent = 1;	m_glossiness = 0;	m_cloudiness = 0;	m_pTextureImage = NULL;	m_bDeleteTextureImage = false;}GRayTraceMaterial::GRayTraceMaterial(GRayTraceMaterial* pThat){	SetColor(Diffuse, pThat->GetColor(Diffuse, NULL));	SetColor(Specular, pThat->GetColor(Specular, NULL));	SetColor(Reflective, pThat->GetColor(Reflective, NULL));	SetColor(Transmissive, pThat->GetColor(Transmissive, NULL));	SetColor(Ambient, pThat->GetColor(Ambient, NULL));	SetColor(Emissive, pThat->GetColor(Emissive, NULL));	m_indexOfRefraction = pThat->m_indexOfRefraction;	m_specularExponent = pThat->m_specularExponent;	m_glossiness = pThat->m_glossiness;	m_cloudiness = pThat->m_cloudiness;	m_pTextureImage = pThat->m_pTextureImage;	m_bDeleteTextureImage = false;}GRayTraceMaterial::~GRayTraceMaterial(){	if(m_bDeleteTextureImage)		delete(m_pTextureImage);}GRayTraceColor* GRayTraceMaterial::GetColor(ColorType eType, GRayTraceRay* pRay){	if(m_pTextureImage && eType == Diffuse)	{		GAssert(pRay->DidRayHitTexture(), "ray doesn't know about this");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -