From 14304a843ac2c6745a205b3d91d4062e5ecacac5 Mon Sep 17 00:00:00 2001 From: "re.kovalev" Date: Mon, 13 Feb 2023 10:12:34 +0300 Subject: [PATCH] parallax occlusion --- include/Model.h | 2 +- shaders/gshader.frag | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/include/Model.h b/include/Model.h index d57884d..6cb5da1 100644 --- a/include/Model.h +++ b/include/Model.h @@ -64,7 +64,7 @@ struct Material alignas(16) glm::vec3 ks; // коэф. зеркального блика float p; // показатель глянцевости int normalmapped; // Использование карт нормалей - bool parallaxmapped; // Использование параллакса + int parallaxmapped; // Использование параллакса // Значения по умолчанию Material() : ka(0.2f), kd(0.2f), ks(0.2f), p(1), normalmapped(false), parallaxmapped(false) { }; }; diff --git a/shaders/gshader.frag b/shaders/gshader.frag index 2dc1b89..5dfb36d 100644 --- a/shaders/gshader.frag +++ b/shaders/gshader.frag @@ -28,7 +28,7 @@ uniform sampler2D tex_specular; uniform sampler2D tex_heights; uniform sampler2D tex_normal; -uniform float parallax_heightScale = 0.03; +uniform float parallax_heightScale = 0.1; void main() { @@ -44,9 +44,42 @@ void main() if (parallaxmapped) { - float height = 1.0 - texture(tex_heights, texCoord).r; - new_texCoord -= viewTBN.xy* (height * parallax_heightScale); + // Число слоев + float layersCount = 32; + // Вычислим размер каждого слоя + float layerDepth = 1.0 / layersCount; + // Глубина текущего слоя + float currentLayerDepth = 0.0; + // Величина сдвига между слоями + vec2 deltaTexCoords = (parallax_heightScale * viewTBN.xy / viewTBN.z) / layersCount; + + // Переменные для вычислений + vec2 currentTexCoords = texCoord; + float currentDepthMapValue = 1.0 - texture(tex_heights, currentTexCoords).r; + + // Пока глубина текущего слоя меньше текущего значения глубины из текстуры + while(currentLayerDepth < currentDepthMapValue) + { + // Сдвигаем координаты + currentTexCoords -= deltaTexCoords; + // Обновляем значение глубины из текстуры + currentDepthMapValue = 1.0 - texture(tex_heights, currentTexCoords).r; + // Сдвигаем глубину на следующий слой + currentLayerDepth += layerDepth; + } + + // Получим значение текстурных координат с предыдущего шага + vec2 prevTexCoords = currentTexCoords + deltaTexCoords; + // Значения глубины до и после пересечения + float afterDepth = currentDepthMapValue - currentLayerDepth; + float beforeDepth = 1.0 - texture(tex_heights, prevTexCoords).r - currentLayerDepth + layerDepth; + + // Интерполяция текстурных координат + float weight = afterDepth / (afterDepth - beforeDepth); + new_texCoord = prevTexCoords * weight + currentTexCoords * (1.0 - weight); + + // Проверка диапазона [0;1] if(new_texCoord.x > 1.0 || new_texCoord.y > 1.0 || new_texCoord.x < 0.0 || new_texCoord.y < 0.0) discard; }