【发布时间】:2016-10-01 07:01:28
【问题描述】:
我编写了一个光线追踪程序,它(目前)有两个表面光照选项:环境光照和反射光照。环境照明复制了自然表面如何散射光。反射显然复制了镜子如何反射光。一切正常,但我不知道如何将颜色与光泽反射混合。
反射算法返回颜色并递归工作。光线以参数化线的形式“投射”。当它们碰到反射表面时,它们会完美地反弹(以及我的这项工作的方法)。然后将这些反射光线作为参数再次调用反射算法。这种情况一直持续到当前光线照射到环境(非反射)表面或当前光线根本不照射到表面为止。
我现在计算颜色的方式是从后到前平均反射表面和新撞击表面的颜色。因此,光线早期击中的表面上的颜色比后来的表面颜色表示得更多。
如果颜色 A 是它撞击的第一个(反射)表面的颜色,颜色 B 是它撞击的第二个表面的颜色,C 是第三个表面的颜色,依此类推。所以最终返回的颜色将是 50% A、25% B、12.5% C...
我为此使用的方法实际上支持加权平均,因此镜像表面对最终颜色的影响较小。这里是:
public void addColor(Color b, double dimFac) {
double red = c.getRed() * (1 - dimFac) + b.getRed() * dimFac;
double green = c.getGreen() * (1 - dimFac) + b.getGreen() * dimFac;
double blue = c.getBlue() * (1 - dimFac) + b.getBlue() * dimFac;
c = new Color((int) red,
(int) green,
(int) blue);
}
这是该程序的屏幕截图。三个环境球体悬停在一个有光泽的反射平面上,“dimFac”为 0.5:
下面是同样的模拟,dimFac 为 1,因此镜子对最终颜色没有影响:
这里的 dimFac 是 0.8
这里是 0.1
也许只有我一个人,但这些反射看起来都不是非常逼真。我用作指导的是康奈尔大学的一个简报,除其他外,它确实提到了有关添加颜色的任何内容。镜子在一定程度上确实有颜色,我不知道混合颜色的正确方法。我做错了什么?
所以我从光线中获取颜色的方式如下。光线追踪器的每次迭代都从形状的初始化开始。该程序支持三种形状:平面、球体和矩形棱柱(最终只有 6 个平面)。我为每个形状都有一个类,以及一个可以存储每种形状类型(但每个对象只有一个)的类(称为 Shapes)。
形状制作完成后,一个类(称为 Projector)通过另一个称为 MasterLight 的类(它实际上包含基本光线追踪、阴影、反射和(现在)折射的方法)投射光线。
为了获得交叉点的颜色,我调用 getColor() 方法,该方法获取交叉点的向量(我如何存储 3d 点)。我用它来确定表面的无阴影颜色。如果表面没有纹理并且只是一种空白颜色(如上面的形状),则返回一个无阴影的颜色(这只是存储在每个形状类“Color c = Color.RED”中)。一个例子是 Color.RED
我采用该颜色并递归地将其插入 MasterLight 作为基础颜色,以获得阴影,就好像表面是正常的和环境的一样。此过程返回形状通常具有的阴影。现在 RGB 值可能是 (128, 0, 0);
public Color getColor(Vector v) {
if (texturing) {
return texturingAlgorithm;
}
else {
return c;
}
}
DimFac 的使用方式有可能是从 0 到 1 的任何值;现在在我的程序中,它是 0.8(这是通用着色常数。在环境着色中,我取我调暗颜色的值并将其乘以 0.8 并加上 0.2(1 - 0.8),这样最暗的颜色可以是其原始亮度的 0.2)。
addColor 在另一个名为 Intersection 的类中(我目前有 17 个,其中一个是枚举)。这存储了关于光线与形状相交的所有重要信息(颜色、位置、撞击表面的法线向量,以及与对象材质相关的一些其他常数)。颜色 c 是计算中该点的当前颜色。
每次反射迭代都会使用最新的表面颜色调用 addColor。更详细地说,如果(在上图中)一条光线刚刚从平面反弹并撞击一个球体并反弹到空旷的空间中,我首先在反弹点找到球体表面的颜色,这就是'c ' 被设定为。然后我用相交点的平面颜色(第一次)调用 addColor。
一旦我回溯了所有的反射,我就会留下一种颜色,这是我用来为特定光线的像素着色的颜色。
告诉我是否遗漏了什么或不清楚。
【问题讨论】:
-
您能否提供一份您用来获取光线颜色的方法的副本?此外,您能否围绕您的
addColor()方法提供一些上下文:dimFac是每个对象的属性,就像在材质中一样?或者它是一个全球价值?你能解释一下你是如何使用Colorc的吗?
标签: java colors raytracing lighting