GLSL 中的版本兼容性
Version Compatibility in GLSL
我正在用 GLSL 做一个项目(我没有这方面的经验)。我目前没有自己编写任何代码,只是想 运行 别人的代码。不幸的是,他们使用 120 版编写代码,而我正在尝试 运行 使用 330 版。注意:我 运行 在 Mac 上使用 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。
谁能给我建议如何将此代码修改为 运行?
最高 OpenGL 2.1。几何是由 glBegin
/glEnd
序列或固定函数属性绘制的。顶点坐标已由当前模型视图和投影矩阵转换,无需着色器程序。
为了与着色器程序一起使用,内置制服 gl_ModelViewMatrix
、gl_NormalMatrix
、gl_ModelViewMatrixInverseTranspose
等,提供对 Legacy OpenGL matrices. This uniforms are provided up to OpenGL Shading Language 1.20 的访问权限,然后被删除。
在兼容性配置文件 OpenGL Context 中,此类应用程序仍然可以 运行 使用最新的 OpenGL 版本,但顶点着色器无法升级到更高版本。
在 "modern" OpenGL 中,您必须自己管理矩阵变换。矩阵由 Uniform variables(例如类型 mat4
)提供给着色器程序。
您的着色器似乎混合了这两种技术。我想是的,因为
的规范
uniform mat4 modelview;
此外,片段着色器输出 gl_FragColor
已弃用。对于片段着色器输出,必须声明一个输出变量。您的着色器也有这样的输出变量:
out vec4 fragColor;
要编译着色器,您必须
- 用
modelview
代替gl_ModelViewMatrix
gl_ModelViewMatrixInverseTranspose
来自 inverse(transpose(modelview))
- 和
gl_FragColor
通过 fragColor
gl_NormalMatrix
是一个 3x3 矩阵 (mat3
) 并且是 gl_ModelViewMatrixInverseTranspose
.
的左上角 3x3
gl_NormalMatrix
可以替换为 mat3(inverse(transpose(modelview)))
您不会 "run GLSL" 在真空中,缺少 运行 着色器之外的任何上下文。着色器不能在其设计环境的上下文之外工作。
您使用的着色器是针对固定函数矩阵等编写的。这些矩阵在 GLSL 3.30 中不存在。但是针对 OpenGL 3.3 编写的程序也不 提供 这些矩阵。它正在使用自己的用户定义数据进行渲染。
如果您要将着色器移植到不同的环境,那么您要么可以控制该环境,要么已被告知该环境如何工作。无论哪种方式,您都知道该环境期望在何处拥有其着色器数据。如果您不知道,那么这将行不通。
所以你现在需要的只是了解 1.20 的东西在做什么。然后,您可以用当前着色器环境的数据替换对它们的引用(或者如果尚未提供,则用所述数据对其进行扩充)。因此:
gl_ModelViewMatrix
:这是模型到相机的变换矩阵。
gl_ModelViewMatrixInverseTranspose
:这就是上面的inverse/transpose。
gl_FragColor
:这是这个片段要写入的输出颜色。您应该改为声明一个 layout(location = 0) out vec4 someName;
变量并写入该变量。
gl_NormalMatrix
:这是一个 3x3 矩阵,旨在用于变换法线。 OpenGL 的计算方式是计算模型-视图矩阵的 inverse/transpose。
因此,只需在这些位置替换您的数据,您应该没问题。
我正在用 GLSL 做一个项目(我没有这方面的经验)。我目前没有自己编写任何代码,只是想 运行 别人的代码。不幸的是,他们使用 120 版编写代码,而我正在尝试 运行 使用 330 版。注意:我 运行 在 Mac 上使用 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。 谁能给我建议如何将此代码修改为 运行?
最高 OpenGL 2.1。几何是由 glBegin
/glEnd
序列或固定函数属性绘制的。顶点坐标已由当前模型视图和投影矩阵转换,无需着色器程序。
为了与着色器程序一起使用,内置制服 gl_ModelViewMatrix
、gl_NormalMatrix
、gl_ModelViewMatrixInverseTranspose
等,提供对 Legacy OpenGL matrices. This uniforms are provided up to OpenGL Shading Language 1.20 的访问权限,然后被删除。
在兼容性配置文件 OpenGL Context 中,此类应用程序仍然可以 运行 使用最新的 OpenGL 版本,但顶点着色器无法升级到更高版本。
在 "modern" OpenGL 中,您必须自己管理矩阵变换。矩阵由 Uniform variables(例如类型 mat4
)提供给着色器程序。
您的着色器似乎混合了这两种技术。我想是的,因为
的规范uniform mat4 modelview;
此外,片段着色器输出 gl_FragColor
已弃用。对于片段着色器输出,必须声明一个输出变量。您的着色器也有这样的输出变量:
out vec4 fragColor;
要编译着色器,您必须
- 用
modelview
代替 gl_ModelViewMatrixInverseTranspose
来自inverse(transpose(modelview))
- 和
gl_FragColor
通过fragColor
gl_ModelViewMatrix
gl_NormalMatrix
是一个 3x3 矩阵 (mat3
) 并且是 gl_ModelViewMatrixInverseTranspose
.
的左上角 3x3
gl_NormalMatrix
可以替换为 mat3(inverse(transpose(modelview)))
您不会 "run GLSL" 在真空中,缺少 运行 着色器之外的任何上下文。着色器不能在其设计环境的上下文之外工作。
您使用的着色器是针对固定函数矩阵等编写的。这些矩阵在 GLSL 3.30 中不存在。但是针对 OpenGL 3.3 编写的程序也不 提供 这些矩阵。它正在使用自己的用户定义数据进行渲染。
如果您要将着色器移植到不同的环境,那么您要么可以控制该环境,要么已被告知该环境如何工作。无论哪种方式,您都知道该环境期望在何处拥有其着色器数据。如果您不知道,那么这将行不通。
所以你现在需要的只是了解 1.20 的东西在做什么。然后,您可以用当前着色器环境的数据替换对它们的引用(或者如果尚未提供,则用所述数据对其进行扩充)。因此:
gl_ModelViewMatrix
:这是模型到相机的变换矩阵。gl_ModelViewMatrixInverseTranspose
:这就是上面的inverse/transpose。gl_FragColor
:这是这个片段要写入的输出颜色。您应该改为声明一个layout(location = 0) out vec4 someName;
变量并写入该变量。gl_NormalMatrix
:这是一个 3x3 矩阵,旨在用于变换法线。 OpenGL 的计算方式是计算模型-视图矩阵的 inverse/transpose。
因此,只需在这些位置替换您的数据,您应该没问题。