Неправильная трассировка с SSLR (локальные отражения в пространстве экрана) - PullRequest
0 голосов
/ 04 ноября 2018

При реализации SSLR я столкнулся с проблемой неправильного отображения объектов: они бесконечно проецируются «вниз» и вообще не отображаются в зеркале. Я даю код и скриншот ниже.

Фрагмент шейдера SSLR:

#version 330 core

uniform sampler2D normalMap; // in view space
uniform sampler2D depthMap; // in view space
uniform sampler2D colorMap;
uniform sampler2D reflectionStrengthMap;
uniform mat4 projection;
uniform mat4 inv_projection;

in vec2 texCoord;

layout (location = 0) out vec4 fragColor;

vec3 calcViewPosition(in vec2 texCoord) {
    // Combine UV & depth into XY & Z (NDC)
    vec3 rawPosition = vec3(texCoord, texture(depthMap, texCoord).r);

    // Convert from (0, 1) range to (-1, 1)
    vec4 ScreenSpacePosition = vec4(rawPosition * 2 - 1, 1);

    // Undo Perspective transformation to bring into view space
    vec4 ViewPosition = inv_projection * ScreenSpacePosition;

    // Perform perspective divide and return
    return ViewPosition.xyz / ViewPosition.w;
}

vec2 rayCast(vec3 dir, inout vec3 hitCoord, out float dDepth) {
    dir *= 0.25f;  

    for (int i = 0; i < 20; i++) {
        hitCoord += dir; 

        vec4 projectedCoord = projection * vec4(hitCoord, 1.0);
        projectedCoord.xy /= projectedCoord.w;
        projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5; 

        float depth = calcViewPosition(projectedCoord.xy).z;
        dDepth = hitCoord.z - depth; 

        if(dDepth < 0.0) return projectedCoord.xy;
    }

    return vec2(-1.0);
}

void main() {
    vec3 normal = texture(normalMap, texCoord).xyz * 2.0 - 1.0;
    vec3 viewPos = calcViewPosition(texCoord);

    // Reflection vector
    vec3 reflected = normalize(reflect(normalize(viewPos), normalize(normal)));

    // Ray cast
    vec3 hitPos = viewPos;
    float dDepth; 
    float minRayStep = 0.1f;
    vec2 coords = rayCast(reflected * max(minRayStep, -viewPos.z), hitPos, dDepth);
    if (coords != vec2(-1.0)) fragColor = mix(texture(colorMap, texCoord), texture(colorMap, coords), texture(reflectionStrengthMap, texCoord).r);
    else fragColor = texture(colorMap, texCoord);
}

Скриншот: sslr

Кроме того, лампа вообще не отражается

Буду благодарен за помощь

UPDATE:

colorMap: cm

normalMap: nm

depthMap: dm

ОБНОВЛЕНИЕ: Я решил проблему с неправильным отражением, но все еще есть проблемы.

Я решил это следующим образом: ViewPosition.y *= -1

Теперь, как вы можете видеть на скриншоте, нижние части объектов по какой-то причине не отражаются. screenshot

Вопрос все еще остается открытым.

1 Ответ

0 голосов
/ 11 ноября 2018

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

  1. Чтобы получить нормали пространства обзора, вам нужно сохранить только вращение камеры и убрать перевод, потому что если вы этого не сделаете, нормали будут вытянуты в противоположном направлении движения камеры и больше не будут иметь правильное направление, даже если вы снова их нормализуете, для столбца Major Mat4 вы можете сделать это так:

    mat4 viewNoTranslation = view; viewNoTranslation [3] = vec4 (0,0, 0,0, 0,0, 1,0);

  2. Выборка глубины из изображения глубины является логарифмической, и если вы ее линеаризуете, вы получите значения от 0 до 1, но они будут неточными в отношении необходимой точности. Я пытался получить значение глубины прямо из вершинного шейдера:

    gl_Position = ubo.projection * ubo.view * ubo.model * inPos; глубина = gl_Position.z;

Я не знаю, правильно ли это, но глубина теперь более точная.

Если вы делаете успехи, пожалуйста, обновите:)

...