【发布时间】:2019-04-02 19:33:46
【问题描述】:
我再次潜入学习着色器并试图更好地了解它们的工作方式,但我在修改着色器顶点程序中的统一数组的值时遇到了麻烦,然后在片段程序中传递和使用这些值。
我正在使用此着色器根据一堆对象“对象 B”的局部矩阵对包含着色器的“对象 A”进行一些计算。
我在顶点程序中使用这些矩阵将它们与“对象 A”的顶点的本地位置相乘,然后我想将这些结果存储在一个数组中并传递给片段程序。
如果我将要修改的数组放在一个结构体中,我可以让它工作该数组的数量为 32,即使我使用了所有 TEXCOORD1 到 TEXCOORD15,这也会限制功能。
这也为我设置了更多限制,因为我想使用多个数组来存储每个数组允许的最大项目数(我相信是 1024)。
所以我很难理解为什么如果我使用统一数组,我不能在顶点程序中修改这些数组值。
我的猜测是这种在顶点程序和片段程序之间传递数据的方式不起作用......
发布着色器的基本版本,排除所有不相关的代码以提高可读性
CGPROGRAM
uniform float4x4 _MyMatrixArray [100];
uniform float4 _WorldPositions [100];
struct vertexInput{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct vertexOutput{
float4 pos : SV_POSITION;
float2 uv: TEXCOORD0;
//float4 _WorldPositions [32] : TEXCOORD1;
};
vertexOutput vert(vertexInput input)
{
for(int i = 0; i < 100; i++)
{
//output._WorldPositions[i] = mul(_MyMatrixArray[i], worldPos);
_WorldPositions[i] = mul(_MyMatrixArray[i], worldPos);
}
}
float4 frag(vertexOutput input) : COLOR
{
for(int i = 0; i < 100; i++)
{
//if (length(input._WorldPositions[i].xyz) > 0.5)
if (length(_WorldPositions[i].xyz) > 0.5)
{
//Do stuff
}
}
}
ENDCG
使用注释行是可行的,但这极大地限制了我的着色器的功能。
如果我在结构之外声明它,为什么不能在顶点程序中修改数组的值?有没有办法做到这一点?
在以我打算的方式使用大型数组时,我应该采取其他方法吗(在顶点/片段程序中更改和使用它们的值?
我有点迷路了,非常感谢任何有关此的信息。提前致谢!
【问题讨论】:
-
您将数组声明为
uniform- 修改它意味着它在着色器执行过程中不再统一 -
@UnholySheep 我明白了,那么只要我不更改着色器本身内部的值,我就可以在顶点/片段程序上使用该统一数组?就像我正在处理另一个数组“_MyMatrixArray[i]”,它在外部 C# 脚本中预定义了所有数据?
-
是的,您可以在着色器中的任何位置读取
uniform变量。可变的全局变量通常是一个坏主意,因此将您需要的值作为参数传递总是一个更好的主意 -
@UnholySheep 非常感谢!我了解现在在着色器中如何处理制服。我想我将不得不以外部方式进行矩阵乘法,然后将它们提供给统一着色器数组:)
标签: arrays matrix multiplication hlsl uniform