карты теней, трюк с ву, пилинг глубины

Я пытаюсь создать самозатеняющийся объект (opengl/glsl). Шаги, которые я сделал, были следующими:

1- Рендерим сцену из света, чтобы получить карту глубины

2- Рендеринг из положения камеры и вычисление расстояния от каждой точки до источника света, если расстояние от точки до источника света больше, чем глубина, хранящаяся в карте глубины, точка находится в тени.

но потом появляется проблема теневых прыщей. Итак, второй шаг будет выглядеть так:

2- ...if(abs(DISTANCE_OF_THE_POINT_TO_LIGHT - DEPTH_STORED_IN_THE_DEPTH_MAP) > BIAS) точка находится в тени.

но все же это не дает мне хороших результатов (нет подходящего значения смещения).

Итак, я реализовал трюк woo (нахождение первой и второй поверхностей по свету, а затем сохранение средней точки в буфере глубины). Для этого я сделал двухпроходный глубокий пилинг. Шаги:

1- Рендерим сцену из света, чтобы получить 1-ю карту глубины, как обычно.

2- Рендерим сцену от света для получения 2-й карты глубины, если расстояние до света точки равно расстоянию в 1-й карте глубины, отбрасываем такую ​​точку (т.е. не рендерим первый слой).

3- Сохранить как окончательную карту глубины (1-я карта глубины + 2-я карта глубины)/2

4- Рендерим из положения камеры и вычисляем расстояние от каждой точки до источника света, если расстояние от точки до источника света больше, чем глубина, сохраненная в карте глубины, точка находится в тени.

проблема появляется теперь на шаге 2, ТАКАЯ ЖЕ проблема у нас была раньше: когда первый и второй слой близки, возникают ошибки округления, а также появляются какие-то прыщи, а также нет подходящего значения смещения. так что я не получаю никакой пользы от алгоритма woo, он просто перемещает проблему в часть очистки глубины.

как вы можете это решить?


person Matias Morant    schedule 08.07.2013    source источник
comment
Я никогда не слышал термина «уловка». Джон Кармак предложил аналогичный трюк много лет назад, используя переднюю грань с последующим рендерингом задней грани вместо пилинга глубины.   -  person a.lasram    schedule 09.07.2013


Ответы (1)


Я не получаю никакой пользы от алгоритма woo, он просто перемещает проблему в часть очистки глубины.

Проблема Z-борьбы существует как при очистке глубины, так и при отображении теней, но в случае с отображением теней дело обстоит намного хуже.

При картировании теней вы находитесь в пространстве камеры, где вы вычисляете значение z и примерное местоположение (x,y) в пространстве карты теней. Проблема в том, что часто в пространстве карты теней нет образца (x,y), поэтому вы берете самый близкий образец к (x,y), а затем сравниваете глубину тени со своим значением z.

В отличие от карт теней, при очистке глубины вы сравниваете z значений в одном и том же месте выборки (в одном и том же пространстве карты теней). На самом деле это отличное решение для борьбы с теневыми артефактами, если вы можете себе это позволить, но оно поможет не во всех ситуациях, например:

Если у вас есть большой объект на экране, скажем, дом. Проекция дома на карте теней может находиться в пределах нескольких или даже одной выборки (одного пикселя), и в этом случае все значения z, вычисленные для дома, будут сравниваться с одним и тем же значением z на карте теней. И наоборот, один пиксель на экране может соответствовать огромной области на карте теней.

Предложение улучшить ваши результаты:

Убедитесь, что DEPTH_STORED_IN_THE_DEPTH_MAP вычисляется точно так же, как DISTANCE_OF_THE_POINT_TO_LIGHT. Обратите особое внимание на скрытую фиксированную арифметику конвейера. Либо используйте их как для DEPTH_STORED_IN_THE_DEPTH_MAP, так и для DISTANCE_OF_THE_POINT_TO_LIGHT, либо никогда не используйте их.

Используйте 32-битные текстуры с плавающей запятой для хранения глубины.

Попробуй процент ближе к фильтру PCF.

Глубинный пилинг дает вам адаптивную предвзятость. У вас также может быть адаптивное разрешение: Каскадные карты теней .

person a.lasram    schedule 09.07.2013