java - 球体光线追踪 - 镜面高光

标签 java render raytracing lighting

我在为我的球体获取正确的光照模型时遇到一些问题。具体来说,我无法正确获得球体的镜面高光。这是我在光线追踪球体时看到的内容:
Wrong specular highlights

现在,镜面高光应该看起来更像这样:
Correct specular highlights

据我了解,照明模型(对于这些漫射球体)如下所示:
Lighting model

其中cr是球体的颜色,ca是光的环境分量,cl是球体的颜色光,n 是球体交点处的法线,l 是光的方向,cp 是颜色镜面高光,e 是眼睛/Look From,r 是球体表面的反射 vector ,指数中的 p 指的是到 phong 常数/指数(灯光的紧/松程度)。

这是我的过程:

public Color calculateIlluminationModel(Vector normal, Scene scene)
{
    //c = cr * ca + cr * cl * max(0, n \dot l)) + cl * cp * max(0, e \dot r)^p
    Vector lightSourceColor = getColorVector(scene.getLight().getLightColor()); //cl
    Vector diffuseReflectanceColor = getColorVector(getMaterialColor()); //cr
    Vector ambientColor = getColorVector(scene.getLight().getAmbientLightColor()); //ca
    Vector specularHighlightColor = getColorVector(getSpecularHighlight()); //cp
    Vector directionToLight = scene.getLight().getDirectionToLight(); //l
    Vector reflectionVector = normal.multiply(2).multiply(normal.crossProduct(directionToLight)).subtract(directionToLight); //r = 2n(n \dot l) - l

    Vector ambientTerm = diffuseReflectanceColor.multiply(ambientColor);
    double angleBetweenLightAndNormal = directionToLight.dotProduct(normal);
    Vector diffuseTerm = diffuseReflectanceColor.multiply(lightSourceColor).multiply(Math.max(0, angleBetweenLightAndNormal));
    Vector phongTerm = lightSourceColor.multiply(specularHighlightColor).multiply(Math.pow(Math.max(0, scene.getCameraSettings().getLookFrom().dotProduct(reflectionVector)), (double) getPhongConstant()));
    return getVectorColor(ambientTerm.add(diffuseTerm).add(phongTerm));
}

请注意,在本例中,phong 项的眼睛分量是相机的观察方向,即 (0, 0, 1),光线方向为 (1, 0, 0)。

知道为什么我的镜面高光位于球体的顶部而不是面向光线的方向吗?

如果我透露了您需要帮助我的任何重要细节,请告诉我。

最佳答案

反射 vector 应根据表面法线和入射光线方向计算,而不是像现在那样根据光线方向计算。

关于java - 球体光线追踪 - 镜面高光,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40569883/

相关文章:

java - 如何验证休息路径(Spring Boot)

java - 可执行 JAR 中的 OpenJDK 只有 : Why does getResourceAsStream() not return MANIFEST. MF

java - Spring Boot应用程序无法检测sqlite db文件中定义的表

reactjs - 当一项更改时,React 会重新渲染整个列表

ruby-on-rails - 一个 Controller 使用另一个 Controller 的 View 进行渲染

c++ - 无法实现光子映射

java - 是什么导致 UsbRequest 从队列方法抛出 IO 异常?

programming-languages - 计算机图形 : Raytracing and Programming 3D Renders

c++ - 奇怪的光线追踪伪影

java - 如何将列表呈现为模板?