gpt4 book ai didi

graphics - 光线追踪-如何结合漫反射和镜面反射颜色?

转载 作者:行者123 更新时间:2023-12-04 03:22:01 31 4
gpt4 key购买 nike

我已经阅读了许多有关光线跟踪和着色的文章,但是我的光线跟踪图像看起来不太好。我说的是镜面反射高光附近非常明亮的绿色区域。结果绿色在这里看起来最大。
如何调整颜色和/或阴影计算以使其看起来正确?

(不要管那些愚蠢的代码,我只是想首先弄清楚这些原则)。

外观如下:

这仅是扩散成分:

这仅是镜面反射组件:

编辑:将漫反射更改为颜色漫反射颜色= ColorMake(0.0f,0.6f,0.0f);
然后图像如下所示:

Point lightPosition = PointMake(-100.0f, 100.0f, -100.0f);
Color diffuseColor = ColorMake(0.0f, 1.0f, 0.0f);
Color specularColor = ColorMake(1.0f, 1.0f, 1.0f);
Color pixelColor = ColorMake(0.0f, 0.0f, 0.0f);

// Trace...

// Diffuse
Point intersectionPosition = PointMake(x, y, z);
Vector intersectionNormal = VectorMake((x - xs) / rs, (y - ys) / rs, (z - zs) / rs);
Vector intersectionNormalN = VectorNormalize(intersectionNormal);
Vector lightVector = VectorSubtract(lightPosition, intersectionPosition);
VectorlightVectorN = VectorNormalize(lightVector);
float cosTheta = VectorDotProduct(intersectionNormalN, lightVectorN);
if (cosTheta < 0.0f)
{
cosTheta = 0.0f;
}

pixelColor = ColorMultScalar(diffuseColor, cosTheta);

// Specular
Vector incomVector = VectorSubtract(intersectionPosition, lightPosition);
Vector incomVectorN = VectorNormalize(incomVector);

float myDot = - VectorDotProduct(incomVectorN, intersectionNormalN);
float myLen = 2.0f * myDot;

Vector tempNormal = VectorMultScalar(intersectionNormalN, myLen);
Vector reflectVector = VectorAdd(tempNormal, incomVectorN);
Vector reflectVectorN = VectorNormalize(reflectVector);

float mySpec = MAX(-VectorDotProduct(reflectVectorN, incomVectorN), 0);
mySpec = powf(mySpec, 5);

specularColor = ColorMultScalar(specularColor, mySpec);
pixelColor = ColorAdd(pixelColor, specularColor);
pixelColor = ColorClamp(pixelColor);

[self putPixelatX:i andY:j andR:pixelColor.r andG:pixelColor.g andB:pixelColor.b];

最佳答案

问题是,当您计算球体的漫反射颜色时,您已经有一小部分像素是1或非常接近1(在绿色 channel 中)。将“phong”分量(在所有 channel 中的值都接近1)相加,得出的像素面积> =1。然后将颜色值钳制为1时,> = 1的面积代表出去。

您可以使用图片编辑程序对此进行测试,并进行两层(漫反射层上方的phong层)的“加法”叠加。这给出了您看到的结果-以及预期的结果。

您可以通过多种措施来避免此问题:

  • 您可以使光源稍微变暗,即将您从余弦计算出的漫射强度乘以亮度-例如0.8或0.7。
  • 您可以限制球体的颜色饱和度(即绿色)并使其不那么贪婪;)
  • 使用色调映射运算符将像素的颜色值归一化为[0..1]范围-但是该主题范围很广-维基百科可能提供了很好的介绍。您甚至不必全力以赴,因为对于非基于物理的渲染,较简单的色调映射运算符可能足以满足需要并产生令人愉悦的结果。

  • 我的光线跟踪实验可以追溯到几年前,但是您可以尝试这些方法。

    更新1:

    我注意到的一件事是,当您对输出图像进行 Gamma 校正时-效果不太明显;)-好的,那有点斑驳。

    最终的解决方案是进行物理校正或仅使用另一个着色模型 Wikipedia on Specular highlight

    更新2:

    一种实际的解决方案是计算phong对最终像素颜色(即变量 mySpec)的贡献。这个想法是只使用镜面反射实际上不为0的漫反射分量的一部分,也就是说,如果您有一些镜面反射分量,则实际上看不到漫反射分量太多(或根本看不到),因此可以调整为:
    float diffuseContrib = 1.f - mySpec;

    这看起来应该不错,但我不确定它的正确性:)。

    但是请注意;这假定您的镜面反射和漫反射分量在[0..1]范围内。

    我的结果看起来像这样:

    关于graphics - 光线追踪-如何结合漫反射和镜面反射颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15619830/

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