gpt4 book ai didi

java - Java:光线追踪:光面反射着色

转载 作者:行者123 更新时间:2023-11-29 04:44:29 26 4
gpt4 key购买 nike

我已经编写了一个光线跟踪程序(目前),它有两个用于表面照明的选项:环境光和反射光。环境照明复制了自然表面散射光的方式。反射显然复制了镜子如何反射光。一切正常,但我不知道如何将颜色与光泽反射混合在一起。

反射算法返回颜色并递归工作。光线以参数化线的形式“投射”。当它们碰到反射性表面时,它们会完美反弹(以及我的工作方法)。然后将这些反射射线用作参数,以再次调用反射算法。一直持续到当前射线照射到周围(非反射性)表面或当前射线完全没有照射到表面为止。

现在,我计算颜色的方式是从后到前平均反射表面和新击中的表面的颜色。因此,光线较早照射到的表面上的颜色比后面的表面颜色要多。

如果颜色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:

enter image description here

这是一个相同的模拟,dimFac为1,因此反射镜对最终颜色没有影响:

enter image description here

这里dimFac是0.8

enter image description here

这是0.1

enter image description here

也许只有我一个人,但是这些思考看起来都不现实。我用作指导的是康奈尔(Cornell)的简报,除其他事项外,它并未提及有关添加颜色的任何内容。镜子的确有一定程度的颜色,我不知道混合颜色的正确方法。我做错了什么?

因此,我从射线中获取颜色的方法如下。光线跟踪器的每次迭代都从形状的初始化开始。该程序支持三种形状:平面,球体和直角棱镜(最终仅是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),以使最暗的a颜色可以是其原始亮度的0.2)。

addColor在另一个类中(称为Intersection)(目前我有17个,其中一个是枚举)。这将存储有关光线与形状(颜色,位置,命中表面的法线向量以及与对象的材质有关的其他常数)的交点的所有重要信息。颜色c是计算中该点的当前颜色。

每次反射迭代都会使用最近的表面颜色调用addColor。详细地讲,如果(在上图中)射线刚从飞机上反弹并撞击了一个球体,然后反弹到空的空间中,那么我首先在​​反弹点找到球体表面的颜色,即' 设定为。然后,我用相交点(第一次)的平面颜色调用addColor。

一旦我回溯了所有反射,就剩下一种颜色,这就是我用来为特定光线的像素着色的颜色。

告诉我是否错过了什么,还是不清楚。

最佳答案

您应该使用由Phong-Bui Tong在1975年创建的Phong Shading方法。Phong方程将照明简化为三个部分:环境,漫反射和镜面反射。

环境光是完全处于黑暗中时对象的照明。环境照明不受光源的影响。

漫射光是基于交点的表面法线与交点的光矢量之间的角度的光的亮度。

我相信您正在寻找镜面反射光。它基于从相交角到相机位置的矢量与围绕表面的光矢量的反射矢量之间的角度。

这是我通常使用Phong着色的方式:


对于场景中的任何对象,定义三个常数:Ka(环境照明),Kd(漫射照明)和Ks(镜面照明)。我们还将为对象的光泽度定义一个常量“ n”。我会将这个值保持在3以上。
找到法线向量和光向量的点积,我们现在称此量为“ dF”。
现在,我们计算反射向量:它是法线向量,乘以法线向量和光向量的点积,再乘以2。减去光向量,如果法线和光向量都这样做,则其大小应为1。
找到交点处反射矢量和矢量的点积,我们将其称为“ sF”。
最后,我们将对象的颜色称为“ clr”,最终的颜色将称为“ fClr”。
要获得最终颜色,请使用以下公式:
fClr = Ka(clr)+ Kd(factor)(clr)+ Ks(specularFactor ^ n)(clr)
最后,我检查您的R,G或B值是否超出范围。如果是这种情况,请使R,G或B值等于最接近的界限。


**如果使用的是RGB,请对每个RGB值执行公式。

**我想指出,所有RGB值应为标量0.0-1.0。如果您使用的是8位RGB(0-255),请先将值除以255,然后再将其放入公式中,然后将输出值乘以255。

**每当我提到一个向量时,它都应该是一个单位向量,即它的大小应为1。

我希望这有帮助!祝好运!

关于java - Java:光线追踪:光面反射着色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37798976/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com