我已经写过一个光线跟踪程序(目前)有两种表面照明选项:环境光和反射光。环境照明复制了自然表面散射光的方式。反射显然会复制镜子如何反射光线。一切正常,但我无法弄清楚如何将颜色与光泽反射混合。
反射算法返回一种颜色并递归地工作。光线是"演员"以参数化线的形式。当它们碰到反光表面时,它们会完美地反弹(以及我的工作方法)。然后将这些反射光线用作再次调用反射算法的参数。这种情况一直持续到当前光线照射到环境(非反射)表面或当前光线根本不会撞击表面。
我现在计算颜色的方法是我从后到前平均反射表面和新击中表面的颜色。因此,光线早期点击的表面上的颜色表示的颜色多于以后的表面颜色。
如果颜色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);
}
这是该程序的屏幕截图。有三个环境球体悬停在有光泽的反射平面上,带有一个“暗淡的”光线。 0.5:
这里使用dimFac为1进行相同的模拟,这样镜子对最终颜色没有影响:
这里dimFac是0.8
这里是0.1
也许它只是我,但这些反思看起来都不太逼真。我作为指南使用的是康奈尔的一个powerpoint,其中包括添加颜色的任何内容。镜子确实有一定程度的颜色,我不知道混合颜色的正确方法。我做错了什么?
所以我从光线中获得颜色的方式如下。光线跟踪器的每次迭代都从形状的开始开始。该程序支持三种形状:平面,球体和矩形棱镜(最终只有6个平面)。我有一个每个形状的类,和一个类(称为形状),可以存储每种类型的形状(但每个对象只有一个)。
在形成形状之后,一个类(称为Projector)通过另一个名为MasterLight的类(实际上包含基本光线跟踪,阴影,反射和(现在)折射的方法)来投射光线。
为了获得交叉点的颜色,我调用方法getColor()来获取交集的向量(我如何存储3d点)。我用它来确定表面的无阴影颜色。如果表面没有纹理并且只是一个空白颜色(如上面的形状),那么将返回一个无阴影的颜色(这只是存储在每个形状类中"颜色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在另一个类(我现在有17个,其中一个是枚举)中称为Intersection。这将存储有关光线交叉的所有重要信息(形状(颜色,位置,命中表面的法向矢量以及与对象材质相关的其他常数)。颜色c是计算中该点的当前颜色。
每次反射迭代都会调用具有最新表面颜色的addColor。详细说明,如果(在上图中)一条光线刚刚从飞机上弹开并击中一个球体并弹回到空的空间,我首先在弹跳点找到球体表面的颜色,是什么' c'被设置为。然后我用交叉点(第一次)的平面颜色调用addColor。
一旦我追溯了所有的反射,我就会留下一种颜色,这就是我用来为特定光线的像素着色的颜色。
告诉我是否遗漏了任何内容或不清楚。
答案 0 :(得分:3)
你应该使用Phong-Bui Tong在1975年创建的Phong Shading方法.Phong方程将光照简化为三个部分:环境光,漫反射光和镜面光。
环境光是指在完全黑暗中物体的照明。环境照明不受光源的影响。
漫反射光是基于交叉点的表面法线与来自交叉点的光矢量之间的角度的光的亮度。
镜面光是我相信你正在寻找的。它基于从交叉角度到摄像机位置的矢量与关于表面的光矢量的反射矢量之间的角度。
以下是我通常使用Phong Shading的方法:
**如果您使用的是RGB,请对每个RGB值执行公式。
**我想指出,所有RGB值都应该是标量0.0 - 1.0。如果您使用的是8位RGB(0-255),请在将它们放入公式之前将值除以255,然后将输出值乘以255.
**每当我引用一个向量时,它应该是一个单位向量,也就是说,它应该具有1的大小。
我希望这有帮助!祝你好运!