Hei*_*bug 6 opengl directx shader glsl hlsl
我试图了解如何在着色器语言中实现传递参数.
我已经阅读了几篇文章和文档,但我仍然有些疑惑.特别是我试图理解C++函数调用的差异,特别强调性能.
HSLS,Cg和之间略有差异,GLSL但我想下划线的实现非常相似.
到目前为止我所理解的:
C++.不支持递归,因此不使用堆栈,并且大多数函数都是内联的,并且参数直接放入寄存器中.HLSL)内联,或者至少内联关键字始终受编译器(Cg)的尊重上面的考虑是对的吗?
现在2具体问题:
1)传递矩阵作为函数参数
inline float4 DoSomething(in Mat4x4 mat, in float3 vec)
{
...
}
Run Code Online (Sandbox Code Playgroud)
考虑到上面的功能,C++这将是令人讨厌的,并且肯定会更好地使用引用:const Mat4x4&.
着色器怎么样?这是一个糟糕的方法吗?我读过,例如,inout限定符可用于通过引用传递矩阵,但实际上它暗示了被调用函数修改的矩阵.
2)数量(和参数类型)是否有任何含义?例如,更好地使用具有有限参数集的函数?或者避免传递矩阵?是inout修改在这里提高性能的有效方法是什么?如果是这样,任何人都知道典型的编译器如何实现它?
3)是否有任何区别HLSL的GLSL说明吗?有人有这方面的提示吗?
根据规范,始终复制值。对于in参数,在调用时复制out参数,在返回时复制inout参数,在调用和返回时复制参数。
用规范的语言(GLSL 4.50,第6.1.1节“函数调用约定”):
所有参数在调用时均按从左到右的顺序进行一次评估。输入参数的求值结果将被复制到形式参数中。评估out参数会产生一个l值,该l值用于在函数返回时复制出一个值。评估inout参数会同时产生一个值和一个l值;该值在调用时被复制到形式参数中,而左值用于在函数返回时复制出一个值。
一个实现当然可以自由地优化它想要的任何东西,只要结果与记录的行为相同即可。但是我不认为您可以期望它以任何指定的方式工作。
例如,inout通过引用传递所有参数将不会被保存。假设您有以下代码:
vec4 Foo(inout mat4 mat1, inout mat4 mat2) {
mat1 = mat4(0.0);
mat2 = mat4(1.0);
return mat1 * vec4(1.0);
}
mat4 myMat;
vec4 res = Foo(myMat, myMat);
Run Code Online (Sandbox Code Playgroud)
正确的结果是包含所有0.0成分的向量。如果参数是按引用传递,mat1而且mat2里面Foo()会别名相同的矩阵。这意味着to的赋值mat2也会更改的值mat1,并且结果是一个包含所有1.0分量的向量。哪有错
这当然是一个非常人为的示例,但是优化必须是选择性的,以便在所有情况下都能正常工作。