我想将 GLSL 着色器编译为 SPIR-V 二进制文件,并在我的 OpenGL 项目中使用它。
我发现glslang,使用我可以将 glsl 着色器编译为 spir-v。但我还没有找到任何关于如何在我的 C++ 项目中使用它的教程。如何加载这些二进制文件并从中创建着色器程序?
我需要在SPIR-V中编译OpenCL内核以与Vulkan一起使用,我尝试使用Google CLSPV https://github.com/google/clspv,但问题出现在矢量化,像vload8这样的功能不起作用.所以我需要使用clang在SPIR-V中编译OpenCL内核.
所以我需要获取一些 GLSL 的 SPIR-V 代码
我能找到的关于该主题的每个资源都涉及为图形等设置整个环境。
在最简单的情况下,当我有一些 GLSL 代码并且我想获取 SPIR-V 代码时,最好的方法是什么?
我正在使用 glslangValidator 编译此着色器,并使用带有扩展名 GL_ARB_gl_spirv 的 OpenGL 4.3 Core Profile,并使用 GLAD Webservice 生成函数指针以访问 Core OpenGL API,并使用 SDL2 创建上下文(如果有任何用处)。
如果我有一个像这样的片段着色器:
#version 430 core
//output Fragment Color
layout (location = 0) out vec4 outFragColor;
//Texture coordinates passed from the vertex shader
layout (location = 0) in vec2 inTexCoord;
uniform sampler2D inTexture;
void main()
{
outFragColor = texture(inTexture, inTexCoord);
}
Run Code Online (Sandbox Code Playgroud)
我如何才能设置inTexture使用哪个纹理单元?
根据我在网上阅读的文档,我无法使用glGetUniformLocation来获取要在 中使用的制服的位置glUniform1i,因为我使用的是 SPIR-V,而不是直接使用 GLSL。
我需要做什么才能将其设置为类似的方式glUniform1i?location我需要在布局修饰符中设置吗?这binding?我尝试过使用统一缓冲区对象,但显然sampler2D只能是统一的。
我试图找出所有着色器语言之间的差异。我正在使用 Vulkan 用 C++ 开发一款游戏,这意味着(如果我没读错的话)我向 Vulkan 提供的每个着色器都必须采用 spir-v 扩展。
但我有时看到这个库的用途:https://github.com/KhronosGroup/SPIRV-Cross 它可以将 spir-v 翻译为其他语言(GLSL、HLSL 或 MSL),当我尝试时它是否有用做一个游戏?不适用于不同平台上的着色器。
或者也许我需要这些不同的格式来使用它们或不同的平台?(这似乎不正确,因为 vulkan 寻找 spir-v)。尽管如此,我看到有一个工具MoltenVK可以在Mac上使用着色器。这意味着 mac 不能正确支持 vulkan?那么这些语言的优点和缺点是什么?(我的意思是在创建游戏时,用户不应该修改着色器)
我希望我的问题不会太模糊。
对于逆向工程师来说,将图形调试器附加到 OpenGL 应用程序以提取着色器源代码是很简单的。我的理解是,另一方面,Vulkan 使用 SPIR-V 字节码,而不是将纯文本着色器传递给图形 API。
SPIR-V 字节码是否混淆了着色器源,或者反编译是否相当容易?
我正在用 C++ 编写一个体素引擎,并且正在实现一个 Vulkan 渲染器。我决定在 HLSL 中编写着色器,并通过 SPIRV-Cross 转换它们。然而,这给我带来了一个问题 - glslang 的 HLSL 编译器不允许采样器。例如,这个像素着色器:
uniform sampler2D tex;
float4 main(float2 uv : TEXCOORD0) : COLOR0 {
return tex2D(tex, uv);
}
Run Code Online (Sandbox Code Playgroud)
给出这个编译器输出:
Expected Sampled Image to be of type OpTypeSampledImage
%19 = OpImageSampleImplicitLod %v4float %17 %18
Run Code Online (Sandbox Code Playgroud)
我不知道是否应该用 GLSL 编写着色器,或者使用不同的库。任何帮助,将不胜感激。
像在opengl中一样,我们可以执行glGetActiveAttrib和glGetActiveUniform。
我正在尝试了解 SPIR-V 规范,例如了解 for 循环。在 1.6 修订版 2 规范的开头,有以下示例(为了一致性,仅取部分内容)
for (int i = 0; i < 4; ++i)
color *= multiplier;
Run Code Online (Sandbox Code Playgroud)
变成:
%49 = OpLabel
OpLoopMerge %51 %52 None ; structured loop
OpBranch %53
%53 = OpLabel
%54 = OpLoad %16 %48
%56 = OpSLessThan %25 %54 %55 ; i < 4 ?
OpBranchConditional %56 %50 %51 ; body or break
%50 = OpLabel ; body
%58 = OpLoad %7 %57
%59 = OpLoad %7 %31
%60 = OpFMul %7 …Run Code Online (Sandbox Code Playgroud) 2018-03-07,新版API(Vulkan 1.1)发布。
我想知道:
$ /usr/bin/vulkaninfo | head -n 5
===========
VULKAN INFO
===========
Vulkan Instance Version: 1.1.70
WARNING: radv is not a conformant vulkan implementation, testing use only.
Run Code Online (Sandbox Code Playgroud)
spir-v ×11
vulkan ×8
glsl ×5
opengl ×5
hlsl ×2
opencl ×2
clang ×1
control-flow ×1
gpgpu ×1
gpu ×1
llvm-clang ×1
obfuscation ×1
shader ×1