编辑: 我发现所有像素颜色都是上下颠倒的,因为屏幕坐标系和世界坐标系的差异,这个问题已经解决了。
编辑: 在遵循@TheVee建议(使用绝对值)之后,我的图片好多了,但我仍然看到颜色方面存在问题。
我在光线追踪三角形方面遇到一些小问题。这是我关于同一主题的之前的问题的后续。那个问题的答案让我意识到需要采取不同的方法。我采用的新方法效果要好得多,但现在我在我的光线追踪器中看到了一些问题:
但这里是我实际看到的:
我认为我的着色出现了一些问题,这可能与各个三角形的法线有关。在为球体和三角形构建照明模型时,我考虑了以下方程式:
现在,这里是实现此操作的代码:
我发现黄色三角形法线和光源之间的点积为-1,蓝色三角形约为-0.707,所以我不确定法线朝向错误是否是问题所在。无论如何,当我确保光线和法线之间的角度为正数(
我怀疑这将是一个小的拼写错误/错误,但我需要另一双眼睛来发现我没有发现的问题。
注意:我的三角形有顶点
以下是我如何计算所有三角形的法线:
请告诉我是否遗漏了任何你认为解决这些问题的重要内容。
编辑:在@TheVee的帮助下,这是我最终得到的结果:
深度缓冲仍存在问题,并且三角形的光照高亮度也存在问题,但我尝试解决的问题已经解决了。
编辑: 在遵循@TheVee建议(使用绝对值)之后,我的图片好多了,但我仍然看到颜色方面存在问题。
我在光线追踪三角形方面遇到一些小问题。这是我关于同一主题的之前的问题的后续。那个问题的答案让我意识到需要采取不同的方法。我采用的新方法效果要好得多,但现在我在我的光线追踪器中看到了一些问题:
- 有一个三角形永远不会以彩色呈现(它总是黑色的,即使它本来应该是黄色的).
![Expected](https://istack.dev59.com/GLZRs.webp)
![Actual](https://istack.dev59.com/4qjs1.webp)
- 解决第一个问题的调试,即使我删除所有其他对象(包括蓝色三角形),黄色三角形始终呈黑色渲染,因此我不认为这是我发送的阴影射线的问题。我怀疑与相机相对于三角形/平面的角度有关。
- 确定光线是否与平面相交。
- 如果是,确定光线是否在三角形内相交(使用参数坐标)。
private Vector getPlaneIntersectionVector(Ray ray)
{
double epsilon = 0.00000001;
Vector w0 = ray.getOrigin().subtract(getB());
double numerator = -(getPlaneNormal().dotProduct(w0));
double denominator = getPlaneNormal().dotProduct(ray.getDirection());
//ray is parallel to triangle plane
if (Math.abs(denominator) < epsilon)
{
//ray lies in triangle plane
if (numerator == 0)
{
return null;
}
//ray is disjoint from plane
else
{
return null;
}
}
double intersectionDistance = numerator / denominator;
//intersectionDistance < 0 means the "intersection" is behind the ray (pointing away from plane), so not a real intersection
return (intersectionDistance >= 0) ? ray.getLocationWithMagnitude(intersectionDistance) : null;
}
一旦我确定射线与平面相交,下面是用于确定射线是否在三角形内部的代码:
private boolean isIntersectionVectorInsideTriangle(Vector planeIntersectionVector)
{
//Get edges of triangle
Vector u = getU();
Vector v = getV();
//Pre-compute unique five dot-products
double uu = u.dotProduct(u);
double uv = u.dotProduct(v);
double vv = v.dotProduct(v);
Vector w = planeIntersectionVector.subtract(getB());
double wu = w.dotProduct(u);
double wv = w.dotProduct(v);
double denominator = (uv * uv) - (uu * vv);
//get and test parametric coordinates
double s = ((uv * wv) - (vv * wu)) / denominator;
if (s < 0 || s > 1)
{
return false;
}
double t = ((uv * wu) - (uu * wv)) / denominator;
if (t < 0 || (s + t) > 1)
{
return false;
}
return true;
}
我认为我的着色出现了一些问题,这可能与各个三角形的法线有关。在为球体和三角形构建照明模型时,我考虑了以下方程式:
![Lighting model](https://istack.dev59.com/gZUR5.webp)
public Color calculateIlluminationModel(Vector normal, boolean isInShadow, Scene scene, Ray ray, Vector intersectionPoint)
{
//c = cr * ca + cr * cl * max(0, n \dot l)) + cl * cp * max(0, e \dot r)^p
Vector lightSourceColor = getColorVector(scene.getLightColor()); //cl
Vector diffuseReflectanceColor = getColorVector(getMaterialColor()); //cr
Vector ambientColor = getColorVector(scene.getAmbientLightColor()); //ca
Vector specularHighlightColor = getColorVector(getSpecularHighlight()); //cp
Vector directionToLight = scene.getDirectionToLight().normalize(); //l
double angleBetweenLightAndNormal = directionToLight.dotProduct(normal);
Vector reflectionVector = normal.multiply(2).multiply(angleBetweenLightAndNormal).subtract(directionToLight).normalize(); //r
double visibilityTerm = isInShadow ? 0 : 1;
Vector ambientTerm = diffuseReflectanceColor.multiply(ambientColor);
double lambertianComponent = Math.max(0, angleBetweenLightAndNormal);
Vector diffuseTerm = diffuseReflectanceColor.multiply(lightSourceColor).multiply(lambertianComponent).multiply(visibilityTerm);
double angleBetweenEyeAndReflection = scene.getLookFrom().dotProduct(reflectionVector);
angleBetweenEyeAndReflection = Math.max(0, angleBetweenEyeAndReflection);
double phongComponent = Math.pow(angleBetweenEyeAndReflection, getPhongConstant());
Vector phongTerm = lightSourceColor.multiply(specularHighlightColor).multiply(phongComponent).multiply(visibilityTerm);
return getVectorColor(ambientTerm.add(diffuseTerm).add(phongTerm));
}
我发现黄色三角形法线和光源之间的点积为-1,蓝色三角形约为-0.707,所以我不确定法线朝向错误是否是问题所在。无论如何,当我确保光线和法线之间的角度为正数(
Math.abs(directionToLight.dotProduct(normal));
)时,会导致相反的问题:![Absolute value of dot products](https://istack.dev59.com/L1gXo.webp)
注意:我的三角形有顶点
(a,b,c)
,边缘(u,v)
分别使用a-b
和c-b
计算(同样,用于计算平面/三角形法线)。一个Vector
由一个(x,y,z)
点组成,一个Ray
由一个起点Vector
和一个归一化方向Vector
组成。以下是我如何计算所有三角形的法线:
private Vector getPlaneNormal()
{
Vector v1 = getU();
Vector v2 = getV();
return v1.crossProduct(v2).normalize();
}
请告诉我是否遗漏了任何你认为解决这些问题的重要内容。
编辑:在@TheVee的帮助下,这是我最终得到的结果:
![“工作”图像](https://istack.dev59.com/DRvya.webp)
if (denominator < epsilon)
中取绝对值。症状看起来像是前后面多边形的典型问题。请记住,点积很容易为负数,而负数肯定比您的 epsilon 更小,即使它“很大”。 - The Vee