我学会了如何使用 https://registry.khronos.org/OpenGL/extensions/ARB/ARB_shading_language_include.txt 扩展感谢 opengl - 如何在 glsl 中使用#include 支持 ARB_shading_language_include - 堆栈溢出。我准备了以下命名字符串和着色器:
// NamedString /lib/VertexData.glsl
struct VertexData {
vec3 objectPosition;
vec3 worldPosition;
};
VertexData fillVertexData() {
VertexData v;
v.objectPosition = objectPosition;
v.worldPosition = vec3(worldFromObject * vec4(objectPosition, 1));
return v
}
// MyShader.vert
#version 430
#extension GL_ARB_shading_language_include : require
layout(location = 0) in vec3 objectPosition;
uniform mat4 worldFromObject; // Model
uniform mat4 viewFromWorld; // View
uniform mat4 projectionFromView; // Projection
#include "/lib/VertexData.glsl"
out VertexData v;
void main() {
v = fillVertexData();
gl_Position = projectionFromView * viewFromWorld * vec4(v.worldPosition, 1);
}
通过 glCompileShaderIncludeARB(vertex, 0, NULL, NULL);
编译着色器时,出现以下错误: Error. Message: 0:18(21): error: 'objectPosition' undeclared.
The objectPosition
vertex attribute declared in MyShader.vert
is not recognized.
fillVertexData()
函数移动到 MyShader.vert
着色器,它工作正常。B选项
// NamedString /lib/VertexData.glsl
struct VertexData {
vec3 objectPosition;
vec3 worldPosition;
};
// MyShader.vert
#version 430
#extension GL_ARB_shading_language_include : require
layout(location = 0) in vec3 objectPosition;
uniform mat4 worldFromObject; // Model
uniform mat4 viewFromWorld; // View
uniform mat4 projectionFromView; // Projection
#include "/lib/VertexData.glsl"
out VertexData v;
VertexData fillVertexData() {
VertexData v;
v.objectPosition = objectPosition;
v.worldPosition = vec3(worldFromObject * vec4(objectPosition, 1));
return v
}
void main() {
v = fillVertexData();
gl_Position = projectionFromView * viewFromWorld * vec4(v.worldPosition, 1);
}
这让我觉得扩展会检查每个命名字符串的变量范围。但这不是我期望 #include
预处理器宏系统的行为。它不应该关心变量范围,而只是预处理 MyShader.vert
并编译那个。我通过
GL_GOOGLE_include_directive
尝试了选项 A,并且 glslangValidator -l MyShader.vert
不会为这两个选项抛出任何错误,并且通过 -E
生成的 GLSL 代码看起来是正确的。这是我的期望。我阅读了扩展规范,它没有提到命名字符串中使用的变量应该在扩展处理命名字符串时声明。难道我做错了什么?或者这是 ARB_shading_language_extension 的设计?关于如何将
fillVertexData()
保留在命名字符串中有什么建议吗?顺便说一下,在为我自己的应用程序编写我自己的
#include
实现之前,我想用尽现有的解决方案。我首先尝试了glslang
图书馆。但是我从中得到的预处理器输出不是可编译的 GLSL:我的 OpenGL 版本不支持 GL_GOOGLE_include_directive
并且它用 #line
指令填充代码,其中第二个参数不是整数而是字符串(文件名),这不是有效的 GLSL.使用
ARB_shading_language_extension
是我第二次尝试通过 #include
s 获得可重用的 GLSL 代码。