如何以 bgra8Unorm 像素格式绘制 MTLTexture
How to draw on MTLTexture in bgra8Unorm pixel format
当我使用 rgba32Float
像素格式在 MTLTexture
上绘图时,我的代码有效,然后我可以从中取出 CVPixelBuffer
。
但是 FlutterTexture
需要 bgra8Unorm
格式。由于性能开销,我不想转换 CVPixelBuffer
。
所以我尝试在 MTLTexture
上使用 bgra8Unorm
像素格式进行渲染,但无法编译以下片段着色器代码:
fragment vector_uchar4 fragmentShader2(Vertex interpolated [[stage_in]]) {
return 0xFFFFFFFF;
}
有错误:Invalid return type 'vector_uchar4' for fragment function
我试图用 uint
类型替换它,但它崩溃并出现错误:
Fatal error: 'try!' expression unexpectedly raised an error:
Error Domain=AGXMetalA11 Code=3
"output of type uint is not compatible with a MTLPixelFormatBGRA8Unorm color attachement."
UserInfo={NSLocalizedDescription=output of type uint is not compatible with a MTLPixelFormatBGRA8Unorm color attachement.}
如果我使用 vector_float4
或 vector_half4
return 键入我的纹理和缓冲区是空的。
我必须为 bgra8Unorm
像素格式使用哪种 return 类型并获得非空图像?金属有可能吗?
这取决于许多不同的因素。在大多数情况下,您应该使用 float4
或 half4
.
所有支持 metal 的现代苹果 GPU 都设计用于对(32 位或 64 位)浮点数据执行计算。这就是 GPU 的工作方式,这意味着着色器在 Float
、Snorm
、Unorm
格式上计算的任何读取操作都将在 32 位或 64 位浮点数上执行,无论的原始输入格式。
在任何写入操作中,着色器都会执行从 32 位或 64 位浮点到目标格式的转换。
转换规则请见Metal Shading Language specification第217页。
任何使用 Float
、Snorm
、Unorm
后缀的金属格式都是浮点格式,而 Uint
和 Sint
是无符号和有符号整数。
Float
- metal 定义的任何表示形式中的浮点值。
Unorm
- [0.0, 1.0] 范围内的浮点值。
Snorm
- [-1.0, 1.0] 范围内的浮点值。
Uint
- 无符号整数。
Sint
- 有符号整数。
我在 Metal Shading Language specification
的第 30 页找到了答案
最后这段代码按预期绘制图像:
fragment float4 fragmentShader2(Vertex interpolated [[stage_in]]) {
// ...
rgba8unorm<float4> rgba;
rgba = float4(color.r, color.g, color.b, 1.0);
return rgba;
}
如果有人能解释幕后发生的事情,我真的不想浪费赏金。
当我使用 rgba32Float
像素格式在 MTLTexture
上绘图时,我的代码有效,然后我可以从中取出 CVPixelBuffer
。
但是 FlutterTexture
需要 bgra8Unorm
格式。由于性能开销,我不想转换 CVPixelBuffer
。
所以我尝试在 MTLTexture
上使用 bgra8Unorm
像素格式进行渲染,但无法编译以下片段着色器代码:
fragment vector_uchar4 fragmentShader2(Vertex interpolated [[stage_in]]) {
return 0xFFFFFFFF;
}
有错误:Invalid return type 'vector_uchar4' for fragment function
我试图用 uint
类型替换它,但它崩溃并出现错误:
Fatal error: 'try!' expression unexpectedly raised an error:
Error Domain=AGXMetalA11 Code=3
"output of type uint is not compatible with a MTLPixelFormatBGRA8Unorm color attachement."
UserInfo={NSLocalizedDescription=output of type uint is not compatible with a MTLPixelFormatBGRA8Unorm color attachement.}
如果我使用 vector_float4
或 vector_half4
return 键入我的纹理和缓冲区是空的。
我必须为 bgra8Unorm
像素格式使用哪种 return 类型并获得非空图像?金属有可能吗?
这取决于许多不同的因素。在大多数情况下,您应该使用 float4
或 half4
.
所有支持 metal 的现代苹果 GPU 都设计用于对(32 位或 64 位)浮点数据执行计算。这就是 GPU 的工作方式,这意味着着色器在 Float
、Snorm
、Unorm
格式上计算的任何读取操作都将在 32 位或 64 位浮点数上执行,无论的原始输入格式。
在任何写入操作中,着色器都会执行从 32 位或 64 位浮点到目标格式的转换。
转换规则请见Metal Shading Language specification第217页。
任何使用 Float
、Snorm
、Unorm
后缀的金属格式都是浮点格式,而 Uint
和 Sint
是无符号和有符号整数。
Float
- metal 定义的任何表示形式中的浮点值。
Unorm
- [0.0, 1.0] 范围内的浮点值。
Snorm
- [-1.0, 1.0] 范围内的浮点值。
Uint
- 无符号整数。
Sint
- 有符号整数。
我在 Metal Shading Language specification
的第 30 页找到了答案最后这段代码按预期绘制图像:
fragment float4 fragmentShader2(Vertex interpolated [[stage_in]]) {
// ...
rgba8unorm<float4> rgba;
rgba = float4(color.r, color.g, color.b, 1.0);
return rgba;
}
如果有人能解释幕后发生的事情,我真的不想浪费赏金。