2012-05-09 2 views
2

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

glTranslated(-camera.x, -camera.y, -camera.z); 

прекрасно работает, но это будет означать, что вы можете идти до края сетки.

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

uniform vec3 camera_position; 
varying vec4 position; 

void main() 
{ 
    vec3 tmp; 
    tmp = gl_Vertex.xyz; 
    tmp -= camera_position; 
    gl_Vertex.y = snoise(tmp.xz/NOISE_FREQUENCY) * NOISE_SCALING; 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
    position = gl_Position; 
} 

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

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

Для справки, вот репозиторий: https://github.com/Orpheon/Synthworld

Что я делаю неправильно?

PS: «Мерцание» неверно. Кажется, что с некоторыми позициями он ничего не рисует, а другие рисуют нормальную сцену с позиции 0, поэтому, если я двигаюсь, не останавливаясь, она мерцает. Я могу остановиться в месте, где он остается черным, или в том месте, где он остается нормальным.

ответ

1

мне удалось исправить эту ошибку с помощью glUniform3fv:

main.c exterp:

// Sync the camera position variable 
GLint camera_pos_ptr; 
float f[] = {camera.x, camera.y, camera.z}; 
camera_pos_ptr = glGetUniformLocation(shader_program, "camera_position"); 
glUniform3fv(camera_pos_ptr, 1, f); 

// draw the display list 
glCallList(grid); 

Vertex Shader:

uniform vec3 camera_position; 
varying vec4 position; 

void main() 
{ 
    vec4 newpos; 
    newpos = gl_Vertex; 
    newpos.y = (snoise((newpos.xz + camera_position.xz)/NOISE_FREQUENCY) * NOISE_SCALING) - camera_position.y; 
    gl_Position = gl_ModelViewProjectionMatrix * newpos; 
    position = gl_Position; 
} 

Если кто-то хочет увидеть полный код, вот репозиторий git снова: https://github.com/Orpheon/Synthworld

+0

Я дам вам щедрость, если вы также * объясните * ошибку и исправление. – Medo42

+0

Вещь, я даже не совсем понимаю ошибку. Я изменил команду. Раньше я использовал команду, которая непосредственно передает поплавки, и сделала какую-то ошибку. Исправить, для меня, было переключиться на команду, которая просто передала указатель на массив (glUniform3fv вместо glUniform3f). Это просто сработало. Так что да, извините. – Orpheon

5
gl_Position = ftransform(); 

Это то, что вы делаете неправильно. ftransform неявно принимает gl_Vertex в качестве параметра. Он просто выполняет именно то, что он должен: выполнить преобразование вершинной позиции точно так, как если бы это был конвейер с фиксированной функцией. Поэтому он использует значение, которое gl_Vertex имеет изначально.

Вы должны сделать соответствующие преобразования на этом:

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
+0

Это не исправить проблему. – Orpheon

+1

@ Orpheon: Честно говоря, я предполагаю, что 'gl_Vertex.xyz - = camera_position;' что-то значимое. Я понятия не имею, почему вы могли бы вычесть позицию вершинной точки модели в позиции камеры, но вы могли бы как-то работать непосредственно в пространстве камеры, поэтому я не могу сказать без дополнительной информации. –

+0

Извините. Camera_position - это стандартные трехмерные пространственные координаты, а не пространство камеры, насколько я могу различить. Я все еще новичок в OpenGL, и да, я нахожусь на дрожащей почве, когда дело доходит до этих разных пространств. – Orpheon

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