Parallax mapping working on single triangle
This commit is contained in:
1 parent
7fc46d36a1
commit
14b43239b5
12 files changed
+290
-132
No files matched your search
@@ -0,0 +1,34 @@
|
||||
// Vertex Shader (Bake Stage)
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
attribute vec3 vNormal; // Нормаль самого камня (для освещения при запекании)
|
||||
|
||||
varying vec2 TexCoord;
|
||||
varying float vHeight;
|
||||
varying vec3 vWorldNormal;
|
||||
|
||||
// Данные о плоскости треугольника планеты
|
||||
uniform vec3 uPlanePoint; // Любая вершина треугольника (например, tri.data[0])
|
||||
uniform vec3 uPlaneNormal; // Нормаль треугольника планеты (ось Z из GetRotationForTriangle)
|
||||
uniform float uMaxHeight; // Максимальный размер камня (BASE_SCALE)
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
// 1. Вычисляем вектор от плоскости до текущей вершины камня
|
||||
vec3 vecToVertex = vPosition - uPlanePoint;
|
||||
|
||||
// 2. Проецируем этот вектор на нормаль плоскости (скалярное произведение)
|
||||
// Это и есть кратчайшее расстояние от точки до плоскости
|
||||
float distance = dot(vecToVertex, uPlaneNormal);
|
||||
|
||||
// 3. Нормализуем высоту для записи в текстуру (0.0 - уровень земли, 1.0 - пик)
|
||||
// Clamp гарантирует, что значения не выйдут за пределы, если камень "утоплен"
|
||||
vHeight = clamp(distance / uMaxHeight, 0.0, 1.0);
|
||||
|
||||
TexCoord = vTexCoord;
|
||||
vWorldNormal = vNormal;
|
||||
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Fragment Shader (Bake Stage)
|
||||
varying vec2 TexCoord;
|
||||
varying float vHeight;
|
||||
varying vec3 vWorldNormal;
|
||||
|
||||
uniform sampler2D Texture; // Текстура камня (rock.png)
|
||||
uniform vec3 uLightDir; // Направление света для базового затенения камней при запекании
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 stoneColor = texture2D(Texture, TexCoord);
|
||||
|
||||
// Простое Lambert-освещение, чтобы камни не были "плоскими" в текстуре
|
||||
//float diff = max(dot(normalize(vWorldNormal), normalize(uLightDir)), 0.3);
|
||||
float diff = 1.0;
|
||||
|
||||
// RGB - цвет камня с учетом света, A - нормализованная высота
|
||||
//gl_FragColor = vec4(stoneColor.rgb * diff, vHeight);
|
||||
gl_FragColor = vec4(vHeight, vHeight, vHeight, vHeight);
|
||||
//gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
@@ -1,18 +1,26 @@
|
||||
// Вершинный шейдер (Vertex Shader)
|
||||
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
|
||||
attribute vec3 vNormal;
|
||||
attribute vec3 vTangent; // Новые атрибуты
|
||||
attribute vec3 vBinormal;
|
||||
|
||||
varying vec2 TexCoord;
|
||||
varying vec3 vViewDirTangent;
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
uniform vec3 uViewPos;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||
|
||||
void main() {
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
TexCoord = vTexCoord;
|
||||
|
||||
vec3 viewDirWorld = normalize(uViewPos - vPosition);
|
||||
|
||||
// Строим матрицу перехода из атрибутов
|
||||
// Так как базис ортонормирован, TBN^-1 == TBN_transpose
|
||||
vViewDirTangent = vec3(
|
||||
dot(viewDirWorld, vTangent),
|
||||
dot(viewDirWorld, vBinormal),
|
||||
dot(viewDirWorld, vNormal)
|
||||
);
|
||||
}
|
||||
@@ -1,24 +1,67 @@
|
||||
// Fragment Shader
|
||||
varying vec2 TexCoord;
|
||||
uniform sampler2D Texture; // sandTexture
|
||||
uniform sampler2D StoneMap; // Наша запеченная текстура
|
||||
uniform float testShift1;
|
||||
uniform float testShift2;
|
||||
void main()
|
||||
{
|
||||
vec2 newTexCoord;
|
||||
newTexCoord.x = TexCoord.x;
|
||||
//newTexCoord.y = TexCoord.y - 0.0122;
|
||||
//newTexCoord.y = TexCoord.y * (1.0+testShift) + 0.0122;
|
||||
//newTexCoord.y = (TexCoord.y + 0.0122)*(1.0 +x/500.0);
|
||||
//newTexCoord.y = TexCoord.y * (1.0-6.0/500.0) + 0.0122+ (11.0/500.0) *0.1 -6/5000.0;
|
||||
newTexCoord.y = TexCoord.y;
|
||||
vec4 sandColor = texture2D(Texture, TexCoord);
|
||||
vec4 stoneData = texture2D(StoneMap, newTexCoord);
|
||||
|
||||
//vec3 finalColor = sandColor.rgb*0.5 + stoneData.rgb*0.5;
|
||||
vec3 finalColor = stoneData.rgb;
|
||||
//vec3 finalColor = sandColor.rgb;
|
||||
varying vec3 vViewDirTangent;
|
||||
|
||||
gl_FragColor = vec4(finalColor, 1.0);
|
||||
}
|
||||
uniform sampler2D Texture; // Нам нужен только Alpha канал (высота)
|
||||
uniform float uHeightScale;
|
||||
|
||||
void main() {
|
||||
vec3 viewDir = normalize(vViewDirTangent);
|
||||
float height = texture2D(Texture, TexCoord).a;
|
||||
|
||||
// Рассчитываем вектор смещения P
|
||||
//vec2 p = viewDir.xy * (height * uHeightScale) / viewDir.z;
|
||||
//vec2 p = vec2(viewDir.y, -viewDir.x) * (height * uHeightScale);
|
||||
//vec2 p = viewDir.xy * (height * uHeightScale);
|
||||
vec2 p = vec2(viewDir.x, -viewDir.y) * (height * uHeightScale);
|
||||
vec2 finalTexCoord = TexCoord + p;
|
||||
|
||||
// 1. Визуализация сетки по смещенным координатам
|
||||
// Если сетка кривая или ломается на стыках — значит T, B, N векторы не сошлись
|
||||
vec2 grid = fract(finalTexCoord * 20.0); // 20 ячеек сетки
|
||||
float line = (step(0.9, grid.x) + step(0.9, grid.y));
|
||||
|
||||
// 2. Визуализация вектора смещения через цвет
|
||||
// Красный = смещение по U, Зеленый = смещение по V
|
||||
vec3 offsetColor = vec3(p * 10.0 + 0.5, 0.0); // Умножаем на 10 для видимости
|
||||
|
||||
vec3 finalColor = mix(offsetColor, vec3(1.0), line); // Накладываем сетку поверх цвета
|
||||
|
||||
// 3. Подмешиваем карту высот, чтобы видеть "объемы"
|
||||
gl_FragColor = vec4(finalColor * height, 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
varying vec2 TexCoord;
|
||||
varying vec3 vViewDirTangent;
|
||||
|
||||
uniform sampler2D Texture;
|
||||
uniform float uHeightScale;
|
||||
|
||||
void main() {
|
||||
vec3 viewDir = normalize(vViewDirTangent);
|
||||
|
||||
// Получаем высоту из альфа-канала запеченной текстуры
|
||||
float height = texture2D(Texture, TexCoord).a;
|
||||
|
||||
// Смещение. Знак минус используется, если мы хотим "вдавить" камни
|
||||
// Деление на viewDir.z помогает избежать сильных искажений под углом
|
||||
vec2 p = viewDir.xy * (height * uHeightScale) / viewDir.z;
|
||||
vec2 finalTexCoord = TexCoord + p;
|
||||
|
||||
gl_FragColor = texture2D(Texture, finalTexCoord);
|
||||
}*/
|
||||
|
||||
/*
|
||||
varying vec2 TexCoord;
|
||||
varying vec3 vViewDirTangent; // Тот самый вектор из VS
|
||||
|
||||
void main() {
|
||||
// 1. Нормализуем входящий вектор
|
||||
vec3 v = normalize(vViewDirTangent);
|
||||
|
||||
// 2. Преобразуем компоненты из [-1, 1] в [0, 1] для визуализации
|
||||
// X -> Red, Y -> Green, Z -> Blue
|
||||
vec3 debugColor = v * 0.5 + 0.5;
|
||||
|
||||
gl_FragColor = vec4(debugColor, 1.0);
|
||||
}*/
|
||||
Reference in new issue
Block a user