Учет волн при выполнении плоских отражений

13

Я изучал примеры Nvidia из SDK, в частности, проект Island11, и обнаружил кое-что любопытное в части кода HLSL, которая корректирует отражения вверх и вниз в зависимости от состояния высоты волны.

Естественно, после изучения краткого абзаца кода:

// calculating correction that shifts reflection up/down according to water wave Y position
float4 projected_waveheight = mul(float4(input.positionWS.x,input.positionWS.y,input.positionWS.z,1),g_ModelViewProjectionMatrix);
float waveheight_correction=-0.5*projected_waveheight.y/projected_waveheight.w;
projected_waveheight = mul(float4(input.positionWS.x,-0.8,input.positionWS.z,1),g_ModelViewProjectionMatrix);
waveheight_correction+=0.5*projected_waveheight.y/projected_waveheight.w;
reflection_disturbance.y=max(-0.15,waveheight_correction+reflection_disturbance.y);

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

введите описание изображения здесь

Теперь это небо отражает то место, где мы должны видеть зеленое / серое / желтоватое отражение местности, пересеченное с базовой линией воды. Моя проблема сейчас в том, что я не могу точно определить, что за этим стоит. Проецируя фактическое мировое пространственное положение точки геометрии волны / воды и затем умножая на -5f, чтобы получить еще одну проекцию той же точки, на этот раз ее координата y изменилась на -0,8 (почему -0,8?).

Подсказки в коде, похоже, указывают на то, что он был получен методом проб и ошибок, поскольку существует избыточность. Например, автор берет отрицательную половину спроецированной координаты y (после деления w):

float waveheight_correction=-0.5*projected_waveheight.y/projected_waveheight.w;

И затем делает то же самое для второго пункта (только положительный, чтобы получить разницу, я полагаю) и объединяет их:

waveheight_correction+=0.5*projected_waveheight.y/projected_waveheight.w;

Убрав деление на 2, я не вижу разницы в улучшении качества (если кто-то захочет меня поправить, сделайте это). Суть этого, кажется, в разнице в прогнозируемом y, почему? Эта избыточность и, казалось бы, произвольный выбор -.8f и -0.15f, позволяют мне сделать вывод, что это может быть комбинацией эвристики / догадок. Есть ли логическое обоснование этому или это просто отчаянный взлом?

Вот преувеличение исходной проблемы, которую исправляет фрагмент кода, наблюдаемый на самом низком уровне тесселяции. Надеюсь, это может зажечь идею, которую мне не хватает. -.8f может быть ссылкой высота, с которой вывести, сколько нарушить координаты текстуры выборки планарно отражение геометрии и визуализации -.15f может быть нижняя граница, мера безопасности.

введите описание изображения здесь

CloseReflector
источник

Ответы:

1

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

v.oddou
источник
2
Можете ли вы рассказать подробнее?