Как улучшить качество моих теней? - PullRequest
2 голосов
/ 24 марта 2012

Во-первых, скриншот:

image

As you can see, the tops of the shadows look OK (if you look at the dirt where the tops of the shrubs are projected, it looks more or less correct), but the base of the shadows is way off.

The bottom left corner of the image shows the shadow map I computed. It's a depth-map from the POV of the light, which is also where my character is standing.

Here's another shot, from a different angle:

image

Any ideas what might be causing it to come out like this? Is the depth of the shrub face too similar to the depth of the ground directly behind it, perhaps? If so, how do I get around that?

I'll post the fragment shader below, leave a comment if there's anything else you need to see.

Fragment Shader

#version 330

in vec2 TexCoord0;
in vec3 Tint0;
in vec4 WorldPos;
in vec4 LightPos;

out vec4 FragColor;

uniform sampler2D TexSampler;
uniform sampler2D ShadowSampler;
uniform bool Blend;

const int MAX_LIGHTS = 16;
uniform int NumLights;
uniform vec3 Lights[MAX_LIGHTS];
const float lightRadius = 100;

float distSq(vec3 v1, vec3 v2) {
    vec3 d = v1-v2;
    return dot(d,d);
}

float CalcShadowFactor(vec4 LightSpacePos)
{
    vec3 ProjCoords = LightSpacePos.xyz / LightSpacePos.w;
    vec2 UVCoords;
    UVCoords.x = 0.5 * ProjCoords.x + 0.5;
    UVCoords.y = 0.5 * ProjCoords.y + 0.5;
    float Depth = texture(ShadowSampler, UVCoords).x;
    if (Depth < (ProjCoords.z + 0.0001))
        return 0.5;
    else
        return 1.0;
}

void main()
{
    float scale;

    FragColor = texture2D(TexSampler, TexCoord0.xy);

    // transparency
    if(!Blend && FragColor.a < 0.5) discard;

    // biome blending
    FragColor *= vec4(Tint0, 1.0f);

    // fog
    float depth = gl_FragCoord.z / gl_FragCoord.w;
    if(depth>20) {
        scale = clamp(1.2-15/(depth-19),0,1);
        vec3 destColor = vec3(0.671,0.792,1.00);
        vec3 colorDist = destColor - FragColor.xyz;
        FragColor.xyz += colorDist*scale;
    }

    // lighting
    scale = 0.30;
    for(int i=0; i

I'm fairly certain this is an offset problem. My shadows look to be about 1 block off, but I can't figure out how to shift them, nor what's causing them to be off.

image


Looks like " смещение карты глубины"на самом деле:

image

Not exactly sure how to set this....do I just call glPolygonOffset перед рендерингом сцены? Попробуете ...

Установка glPolygonOffset на 100,100 усиливает проблему:

Ответы [ 3 ]

2 голосов
/ 24 марта 2012

Это называется эффектом "оленей в фарах" теней, отображаемых в буфер. Есть несколько способов минимизировать этот эффект. Ищите «светлое космическое теневое картирование».

1 голос
/ 05 апреля 2012

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

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

Я добавил несколько комментариев к вашему коду:

vec3 ProjCoords = LightSpacePos.xyz / LightSpacePos.w; // So far so good...
vec2 UVCoords;
UVCoords.x = 0.5 * ProjCoords.x + 0.5; // Right, you're converting X and Y from clip
UVCoords.y = 0.5 * ProjCoords.y + 0.5; // space to texel space...
float Depth = texture(ShadowSampler, UVCoords).x; // I expect we sample a value in [0,1]
if (Depth < (ProjCoords.z + 0.0001)) // Uhoh, we never converted Z's clip space to [0,1]
    return 0.5;
else
    return 1.0;

Итак, я подозреваю, что вы хотите сравнить с ProjCoords.z * 0.5 + 0.5:

if (Depth < (ProjCoords.z * 0.5 + 0.5 + 0.0001))
    return 0.5;
else
    return 1.0;

Кроме того, этот фактор смещения заставляет меня нервничать.А еще лучше, просто возьмите это сейчас и разберитесь с этим, как только тени появятся в правильных местах:

const float bias = 0.0;
if (Depth < (ProjCoords.z * 0.5 + 0.5 + bias))
    return 0.5;
else
    return 1.0;

Возможно, я не совсем прав насчет того, как преобразовать ProjCoords.z, чтобы он соответствовал выборкезначение, однако это, вероятно, проблема.Кроме того, если вы переходите к каскадным картам теней (я рекомендую выравнивать по миру), я настоятельно рекомендую рисовать узоры, представляющие, где просматривается каждая карта теней - это значительно упрощает отладку.

1 голос
/ 04 апреля 2012

NVidia OpenGL SDK имеет пример "каскадных карт теней".Возможно, вы захотите проверить это (хотя сам не использовал).

Как улучшить качество моих теней?

Возможно, проблемаиспользуя неправильную матрицу при рендеринге теней.Ваш пример не демонстрирует, как устанавливаются световые матрицы.По закону Мерфи, я должен предположить, что ошибка заключается в этом недостающем куске кода - поскольку вы решили, что эта часть не важна, она, вероятно, вызывает проблему.Если матрица, используемая при тестировании тени, отличается от матрицы, используемой для визуализации тени, вы получите именно эту проблему.

Я предлагаю на мгновение забыть обо всем, что связано с Minecraft, и поиграться с тенями в простом приложении.Создайте отдельное приложение с плоскостью пола и вращающимся кубом (или чайником, или чем угодно) и отлаживайте там карты теней, пока не освоитесь.Поскольку вы готовы добавить +100 к вознаграждению за этот вопрос, вы также можете опубликовать полный код своего автономного образца здесь - если проблема все еще не устранена.Попытка внедрить технологию, с которой вы не знакомы, в середину рабочего (?) Движка в любом случае не является хорошей идеей.Успокойся, привыкни к технике / технологии / эффекту, а затем интегрируй.

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