Совместимость версий в GLSL - PullRequest
1 голос
/ 31 января 2020

Я работаю над проектом в GLSL (из которого у меня нет опыта). В настоящее время я сам ничего не кодирую, просто пытаюсь запустить чужой код. К сожалению, они написали свой код, используя версию 120, и я пытаюсь запустить его с версией 330. Примечание: я запускаю это на Ma c с версией 10.15. Вот код:

# version 330 core
in vec3 mynormal; 
in vec4 myvertex; 

uniform mat4 modelview;

out vec4 fragColor;

uniform vec3 color;

const int numLights = 10; 
uniform bool enablelighting; // are we lighting at all (global).
uniform vec4 lightposn[numLights]; // positions of lights 
uniform vec4 lightcolor[numLights]; // colors of lights
uniform int numused;               // number of lights used  

uniform vec4 ambient; 
uniform vec4 diffuse; 
uniform vec4 specular; 
uniform vec4 emission; 
uniform float shininess; 

vec4 ComputeLight (const in vec3 direction, const in vec4 lightcolor, const in vec3 normal, const in vec3 halfvec, const in vec4 mydiffuse, const in vec4 myspecular, const in float myshininess) {

    float nDotL = max(dot(normal, direction), 0.0);
    vec4 diffuse = mydiffuse * lightcolor * nDotL;

    float nDotH = max(dot(normal, halfvec), 0.0);
    vec4 specular = myspecular * lightcolor * pow(nDotH, myshininess);

    return diffuse + specular;
}

void main (void)
{
    if (enablelighting) {
        const vec3 eyepos = vec3(0,0,0) ;
        vec4 _mypos = gl_ModelViewMatrix * myvertex ;
        vec3 mypos = _mypos.xyz / _mypos.w;
        vec3 eyedir = normalize(eyepos - mypos);

        vec3 _normal = (gl_ModelViewMatrixInverseTranspose*vec4(mynormal,0.0)).xyz ;
        vec3 normal = normalize(_normal);

        gl_FragColor = ambient;
        for (int i = 0; i < numused; ++i) {
            vec3 light_direction;
            if (lightposn[i].w == 0) {
                light_direction = lightposn[i].xyz;
            } else {
                vec3 light_position = lightposn[i].xyz / lightposn[i].w ;
                light_direction = normalize(light_position - mypos); // no attenuation
            }
            vec3 half = normalize (light_direction + eyedir);
            vec4 col = ComputeLight(light_direction, lightcolor[i], normal, half, diffuse, specular, shininess);
            gl_FragColor += col;
        }
    }
    else gl_FragColor = color ;
}

И вот ошибки, которые я получаю:

Compile Error, Log Below
ERROR: 0:60: Use of undeclared identifier 'gl_ModelViewMatrix'
ERROR: 0:61: Use of undeclared identifier '_mypos'
ERROR: 0:61: Use of undeclared identifier '_mypos'
ERROR: 0:63: Use of undeclared identifier 'mypos'
ERROR: 0:64: Use of undeclared identifier 'gl_NormalMatrix'
ERROR: 0:79: Use of undeclared identifier 'mypos'
ERROR: 0:90: Use of undeclared identifier 'mypos'
ERROR: 0:101: Use of undeclared identifier 'mypos'
ERROR: 0:112: Use of undeclared identifier 'mypos'
ERROR: 0:123: Use of undeclared identifier 'mypos'
ERROR: 0:134: Use of undeclared identifier 'mypos'
ERROR: 0:145: Use of undeclared identifier 'mypos'
ERROR: 0:156: Use of undeclared identifier 'mypos'
ERROR: 0:167: Use of undeclared identifier 'mypos'
ERROR: 0:178: Use of undeclared identifier 'mypos'
ERROR: 0:193: Use of undeclared identifier 'eyedirn'
ERROR: 0:196: Use of undeclared identifier 'normal'
ERROR: 0:196: Use of undeclared identifier 'halfy'
ERROR: 0:197: Use of undeclared identifier 'colApp'
ERROR: 0:206: Use of undeclared identifier 'gl_FragColor'
ERROR: 0:208: Use of undeclared identifier 'gl_FragColor'

После некоторого поиска в Google, я понимаю, что это проблема совместимости между версии. Тем не менее, я не знаю достаточно о GLSL, чтобы знать, как это исправить. Я надеюсь изменить этот файл для запуска вместо того, чтобы пытаться написать его для совместимости с версией 330. Может кто-нибудь дать мне совет, как изменить этот код для запуска для меня?

Ответы [ 2 ]

1 голос
/ 31 января 2020

Вы не «запускаете GLSL» в вакууме, без какого-либо контекста, кроме запуска шейдера. Шейдер не работает вне контекста среды, для которой он был разработан.

Используемый шейдер был написан, например, для матриц с фиксированными функциями. Эти матрицы не существуют в GLSL 3.30. Но программа, написанная для OpenGL 3.3, также не обеспечивает эти матрицы. Он выполняет рендеринг с использованием собственных пользовательских данных.

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

Итак, все, что вам нужно сейчас, это понять, что делает материал 1,20. Затем вы можете заменить ссылки на них данными вашей текущей шейдерной среды (или дополнить их указанными данными, если они еще не предоставлены). Следовательно:

  • gl_ModelViewMatrix: это матрица преобразования модели в камеру.
  • gl_ModelViewMatrixInverseTranspose: это обратное / транспонированное из приведенного выше.
  • gl_FragColor: это выходной цвет, который будет записан этим фрагментом. Вместо этого вы должны объявить переменную layout(location = 0) out vec4 someName; и записать в нее.
  • gl_NormalMatrix: это матрица 3x3, предназначенная для преобразования нормалей. Способ вычисления OpenGL - вычисление обратной / транспонированной матрицы представления модели.

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

1 голос
/ 31 января 2020

До OpenGL 2.1. геометрия была нарисована с помощью glBegin / glEnd последовательностей или фиксированных атрибутов функций. Координаты вершин были преобразованы в текущем виде модели и матрице проекции, и программа шейдера не требовалась.
Для использования с программами шейдеров встроенная униформа gl_ModelViewMatrix, gl_NormalMatrix, gl_ModelViewMatrixInverseTranspose и c, предоставьте доступ к Legacy OpenGL матрицам. Эта униформа предоставляется до OpenGL Shading Language 1.20 и затем была удалена.
В профиле совместимости Контекст OpenGL такие приложения все еще могут работать с самой последней версией OpenGL, но вершинный шейдер не может быть обновлен до более высокой версии.

В «современном» OpenGL вы должны управлять преобразованиями матрицы самостоятельно. Матрицы предоставляются программе шейдеров Унифицированные переменные (например, типа mat4).

Это показывает, что ваш шейдер смешивает обе технологии. Я так думаю, из-за спецификации

uniform mat4 modelview;

Более того, вывод шейдера фрагмента gl_FragColor устарел. Для вывода фрагмента шейдера выходная переменная должна быть объявлена. Ваш шейдер также имеет такую ​​выходную переменную:

out vec4 fragColor;

Чтобы компилировать ваш шейдер, вы должны

  • заменить gl_ModelViewMatrix на modelview
  • gl_ModelViewMatrixInverseTranspose по inverse(transpose(modelview))
  • и gl_FragColor по fragColor

gl_NormalMatrix - матрица 3x3 (mat3) и верхний левый 3x3 gl_ModelViewMatrixInverseTranspose.
gl_NormalMatrix может быть заменен на mat3(inverse(transpose(modelview)))

...