Я столкнулся с некоторыми проблемами при попытке сделать массив воды с помощью GLSL. У текстур, которые я использую как отражение и преломление, их координаты рассчитаны неправильно, и я не могу понять, что не так. Он основан на руководстве по DirectX11 и был преобразован в соответствии со стандартами GLSL.
Вершинный шейдер:
#version 330 core
layout (location = 0) in vec3 vPos;
layout (location = 1) in vec2 vTexCoords;
out vec4 reflectionPosition;
out vec4 refractionPosition;
out vec3 viewDirection;
out vec2 tex1;
out vec2 tex2;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 reflection;
uniform vec3 viewPos;
uniform vec2 normalMapTiling;
void main()
{
mat4 reflectProjectWorld = reflection * projection * model;
reflectionPosition = reflectProjectWorld * vec4(vPos, 1.0f);
mat4 viewProjectWorld = view * projection * model;
refractionPosition = viewProjectWorld * vec4(vPos, 1.0f);
vec4 worldPosition = model * vec4(vPos, 1.0f);
viewDirection = viewPos - vec3(worldPosition);
viewDirection = normalize(viewDirection);
tex1 = vTexCoords / normalMapTiling.x;
tex2 = vTexCoords / normalMapTiling.y;
gl_Position = projection * view * model * vec4(vPos, 1.0f);
}
Фрагментный шейдер:
#version 330 core
out vec4 FragColor;
in vec4 reflectionPosition;
in vec4 refractionPosition;
in vec3 viewDirection;
in vec2 tex1;
in vec2 tex2;
uniform sampler2D refractionTexture;
uniform sampler2D reflectionTexture;
uniform sampler2D normalTexture;
uniform vec4 refractionTint;
uniform vec3 lightDirection;
uniform float waterTranslation;
uniform float reflectRefractScale;
uniform float specularShininess;
void main()
{
vec4 normalMap1;
vec4 normalMap2;
vec3 normal1;
vec3 normal2;
vec3 normal;
vec2 refractTexCoord;
vec2 reflectTexCoord;
vec4 reflectionColor;
vec4 refractionColor;
vec3 heightView;
float r;
float fresnelFactor;
vec4 color;
vec3 reflection;
float specular;
vec2 texCoord1 = tex1;
vec2 texCoord2 = tex2;
texCoord1.y += waterTranslation;
texCoord2.y += waterTranslation;
normalMap1 = texture(normalTexture, texCoord1);
normalMap2 = texture(normalTexture, texCoord2);
normal1 = (normalMap1.rgb * 2.0f) - 1.0f;
normal2 = (normalMap2.rgb * 2.0f) - 1.0f;
normal = normalize(normal1 + normal2);
refractTexCoord.x = refractionPosition.x / refractionPosition.w / 2.0f + 0.5f;
refractTexCoord.y = -refractionPosition.y / refractionPosition.w / 2.0f + 0.5f;
reflectTexCoord.x = reflectionPosition.x / reflectionPosition.w / 2.0f + 0.5f;
reflectTexCoord.y = -reflectionPosition.y / reflectionPosition.w / 2.0f + 0.5f;
reflectTexCoord = reflectTexCoord + (normal.xy * reflectRefractScale);
refractTexCoord = refractTexCoord + (normal.xy * reflectRefractScale);
reflectionColor = texture(reflectionTexture, reflectTexCoord);
refractionColor = texture(refractionTexture, refractTexCoord);
refractionColor = clamp(refractionColor * refractionTint, 0.0, 1.0);
heightView.x = viewDirection.y;
heightView.y = viewDirection.y;
heightView.z = viewDirection.y;
r = (1.2f - 1.0f) / (1.2f + 1.0f);
fresnelFactor = max(0.0f, min(1.0f, r + (1.0f - r) * pow(1.0f - dot(normal, heightView), 2)));
color = mix(reflectionColor, refractionColor, fresnelFactor);
reflection = -reflect(normalize(lightDirection), normal);
specular = dot(normalize(reflection), normalize(viewDirection));
if(specular > 0.0f)
{
specular = pow(specular, specularShininess);
color = clamp(color + specular, 0.0, 1.0);
}
FragColor = color;
}
Результат выглядиткак это:
Изображение ошибки воды
Как лучи, идущие к центру поверхности воды. Я уже несколько дней царапал мне голову, но ничего не помогло.