Я читал многочисленные статьи о трассировке лучей и затенении, но изображение, прорисованное лучом, выглядит не очень хорошо. Я говорю о очень яркой зеленой зоне рядом с зеркальной подсветкой. Результат зеленого цвета здесь максимален, похоже. Как настроить расцветку и/или затенение расчетов, чтобы это выглядело правильно?Raytracing - как сочетать диффузный и зеркальный цвет?
(Не обращайте внимания на глупый код, я просто пытаюсь сначала исправить принципы).
Вот как это выглядит:
Вот диффузный компонент только:
Вот зеркальная составляющая только:
РЕДАКТИРОВАНИЕ: изменение диффузного цвета в цвете diffuseColor = 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];
Неправильно, это точка. Не может быть «гарантии правильности»;) - это действительно просто способ раскрашивания пикселей с удобными математическими функциями (например, pow для phong и плюс некоторые произвольные значения для ambient). По крайней мере, так я это вижу. Самое главное; PBRT FTW !! 1 –
Пока ваша точка на 100% действительна, многие люди, которые прыгают в raytracing, не понимают этого факта - их обычно качают красивые картинки, не зная, что существует целая куча настроек :) –