OpenGL рендеринг воды: координаты текстуры для отражения и преломления - PullRequest
1 голос
/ 13 октября 2019

Я столкнулся с некоторыми проблемами при попытке сделать массив воды с помощью 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;
    }

Результат выглядиткак это:

Изображение ошибки воды

Как лучи, идущие к центру поверхности воды. Я уже несколько дней царапал мне голову, но ничего не помогло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...