GLSL - проблема кастинга и странная ошибка - PullRequest
1 голос
/ 02 августа 2010

Я здесь, чтобы получить справку о странном поведении моего GLSL-кода, когда я приводил float к int, и я никогда не видел такой ошибки с тех пор, как начал GLSL

На самом деле я пытаюсь добиться скинов сетки на процессоре с помощью GLSL

Я использую ATI Radeon HD 4850 (Gainward) и работаю с OpenGL 2.1 на Windows XP

так что на стороне процессора я собираю индексы и веса костей и бросаю их в шейдер с атрибутами вершин затем я умножаю матрицы костей на веса и использую результат для вычисления нормалей и gl_Position

очень обычно до там

Проблемы возникают, когда мне нужно получить индексы Bones from Bones

Я работаю с простой цилиндрической сеткой с 4 костями; Я посылаю кости из процессора через единую переменную, и кажется, что проблема не в этих матрицах костей, я жестко закодировал их в шейдере, и ошибка остается Кстати, форма правильна, когда я сравниваю с рендерингом Maya

Более того, индексы костей для каждой вершины все те же: 0, 1, 2, 3; они отправляются с типом GL_UNSIGNED_INT через VBO; но в шейдере uvec4, похоже, не работает (ни ivec4), поэтому я должен использовать float vec4 и приводить с int ()

так вот мой код вершинного шейдера:

uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat3 NormalMatrix;

uniform mat4 bones[4];

varying vec3 normal;

attribute vec3 v_pos;
attribute vec3 v_normal;

//the 4 first bones indices of the vertex;
attribute vec4 v_boneIndices0;
//the 4 first bones weights of the vertex
attribute vec4 v_boneWeights0;

void main()
{   

/* To compare with bones sent via uniform, i hardcoded the bones matrices in this array; doesn't seem to make a difference

        mat4 mattab[4];

        mattab[0] = mat4(1.0f, 0.0f, 0.0f, 0.0f,
                         0.0f, 1.0f, 0.0f, 0.0f,
                         0.0f, 0.0f, 1.0f, 0.0f,
                         0.0f, 0.0f, 0.0f, 1.0f);

        mattab[1] = mat4(1.0f, 0.0f, 0.0f, 0.0f,
                         0.0f, 0.816489f, 0.57736f, 0.0f,
                         0.0f, -0.57736f, 0.816489f, 0.0f,
                         0.0f, -0.341108f, 1.07319f, 1.0f);

        mattab[2] = mat4(0.999949f, -0.00863831f, 0.00528692f, 0.0f,
                         -0.00400147f, 0.142574f, 0.989776f, 0.0f, 
                         -0.00930377f, -0.989746f, 0.142532f, 0.0f, 
                         0.00201152f, -0.00111439f, 0.865123f, 1.0f); 

        mattab[3] = mat4(0.799844f, -0.0233416f, -0.599754f, 0.0f,
                         0.448905f, 0.686556f, 0.571949f, 0.0f,
                         0.398414f, -0.726702f, 0.559616f, 0.0f, 
                         -1.23581f, -1.4976f, 2.0412f, 1.0f );

*/

        //the average matrix of weighted bones
        mat4 mat = mat4(0.0f);

        for ( int i = 0; i < 4; i++){

               //normally, the both lines below are equivalent 
               //because v_boneIndices0 is always 0,1,3,4

               mat += v_boneWeights0[i] * bones[int(v_boneIndices0[i])];
               //mat += v_boneWeights0[i] * bones[i];  

                }

        //Here, I multiply the average matrix with v_normal and v_pos

        normal = NormalMatrix * (mat3(mat[0].xyz,mat[1].xyz,mat[2].xyz) * v_normal);

        gl_Position = ProjectionMatrix*ModelViewMatrix*(mat*vec4(v_pos, 1.0f));

}

ошибка появляется, когда я смотрю на скорость FPS; без скинов я получаю 2000 FPS

когда я использую линию

mat += v_boneWeights0[i] * bones[i];

Я получаю правильную форму с некоторыми артефактами, FPS остается на 2000

но когда я использую линию

mat += v_boneWeights0[i] * bones[int(v_boneIndices0[i])];

(что аналогично другой линии) форма идеальна, но FPS падает до 1500 FPS ...

Я думал, что это была сама линия, которая замедляла цикл; однако, если я оставлю эту строку и уберу мат из обычных вычислений и вычислений gl_Position, скорость FPS возрастет до 2000

другое странное поведение, если я вычислю

vec4 test = ProjectionMatrix*ModelViewMatrix*(mat*vec4(v_pos, 1.0f));

сразу после цикла и вычисления Normal gl_Position без умножения мата

normal = NormalMatrix * v_normal;
gl_Position = ProjectionMatrix*ModelViewMatrix* vec4(v_pos, 1.0f);

скорость FPS также возрастает до 2000

Это похоже на ошибку, только если я объединяю

mat += v_boneWeights0[i] * bones[int(v_boneIndices0[i])];

and

normal = NormalMatrix * (mat3(mat[0].xyz,mat[1].xyz,mat[2].xyz) * v_normal);
gl_Position = ProjectionMatrix*ModelViewMatrix*(mat*vec4(v_pos, 1.0f));

Я думаю, что это аппаратная ошибка, или, возможно, я делаю это неправильно, я не знаю Но я уверен, что проблема связана с приведением типа int () И, кстати, почему uvec4 и ivec4 не работают?

кто-нибудь сталкивался с таким поведением с Nvidia? Я ничего не нашел в Google

Надеюсь, вы сможете мне помочь

Спасибо:)

Ответы [ 2 ]

3 голосов
/ 02 августа 2010

Ваша ошибка в том, что вы смотрите на кадров в секунду для производительности вместо времени на кадр (timedelta) . Разница между 2000 кадров в секунду и 1500 кадров в секунду очень мала. 2000 кадров в секунду означает 0,5 мс на кадр. 1500 кадров в секунду означает 0,6 мс на кадр. Корреляция между частотой кадров в секунду и временем на кадр составляет , а не линейный. Эффективный кадр / с равен 1 / таймделта. Чем больше у вас fps, тем более чувствительным становится fps, потому что временное окно очень мало. Скажем, если у вас было 10000 кадров в секунду, и оно колебалось от 10000 кадров в секунду до 5000 кадров в секунду. Это даст вам временное окно от 0,1 мс до 0,2 мс. В этот момент любая операция может повлиять на timedelta.

0 голосов
/ 03 августа 2010

ivec4 и uvec4 не являются частью GLSL в OpenGL 2.1, это расширение (GL_EXT_gpu_shader4), поэтому вам нужно включить это расширение, используя:

#extension GL_EXT_gpu_shader4 : enable

В начале вашего шейдера, а затемвы сможете использовать реальные целые числа в шейдерах.Обратите внимание, что это расширение поддерживается только в DX 10 и более новых картах (что делает ваша карта).

Расширение является частью Core OpenGL 3.0.

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