#graphics #glsl #lighting
Вопрос:
Я тестирую библиотеку «Сокол» (https://github.com/floooh/sokol) для создания простого игрового образца с подсветкой в OpenGL, D3D11 и Metal. Я использую шейдеры, аналогичные учебникам LearnOpenGL (https://learnopengl.com/Lighting/Light-casters).
Это часть моего фрагментарного шейдера:
vec3 lightDir = normalize(light.position - v_position);
float diff = max(dot(normal, lightDir), 0.0);
diffuse = vec3(1.0,1.0,1.0) * diff * vec3(texture(u_diffuse, v_uv));
Цвета в земле не являются непрерывными, вы можете видеть цветовые слои (посмотрите красные линии).
Вот еще один пример использования шейдеров PBR. Опять же, цвет в земле не является непрерывным.
Почему это происходит? Как я могу создать идеальную плоскую площадку?
Ответ №1:
«Полосы», которые вы видите, просто отличаются на 1 в одном из цветовых каналов. Вы только что достигли фактического предела точности цвета 8 бит на канал, между этими двумя полосами просто нет другого презентабельного цвета. В зависимости от используемого дисплея и настроек дисплея он будет более или менее заметен. Существует 3 возможных решения:
- Эффекты особенно заметны, потому что ваш пол окрашен в один сплошной цвет. Человеческий глаз будет наиболее чувствителен к таким изменениям (см. Также эффект полосы Маха). Добавив к нему некоторую структуру / текстуру, он больше не будет восприниматься.
- Используйте дисплей с точностью цветопередачи более 8 бит на канал. В настоящее время HDR-дисплеи допускают 10 или более бит.
- Нанесите на изображение некоторое размытие, чтобы скрыть видимые полосы. Упорядоченное смешение с некоторым шаблоном байера может быть легко реализовано в шейдере GLSL.
Комментарии:
1. Спасибо за помощь, теперь я понимаю. Вы сказали использовать дисплей с 10 или более битами на chanel, но нужно ли мне также изменять свойство цвета буфера кадров? От RGB8 до чего-то вроде RGB16?
2. Что ж, это довольно сложная тема. Для включения вывода HDR обычно требуются некоторые API-интерфейсы для конкретной платформы (и, возможно, даже для конкретного драйвера), и, как правило, для буфера кадров вашего окна необходимо использовать формат с плавающей запятой, драйвер преобразует его в фактическую точность для конкретного используемого дисплея. Посмотрите, например, на эту презентацию nvidia