仅针对 float3 更正着色器上的 "Semantic" 标记?
Correct "Semantic" tag on a shader for just a float3?
这是一个非常简单的着色器,
float4 vert (float4 vertex :POSITION, out PositionHolder o) :SV_POSITION
{
UNITY_INITIALIZE_OUTPUT(PositionHolder,o);
o.localPos = vertex;
return UnityObjectToClipPos(vertex);
}
fixed4 frag (PositionHolder IN) :SV_Target
{
if (IN.localPos.y > -.2)
return _UpperColor;
else
return _LowerColor;
}
(因此,如果在四边形上,它只用一种颜色绘制顶部 70%,用另一种颜色绘制底部条纹。)
请注意,vert
唯一做的就是沿着网格顶点位置的局部传递。
这是这样做的结构
struct PositionHolder
{
float3 localPos;
};
但是,(无论如何在 Unity 中)它需要 float3 的语义。
查看 Unity 的 doco,他们当然没有,但是有 link 到
https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-semantics
(除此之外 - 据我了解,它专门用于 D3D,但是,我想这就是 syntax/semantic 可以使用的吗?)
我的阅读情况,
建议你应该使用 say,
struct PositionHolder
{
float3 localPos :POSITION1;
};
或者实际上,您还没有将位置任意数字用作资源。
怎么样,
struct PositionHolder
{
float3 localPos :POSITION8;
};
祝你好运。
(令人困惑的是,它们似乎 运行 仅从 空白到 9,我不知道这是否反映了硬件现实,或者只是某处的劣质产品- 或什么。但无论如何,基本上是“您尚未在其他地方使用的任何数字 1 到 9。)
请注意,无论如何,POSITION
是一个 float4,真的适合我的 float3 吗? 对于通用的 float3,有没有比 POSITION 更好的东西? (我注意到如果你只使用,比如说,一种颜色,它也能正常工作。这有关系吗?)
“1 on the end”系统实际上正确吗?那么,POSITION1 可以开始了吗?我没有融化 gpu 或类似的东西?
嗯,我注意到您可以在其中输入任何内容(例如,"abcd1")。但是可以肯定的是,它实际上不是硬件寄存器吗???
1:GPU 寄存器是基于硬件的,它们总是大小为 4 的向量(float4 等),语义只是为了将变量绑定到名称,以便所有数据最终都在正确的位置。 GPU 上的所有矢量运算都使用 SIMD(单指令,多数据),因此对矢量执行计算几乎与标量一样快。但是,我不确定 POSITION,通常这个名称只填充输入变量的函数 - 对于您自己的任意输出变量,您应该使用 TEXCOORD0-N。 COLOR 插值器具有 8 位精度,也可能将值限制在 0-1 的范围内。
2:您可以使用的插值器寄存器的数量取决于支持的着色器模型(您可以使用#pragma target 4.0 来支持最多 32 个插值器,代价是至少需要 Direct3D 10)。但是,是的,您可以使用 0 或 8 或 4 或其他任何值。
3:你试过了吗?实际上,语义只是用来为编译器提供 hints/labels 我们想要什么数据在哪里。但是对于大多数值,我们使用哪个寄存器并不重要,显式输入寄存器实际上只是过去的遗留问题。不过,我从未见过有人将随机的东西写成着色器语义!
就个人而言,我认为像这样构建输入和输出更直观:
struct VertexInput {
// Here we use POSITION to tell the compiler that we want the vertex coords to be written to this variable.
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct VertexOutput {
float4 clipPos : SV_POSITION;
// Here we use TEXCOORD0-1, since these are just variables to be interpolated.
float3 localPos : TEXCOORD0;
float3 normal : TEXCOORD1;
};
VertexOutput Vert(VertexInput v) {
VertexOutput o;
o.clipPos = UnityObjectToClipPos(v.vertex);
o.localPos = v.vertex;
o.normal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 Frag(VertexOutput o) : SV_Target {
half3 normal = normalize(o.normal); // Interpolated values are not necessarily normalized
half NdotL = saturate(dot(normal, _WorldSpaceLightPos0.xyz));
return fixed4((fixed3)NdotL, 1); // Basic lambert lighting as an example
}
假设您的开发平台是iOS。
iOS有自己的着色器语言——金属着色语言。
为了让您的着色器在 iOS 上工作,unity 将它们从 HLSL 编译为 Metal。
因此,如果我们要编译以下着色器部分:
HLSL:
float4 localPos: POSITION1;
编译结果如下:
金属:
float4 POSITION1 [[ user(POSITION1) ]];
根据Metal Shading Language Specification
The attribute [[user(name)]] syntax can also be used to specify an
attribute name for any user-defined variables.
Unity3d 将您的 HLSL 语义字段 "name" 转换为 Metal Language 属性 [user(name)]。
所以,写成:[POSITION1 或 HelloWorld 或 Fattie] 都没关系,
只要它是唯一的并且不使用保留关键字。
因此,编译以下着色器后
HLSL:
float4 localPos: Fattie;
这将是结果:
金属:
float4 Fattie0 [[ user(Fattie0) ]];
关于向量数据类型,向量类型[float, float2, float3, float4, etc]
不特定于您的自定义语义名称。
使用 float3
编译此着色器
HLSL:
float3 localPos: Fattie;
给出以下结果:
金属:
float3 Fattie0 [[ user(Fattie0) ]];
这是一个非常简单的着色器,
float4 vert (float4 vertex :POSITION, out PositionHolder o) :SV_POSITION
{
UNITY_INITIALIZE_OUTPUT(PositionHolder,o);
o.localPos = vertex;
return UnityObjectToClipPos(vertex);
}
fixed4 frag (PositionHolder IN) :SV_Target
{
if (IN.localPos.y > -.2)
return _UpperColor;
else
return _LowerColor;
}
(因此,如果在四边形上,它只用一种颜色绘制顶部 70%,用另一种颜色绘制底部条纹。)
请注意,vert
唯一做的就是沿着网格顶点位置的局部传递。
这是这样做的结构
struct PositionHolder
{
float3 localPos;
};
但是,(无论如何在 Unity 中)它需要 float3 的语义。
查看 Unity 的 doco,他们当然没有,但是有 link 到
https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-semantics
(除此之外 - 据我了解,它专门用于 D3D,但是,我想这就是 syntax/semantic 可以使用的吗?)
我的阅读情况,
建议你应该使用 say,
struct PositionHolder
{
float3 localPos :POSITION1;
};
或者实际上,您还没有将位置任意数字用作资源。
怎么样,
struct PositionHolder
{
float3 localPos :POSITION8;
};
祝你好运。
(令人困惑的是,它们似乎 运行 仅从 空白到 9,我不知道这是否反映了硬件现实,或者只是某处的劣质产品- 或什么。但无论如何,基本上是“您尚未在其他地方使用的任何数字 1 到 9。)
请注意,无论如何,
POSITION
是一个 float4,真的适合我的 float3 吗? 对于通用的 float3,有没有比 POSITION 更好的东西? (我注意到如果你只使用,比如说,一种颜色,它也能正常工作。这有关系吗?)“1 on the end”系统实际上正确吗?那么,POSITION1 可以开始了吗?我没有融化 gpu 或类似的东西?
嗯,我注意到您可以在其中输入任何内容(例如,"abcd1")。但是可以肯定的是,它实际上不是硬件寄存器吗???
1:GPU 寄存器是基于硬件的,它们总是大小为 4 的向量(float4 等),语义只是为了将变量绑定到名称,以便所有数据最终都在正确的位置。 GPU 上的所有矢量运算都使用 SIMD(单指令,多数据),因此对矢量执行计算几乎与标量一样快。但是,我不确定 POSITION,通常这个名称只填充输入变量的函数 - 对于您自己的任意输出变量,您应该使用 TEXCOORD0-N。 COLOR 插值器具有 8 位精度,也可能将值限制在 0-1 的范围内。
2:您可以使用的插值器寄存器的数量取决于支持的着色器模型(您可以使用#pragma target 4.0 来支持最多 32 个插值器,代价是至少需要 Direct3D 10)。但是,是的,您可以使用 0 或 8 或 4 或其他任何值。
3:你试过了吗?实际上,语义只是用来为编译器提供 hints/labels 我们想要什么数据在哪里。但是对于大多数值,我们使用哪个寄存器并不重要,显式输入寄存器实际上只是过去的遗留问题。不过,我从未见过有人将随机的东西写成着色器语义!
就个人而言,我认为像这样构建输入和输出更直观:
struct VertexInput {
// Here we use POSITION to tell the compiler that we want the vertex coords to be written to this variable.
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct VertexOutput {
float4 clipPos : SV_POSITION;
// Here we use TEXCOORD0-1, since these are just variables to be interpolated.
float3 localPos : TEXCOORD0;
float3 normal : TEXCOORD1;
};
VertexOutput Vert(VertexInput v) {
VertexOutput o;
o.clipPos = UnityObjectToClipPos(v.vertex);
o.localPos = v.vertex;
o.normal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 Frag(VertexOutput o) : SV_Target {
half3 normal = normalize(o.normal); // Interpolated values are not necessarily normalized
half NdotL = saturate(dot(normal, _WorldSpaceLightPos0.xyz));
return fixed4((fixed3)NdotL, 1); // Basic lambert lighting as an example
}
假设您的开发平台是iOS。
iOS有自己的着色器语言——金属着色语言。
为了让您的着色器在 iOS 上工作,unity 将它们从 HLSL 编译为 Metal。 因此,如果我们要编译以下着色器部分:
HLSL:
float4 localPos: POSITION1;
编译结果如下:
金属:
float4 POSITION1 [[ user(POSITION1) ]];
根据Metal Shading Language Specification
The attribute [[user(name)]] syntax can also be used to specify an attribute name for any user-defined variables.
Unity3d 将您的 HLSL 语义字段 "name" 转换为 Metal Language 属性 [user(name)]。 所以,写成:[POSITION1 或 HelloWorld 或 Fattie] 都没关系, 只要它是唯一的并且不使用保留关键字。 因此,编译以下着色器后
HLSL:
float4 localPos: Fattie;
这将是结果:
金属:
float4 Fattie0 [[ user(Fattie0) ]];
关于向量数据类型,向量类型[float, float2, float3, float4, etc] 不特定于您的自定义语义名称。 使用 float3
编译此着色器HLSL:
float3 localPos: Fattie;
给出以下结果:
金属:
float3 Fattie0 [[ user(Fattie0) ]];