diff --git a/shaders/gshader.frag b/shaders/gshader.frag index cd9e258..95910fe 100644 --- a/shaders/gshader.frag +++ b/shaders/gshader.frag @@ -29,7 +29,7 @@ uniform sampler2D tex_normal; uniform bool normalmapped; uniform bool parallaxmapped; -uniform float parallax_heightScale = 0.03; +uniform float parallax_heightScale = 0.1; void main() { @@ -45,9 +45,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; }