C 我的光线跟踪器中看起来像颗粒状的球体
我想写一个简单的光线跟踪器。最后一张图片应该是这样的:我已经读了一些关于它的东西,下面是我正在做的事情:C 我的光线跟踪器中看起来像颗粒状的球体,c,opengl,raytracing,C,Opengl,Raytracing,我想写一个简单的光线跟踪器。最后一张图片应该是这样的:我已经读了一些关于它的东西,下面是我正在做的事情: create an empty image (to fill each pixel, via ray tracing) for each pixel [for each row, each column] create the equation of the ray emanating from our pixel trace() ray: if ray intersects SP
create an empty image (to fill each pixel, via ray tracing)
for each pixel [for each row, each column]
create the equation of the ray emanating from our pixel
trace() ray:
if ray intersects SPHERE
compute local shading (including shadow determination)
return color;
现在,场景数据如下:它将半径为1的灰色球体设置为(0,0,-3)。它在原点设置一个白色光源
2
amb: 0.3 0.3 0.3
sphere
pos: 0.0 0.0 -3.0
rad: 1
dif: 0.3 0.3 0.3
spe: 0.5 0.5 0.5
shi: 1
light
pos: 0 0 0
col: 1 1 1
我的看起来很奇怪:
//check ray intersection with the sphere
boolean intersectsWithSphere(struct point rayPosition, struct point rayDirection, Sphere sp,float* t){
//float a = (rayDirection.x * rayDirection.x) + (rayDirection.y * rayDirection.y) +(rayDirection.z * rayDirection.z);
// value for a is 1 since rayDirection vector is normalized
double radius = sp.radius;
double xc = sp.position[0];
double yc =sp.position[1];
double zc =sp.position[2];
double xo = rayPosition.x;
double yo = rayPosition.y;
double zo = rayPosition.z;
double xd = rayDirection.x;
double yd = rayDirection.y;
double zd = rayDirection.z;
double b = 2 * ((xd*(xo-xc))+(yd*(yo-yc))+(zd*(zo-zc)));
double c = (xo-xc)*(xo-xc) + (yo-yc)*(yo-yc) + (zo-zc)*(zo-zc) - (radius * radius);
float D = b*b + (-4.0f)*c;
//ray does not intersect the sphere
if(D < 0 ){
return false;
}
D = sqrt(D);
float t0 = (-b - D)/2 ;
float t1 = (-b + D)/2;
//printf("D=%f",D);
//printf(" t0=%f",t0);
//printf(" t1=%f\n",t1);
if((t0 > 0) && (t1 > 0)){
*t = min(t0,t1);
return true;
}
else {
*t = 0;
return false;
}
调用trace()
的代码如下所示:
void draw_scene()
{
//Aspect Ratio
double a = WIDTH / HEIGHT;
double angel = tan(M_PI * 0.5 * fov/ 180);
ray[0].x = 0.0;
ray[0].y = 0.0;
ray[0].z = 0.0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
unsigned int x,y;
float sx, sy;
for(x=0;x < WIDTH;x++)
{
glPointSize(2.0);
glBegin(GL_POINTS);
for(y=0;y < HEIGHT;y++)
{
sx = (((x + 0.5) / WIDTH) * 2.0 ) - 1;
sy = (((y + 0.5) / HEIGHT) * 2.0 ) - 1;;
sx = sx * angel * a;
sy = sy * angel;
//set ray direction
ray[1].x = sx;
ray[1].y = sy;
ray[1].z = -1;
normalizedRayDirection[0] = normalize(ray[1]);
unsigned char* color = trace(ray[0],normalizedRayDirection[0],spheres);
unsigned char x1 = color[0] * 255;
unsigned char y1 = color[1] * 255;
unsigned char z1 = color[2] * 255;
plot_pixel(x,y,x1 %256,y1%256,z1%256);
}
glEnd();
glFlush();
}
}
void draw_场景()
{
//纵横比
双a=宽度/高度;
双角度=tan(μPI*0.5*fov/180);
射线[0],x=0.0;
射线[0],y=0.0;
射线[0],z=0.0;
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
无符号整数x,y;
浮子sx,sy;
对于(x=0;x
代码/理解可能会有很多很多问题。您这样做的可能原因是什么(在
跟踪(…)
的非阴影分支中):
您还可以注释掉前两个计算,因为您将每个计算的结果写入同一个组件。我想你可能是想这样做的:
V[0].x = - rayDirection.x;
V[0].y = - rayDirection.y;
V[0].z = - rayDirection.z;
也就是说,您还应该避免使用
GL_POINT
原语来覆盖2x2像素的四边形。点原语不能保证为正方形,OpenGL实现不需要支持除1.0以外的任何大小。实际上,大多数支持1.0-~64.0,但glDrawPixels(…)
是一种更好的写入2x2像素的方法,因为它跳过了基本体组装和上述限制。无论如何,您在本例中使用的是立即模式,因此glRasterPos(…)
和glDrawPixels(…)
仍然是一种有效的方法。您这样做的可能原因是什么(在跟踪(…)
的非阴影分支中):
您还可以注释掉前两个计算,因为您将每个计算的结果写入同一个组件。我想你可能是想这样做的:
V[0].x = - rayDirection.x;
V[0].y = - rayDirection.y;
V[0].z = - rayDirection.z;
也就是说,您还应该避免使用
GL_POINT
原语来覆盖2x2像素的四边形。点原语不能保证为正方形,OpenGL实现不需要支持除1.0以外的任何大小。实际上,大多数支持1.0-~64.0,但glDrawPixels(…)
是一种更好的写入2x2像素的方法,因为它跳过了基本体组装和上述限制。无论如何,在本例中,您使用的是立即模式,因此glRasterPos(…)
和glDrawPixels(…)
仍然是一种有效的方法。看起来您正在实现公式,但最后偏离了本文的方向
首先,文章警告说D&b的价值可能非常接近,因此-b+D得到的数字非常有限。他们提出了另一种选择
另外,您正在测试t0和t1是否都大于0。这并不一定是真的,你可以击中球体,你可以在里面(虽然你显然不应该在你的测试场景)
最后,我将在开始时添加一个测试,以确认方向向量已规范化。在我的渲染器中,我不止一次地把这个问题搞砸了。看起来你在实现这个公式,但你最终偏离了文章的方向 首先,文章警告说D&b的价值可能非常接近,因此-b+D得到的数字非常有限。他们提出了另一种选择 另外,您正在测试t0和t1是否都大于0。这并不一定是真的,你可以击中球体,你可以在里面(虽然你显然不应该在你的测试场景)
最后,我将在开始时添加一个测试,以确认方向向量已规范化。在我的渲染器中,我已经不止一次地把这个问题搞砸了。我没有花时间去理解你所有的代码,而且我肯定不是一个图形专家,但我相信你遇到的问题被称为“表面痤疮”。在这种情况下,这可能是因为阴影光线与对象本身相交。我在代码中所做的是将epsilon*hitPoint.normal添加到阴影光线原点。这将有效地使光线稍微远离对象,因此它们不会相交
我用的epsilon值是
1.19209290*10^-7的平方根,因为这是一个叫做epsilon
的常数的平方根,这个常数是用我使用的特定语言定义的。我没有花时间理解你所有的代码,而且我肯定不是一个图形专家,但我相信你的问题被称为“表面痤疮”。在这种情况下,这可能是因为阴影光线与对象本身相交。我在代码中所做的是将epsilon*hitPoint.normal添加到阴影光线原点。这将有效地使光线稍微远离对象,因此它们不会相交
我使用的epsilon值是1.19209290*10^-7
的平方根,因为这是一个名为epsilon
的常数的平方根,该常数是用我使用的特定语言定义的。如果有命中,请尝试打印黑色,如果没有则打印白色。因此,我们可以查看结果并从中获取结果。此外,不要尝试使用GL_POINTS
原语
V[0].x = - rayDirection.x;
V[0].y = - rayDirection.y;
V[0].z = - rayDirection.z;