Shader Graph – 每次更改都重新编译着色器是一个好主意吗?

huangapple go评论74阅读模式
英文:

Shader Graph - Is recompilation of a shader for each change a good idea?

问题

我正在为我的工程论文编写着色器图表。我有点困惑,不知道是否应该在某些引脚值更改时重新编译着色器以获得实时预览结果,或者可能有更好的处理方式。

让我们考虑一下这个截图:
Shader Graph – 每次更改都重新编译着色器是一个好主意吗?

为了简单起见,片段材质只有两个字段 - 基础颜色和透明度。

这个图表生成的代码如下:

void FragmentShader(out FragmentMaterial material)
{
    vec3 _Vector3_4302458404873090201 = vec3(0.2, 0.0, 0.0);
    material.baseColor.rgb = _Vector3_4302458404873090201;
    material.baseColor.a = 1.0;
}

这只是一个简单的函数,添加到着色器代码的末尾,并在片段着色器的main函数中调用。

用户可以操作X、Y和Z值。每当值更改时,着色器都会重新编译并缓存。最大缓存大小为50个着色器。

可以使用的值的数量非常大。假设用户会将X从0滑动到1(不要太快),每次增加0.01。该值总是不同的,因此需要重新编译100个着色器。每帧只能重新编译一个着色器。

虽然我认为这没有问题,因为着色器编译速度很快,但我觉得这可能不是最佳选择。

或者也许我只是在瞎担心,直到它不会给我带来性能问题,我应该坚持下去,因为它只是一个编辑器。我相信最慢的部分将是预处理和编译为spirv(可能会有点慢,我曾经使用过shaderc库),但只有在选择了最终值之后才会完成(如果它们不在统一缓冲区中,但这不需要重新编译着色器)。

编辑器使用OpenGL,因此不需要将着色器转换为spirv格式才能工作。

我不知道。您有任何想法,或者是否发现了这种方法的一些问题,或者可以建议我应该做些什么吗?

英文:

I am writing a Shader Graph for my engineering thesis. I'm kinda stuck on whether I should recompile the shader each time some pin value changes to get a real-time preview result or maybe there's a better way to handle this.

Let's consider this screenshot:
Shader Graph – 每次更改都重新编译着色器是一个好主意吗?

For simplicity a fragment material has only 2 fields - base color and alpha.

the generated code of this graph looks like this:

void FragmentShader(out FragmentMaterial material)
{
    vec3 _Vector3_4302458404873090201 = vec3(0.2, 0.0, 0.0);
    material.baseColor.rgb = _Vector3_4302458404873090201;
    material.baseColor.a = 1.0;
}

it's just a simple function that is added to the end of a shader code and gets invoked in a main function of a fragment shader.

User can manipulate X, Y and Z values. Each time the value changes the shader is recompiled and cached. Maximum cache size is 50 shaders.

The number of values ​​that can be used is very large. Let's say the user will be sliding the X from 0 to 1 (not too fast) increasing by 0.01. The value is always different, so that's 100 shader recompiles. Only one shader can be recompiled during a frame.

Although I don't see a problem with that, because the shader compilation is fast, I feel like this is not the best option.

Or maybe I'm just tripping and until it won't cause me a performance problem I should stick with it since it's just an editor. I believe the slowest part would be preprocessing and compiling to spirv (which may be kinda slow, I used to use shaderc library), but it will be done when the final values were picked (if they're not in a uniform buffer, but it does not require a shader recompilation).

The editor uses OpenGL so it does not require a shader to be in a spirv format to work.

I don't know. Do you have any ideas, or maybe do you see some problems with this approach, or could suggest what I should do?

答案1

得分: 0

正如Quimby建议的那样,在预览中,只有当连接发生变化时,着色器才会重新编译。

如果一个输入引脚没有连接,那么它将被视为一个统一变量。

如果它被连接了,那么可能有一个不同的源(节点),其中可能有可调整的输入。

除非它是一个属性节点,它始终被视为一个统一变量,而我的现有工作流程已经支持它,所以我不需要改变这些节点生成的代码方式。

英文:

As Quimby suggested, for previews the shader is recompiled only when connections change.

If an input pin is not connected then it's treated as a uniform variable.

If it's connected, then there has to be a different source (node) that probably has tweakable inputs.

Unless it's a property node that is always treated as a uniform variable and my existing workflow already supports it, so I didn't have to change the way the code is generated by these nodes.

huangapple
  • 本文由 发表于 2023年7月13日 21:54:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76680183.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定