存储在命名字符串中的 GLSL 代码片段是否必须是通过 ARB_shading_language_include 扩展#include 的可编译代码?

问题描述 投票:0回答:0

我学会了如何使用 https://registry.khronos.org/OpenGL/extensions/ARB/ARB_shading_language_include.txt 扩展感谢 opengl - 如何在 glsl 中使用#include 支持 ARB_shading_language_include - 堆栈溢出。我准备了以下命名字符串和着色器:

选项A

// 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 是我第二次尝试通过 #includes 获得可重用的 GLSL 代码。

opengl include glsl shader preprocessor
© www.soinside.com 2019 - 2024. All rights reserved.