2016-09-02 7 views
2

Я пытаюсь вычислить нормали на поверхности сферы в вершинном шейдере, потому что откладываю вычисление моего шума до вершинного шейдера , Нормальные результаты хороши, когда мой тета (угол отбора проб) ближе к 1, но для более подробной местности & меньшая тета, мои нормали становятся очень неправильными. Вот что я имею в виду:GLSL вычисление нормали на сфере сетки в вершинном шейдере с использованием шумовой функции путем выборки создает странные графические ошибки

Точных нормали

Accurate normals

Более подробный шум с более высокой тетой

More detailed noise with a higher theta

Увеличенный на поверхность последнего изображения. Красный цвет указывает на гребни, синий показывает неправильные тени

More detailed noise with a higher theta zoomed in

код я использую для расчета нормалей:

vec3 calcNormal(vec3 pos) 
{ 
    float theta = .1; //The closer this is to zero the less accurate it gets 
    vec3 vecTangent = normalize(cross(pos, vec3(1.0, 0.0, 0.0)) 
     + cross(pos, vec3(0.0, 1.0, 0.0))); 
    vec3 vecBitangent = normalize(cross(vecTangent, pos)); 
    vec3 ptTangentSample = getPos(pos + theta * normalize(vecTangent)); 
    vec3 ptBitangentSample = getPos(pos + theta * normalize(vecBitangent)); 

    return normalize(cross(ptTangentSample - pos, ptBitangentSample - pos)); 
} 

Я называю calcNormal с

calcNormal(getPos(position)) 

где GetPos является 3D шумовая функция, которая принимает и возвращает vec3, а позиция - это исходное положение на сфере.

+1

Если вы, возможно, нормализовать аргументы 'GetPos()' проецировать его на сфере? Правильно ли предположить, что сфера имеет единичный радиус и центрирована в начале координат? –

+0

@NicoSchertler OH! Это верно. Благодаря! Я изменил строки ptTangentSample и ptBitangentSample на getPos (** normalize ** (...)) – samsun96

ответ

0

Благодаря @NicoSchertler правильная версия calcNormal является

vec3 calcNormal(vec3 pos) 
{ 
    float theta = .00001; 
    vec3 vecTangent = normalize(cross(pos, vec3(1.0, 0.0, 0.0)) 
    + cross(pos, vec3(0.0, 1.0, 0.0))); 
    vec3 vecBitangent = normalize(cross(vecTangent, pos)); 
    vec3 ptTangentSample = getPos(normalize(pos + theta * normalize(vecTangent))); 
    vec3 ptBitangentSample = getPos(normalize(pos + theta * normalize(vecBitangent))); 

    return normalize(cross(ptTangentSample - pos, ptBitangentSample - pos)); 
    }