освещение blinn phong создает странные результаты - PullRequest
0 голосов
/ 06 мая 2018

Я создаю raycaster и пытаюсь использовать глобальное освещение в качестве метода затенения Я рассчитал пересечение сферы и куба, а также их нормалей

создание каждого отдельного окружающего, рассеянного и зеркального результата приводит к затенению объекта, как и ожидалось в общем случае после их сложения, как показано в коде ниже

glm::vec3 n = surfaceNormal(position, intersect);
glm::vec3 lightStart = glm::vec3(-10, 1, 10);//light points in 3d space
glm::vec3 lightDir = glm::normalize(lightStart - intersect); // direction towards light source
glm::vec3 viewDir = glm::normalize(cam.pos - intersect); // direction towards camera
glm::vec3 midDir = glm::normalize(lightDir + viewDir);//mid point between light and view

glm::vec3 lightColor = glm::vec3(1, 1, 1);//color of light
glm::vec3 objectColor = color ;

float shinyness = 10.0f;
float ambientStr = 0.1f;   

///ambient
glm::vec3 ambient = lightColor * ambientStr;
///diffuse
glm::vec3 diffuse = lightColor * glm::max(glm::dot(n,lightDir), 0.0f);
///specular

//ks * light color * facing * (max(n dot h))

glm::vec3 specular = lightColor * facing(n, lightDir) * 
std::pow(glm::max(glm::dot(n, midDir), 0.0f), shinyness);

glm::vec3 outColor = ambient + diffuse + specular;
return outColor * objectColor * 255.0f;

метод облицовки возвращает 1, если перекрестное произведение (n, lightDir)> 0, иначе возвращает 0 это нужно для того, чтобы не освещать лица, направленные в неправильном направлении

это результат:

result

1 Ответ

0 голосов
/ 06 мая 2018

*255f уже был подозрительным (типичное использование OpenGL работает с цветными компонентами в диапазоне [0 ... 1]), и вы добавили комментарий

выводом являются значения с плавающей запятой для цвета, выводимого прямо на экран.

Это простая проблема переполнения. Ваш вес представляет собой сумму 0,1+ [0 ... 1] + [0 ... 1] (окружающий, рассеянный и зеркальный), которая попадает в [0,1 ... 2,1], и когда вы умножаете его на цвет Компонент больше 0,5 (приблизительно, 1 / 2,1 является точным пределом), их произведение превышает 1. Затем это число умножается на 255, и результат будет выше 255, а при сокращении до байта он «начинается заново» с черный, по компонентам.

Исходя из кода, который вы показываете, вы, вероятно, можете попробовать что-то вроде

return glm::min(outColor * objectColor * 255.0f, glm::vec3(255f, 255f, 255f));

но для этого может быть лучшая функция.

...