2014-09-27 2 views
0

Я пытаюсь отобразить карту высот с помощью обычной карты, используя OpenGL и GLSL. Что я до сих пор: Квадратная сетка с высотой, обновляемая в вершинном шейдере на основе карты высот. Сформирован нормальная текстура Примера оды одного предложения этого типа: http://www.leadwerks.com/wiki/images/0/08/Terr16.JPGOpenGL рендеринг hieghtmap с нормальной картой

местность не имеет касательные или вершинные нормали. Я не могу заставить свою световую систему работать без этих атрибутов. Я предполагаю, что я должен использовать матрицу TBN для корректного создания векторов. Но как это сделать без вершинного нормального или касательного? Есть ли более простой способ, чем сложное воспроизведение всего? Действительно ли это утечка нормального преобразования? Или мой метод расчета света неправильный? кодекса фрагменты:

ВС:

vec4 pos=vertex_position;//grid position (only x,z) 
pos.y=((texture(heightmap_tex,uv_coords).x)*scale_height); 
pos.w=1.0;//to be safe 
vec4 P=viewMatrix*pos; 
vec3 L=mat3(MVmatrix)*vec3(worldLightPos)-P.xyz; 
Out.lightDir=L; 
vec3 V=-P.xyz; 
Out.eyeDir=V; 
Out.texCOORD=uv_coords; 
gl_Position = MVPmatrix * pos; 

FS:

vec3 V=normalize(In.eyeDir); 
vec3 L=normalize(In.lightDir); 
vec2 norm_texture=texture(texturenormal,In.TexCoord).xy*2.0-vec2(1.0); 
vec3 N=normalize(vec3(norm_texture,sqrt(1.0-dot(norm_texture.xy, norm_texture.xy))*2.0-vec3(1.0)));//unpacking from 2 channel 
vec3 R=reflect(-L,N);//phong 
vec3 specular=pow(max(dot(R,V),0.0),shininess)*specularColor;//phong 
vec3 diffuse=max(dot(N,L),0.1)*vec3(texColor);//phong 

Сейчас местность становится ярче/темнее на основе камеры влево/вправо вращение. Так что это далеко не правильно.

+0

Прямо сейчас рельеф становится ярче/темнее, основываясь на вращении влево/вправо. Так что это далеко не правильно. – Skides

+1

Вам не нужны тангенсы для нормальной карты местности, если вы не деформируете ее. Я думаю, что ваш расчет 'L' в вершинном шейдере выглядит немного подозрительным. Что такое 'MVmatrix' и что происходит, когда вы создаете из него' vec3'? – GuyRT

ответ

0

Я сделал это, взяв образец карты высоты соседних вершин и вычислив нормали с результатом. Итак, для вершины (x, y), я пробую карту высоты в этой точке. Затем я также пробую его в (x + 1, y) и (x, y + 1) и возьмем произведение произведений результирующих векторов. Так что мой вершинный шейдер выглядит примерно так:

vec3 calculateNormal (float y0, float y1, float y2) 
{ 
    vec3 p1 = gl_Vertex.xyz; 
    vec3 p2 = gl_Vertex.xyz; 
    vec3 p3 = gl_Vertex.xyz; 
    p2.x += vertexDelta.x; 
    p3.z += vertexDelta.y; 

    p1.y = y0; 
    p2.y = y1; 
    p3.y = y2; 

    return normalize(gl_NormalMatrix * cross(p3 - p1, p2 - p1)); 
} 

void main() 
{ 
    vec4 heightSample = texture2DRect(heightMap, gl_MultiTexCoord3.xy); 
    vec4 heightSampleX = texture2DRect(heightMap, gl_MultiTexCoord4.xy); 
    vec4 heightSampleY = texture2DRect(heightMap, gl_MultiTexCoord5.xy); 
    ... 
    normal = calculateNormal (heightSample, heightSampleX, heightSampleY); 
} 

Это предполагает, что вершины равномерно распределены в направлениях х и у по vertexDelta.xy. Также предполагается, что вы настроили текстурные координаты текстурных блоков 3, 4 и 5. Блок текстуры 3 содержит фактические координаты текстуры карты высоты. Блок текстуры 4 - это то же самое, но перемещается на расстояние между вершинами в направлении х. Блок 5 текстуры такой же, как текстурный блок 3, но с координатами, сдвинутыми на расстояние y между вершинами. (Вы можете рассчитать расстояние в вершинном шейдере, но оно становится зависимым, который медленнее.)

Смежные вопросы