- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试移植一些 CIFilter
来自这个source通过为 Core Image 使用 Metal 着色语言。
我有一个由 RGB
数组组成的调色板结构,我想将它们作为参数传递给自定义 CI 彩色图像内核。
RGB 结构被转换为 SIMD3<Float>
的数组.
static func SIMD3Palette(_ palette: [RGB]) -> [SIMD3<Float>] {
return palette.map{$0.toFloat3()}
}
内核应该采用 simd_float3
的数组值,问题是当我启动过滤器时它告诉我索引 1 处的参数需要一个 NSData
.
override var outputImage: CIImage? {
guard let inputImage = inputImage else
{
return nil
}
let palette = EightBitColorFilter.palettes[Int(inputPaletteIndex)]
let extent = inputImage.extent
let arguments = [inputImage, palette, Float(palette.count)] as [Any]
let final = colorKernel.apply(extent: extent, arguments: arguments)
return final
}
这是内核:
float4 eight_bit(sample_t image, simd_float3 palette[], float paletteSize, destination dest) {
float dist = distance(image.rgb, palette[0]);
float3 returnColor = palette[0];
for (int i = 1; i < floor(paletteSize); ++i) {
float tempDist = distance(image.rgb, palette[i]);
if (tempDist < dist) {
dist = tempDist;
returnColor = palette[i];
}
}
return float4(returnColor, 1);
}
我想知道如何将数据缓冲区传递给内核,因为将其转换为 NSData 似乎还不够。
我看到了一些例子,但他们使用的是“完整”着色语言,这种语言不适用于 Core Image,这是一种 subset只处理片段。
最佳答案
我们现在已经弄清楚了如何将数据缓冲区直接传递到 Core Image 内核中。使用 CIImage
如下所述不需要,但仍然可行。
假设您的原始数据为 NSData
,您可以在调用时将其传递给内核:
kernel.apply(..., arguments: [data, ...])
注意:Data
可能也有效,但我知道 NSData
是一种参数类型,它允许 Core Image 根据输入参数缓存过滤结果。因此,当有疑问时,最好将其转换为 NSData
.
然后在内核函数中,只需要用合适的 constant
来声明参数即可输入:
extern "C" float4 myKernel(constant float3 data[], ...) {
float3 data0 = data[0];
// ...
}
上一个答案
Core Image 内核似乎不支持指针或数组参数类型。尽管 iOS 13 似乎带来了一些东西。来自发行说明:
Metal CIKernel instances support arguments with arbitrarily structured data.
但是,与 Core Image 一样,似乎没有进一步的文档......
但是,您仍然可以使用传递缓冲区数据的“旧方法”,将其包装在 CIImage
中。并在内核中对其进行采样。例如:
let array: [Float] = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]
let data = array.withUnsafeBufferPointer { Data(buffer: $0) }
let dataImage = CIImage(bitmapData: data, bytesPerRow: data.count, size: CGSize(width: array.count/4, height: 1), format: .RGBAf, colorSpace: nil)
请注意,没有 CIFormat
对于 3 channel 图像,因为 GPU 不支持这些图像。所以你要么必须使用单 channel .Rf
并将内核中的值重新打包为 float3
再次,或者向您的数据添加一些步幅并使用 .RGBAf
和 float4
分别(我推荐这样做,因为它减少了纹理获取)。
当您将该图像传递到内核时,您可能希望将采样模式设置为 nearest
,否则在两个像素之间采样时可能会得到插值:
kernel.apply(..., arguments: [dataImage.samplingNearest(), ...])
在您的(Metal)内核中,您可以像使用普通输入图像一样通过 sampler
评估数据。 :
extern "C" float4 myKernel(coreimage::sampler data, ...) {
float4 data0 = data.sample(data.transform(float2(0.5, 0.5))); // data[0]
float4 data1 = data.sample(data.transform(float2(1.5, 0.5))); // data[1]
// ...
}
请注意,我添加了 0.5
到坐标,以便它们指向数据图像中像素的中间,以避免模糊和插值。
另请注意,您从 sampler
获得的像素值总是有4个 channel 。因此,即使您使用甲酸盐.Rf
创建数据图像, ,您将得到 float4
采样时(其他值用 0.0
填充 G 和 B,用 1.0
填充 alpha)。在这种情况下,你可以这样做
float data0 = data.sample(data.transform(float2(0.5, 0.5))).x;
编辑
我之前忘记将样本坐标从绝对像素空间(其中 (0.5, 0.5)
是第一个像素的中间)转换为相对采样器空间(其中 (0.5, 0.5)
是整个缓冲区的中间)。现在已经修复了。
关于ios - Core Image 颜色内核的 Metal 着色语言,如何传递 float3 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57751660/
在 Metal 中,在着色器内部(进出)使用什么坐标系?当我们渲染到纹理时是一样的吗?也有z缓冲区?有没有不一致的地方?最后 Metal ,opengl和directX有什么区别? 最佳答案 Meta
我正在尝试在 Mac 上的 Apple metal 中开发我自己的迷你游戏引擎,但我被困在我想在 GPU 上渲染文本的地方。我没有太多的图形编程经验,因此我不知道该怎么做。我偶然发现了 Warren
我找不到答案的简单问题,在 openGL 上有一个 glDeleteTextures(1, &t) 显然模型有很大的不同,但我想知道 Metal 是否有相同的需要或要求。 MTLTexture 是通过
我是 Metal 新手。我想使用 Metal 计算来做一些数学运算,所以我创建了一个内核函数(着色器?),比方说 kernel void foo(device float *data1,
我假设除了 Metal 之外的其他 API 中存在颜色附件(我肯定知道 OpenGL),但我是图形编程的新手,我想知道颜色附件在概念上到底是什么。我所做的所有绘图都涉及在颜色附件数组中的第一个设置属性
在计算着色器中,我可以看到双三次是一个选项,但前提是定义了 __HAVE_BICUBIC_FILTERING__。当我将 bicubic 设置为过滤选项时,出现语法错误。 Linear 或Neares
这是一个绝对的初学者问题。 背景:我并不是真正的游戏开发者,但我正在努力学习底层 3D 编程的基础知识,因为这是一个有趣且有趣的话题。我选择了 Apple 的 Metal 作为图形框架。我知道 Sce
在 GLSL 中,我只需使用 out vec3 array[10]; 将数组从顶点着色器传递到片段着色器。然而,在 Metal 中,我想这样做: struct FragmentIn { flo
我看到 Apple GPU 硬件和 iOS/MacOS 版本的组合决定了一个功能集。我可以使用下面的快速代码片段查询我的 MTLDevice 支持哪些功能集。 device.supportsFeatu
我想将深度缓冲区保存到 Metal 纹理中,但我尝试过的任何方法似乎都不起作用。 _renderPassDesc.colorAttachments[1].clearColor = MTLClearCo
我想在我的 Metal 应用程序中实现一个 A-Buffer 算法来实现与订单无关的透明度。该技术的描述提到使用原子计数器。我从未使用过其中之一,甚至没有听说过。我刚刚阅读了 Metal Shadin
假设我有一个 N channel MPSImage 或基于 MTLTexture 的纹理数组。 我如何从中裁剪一个区域,复制所有 N 个 channel ,但改变“像素大小”? 最佳答案 我将只讨论裁
TL;DR:Metal 似乎没有检测到我的顶点着色器返回的内容 我有这两个用 MSL 编写的函数: vertex float4 base_image_rect(constant float4 *pos
如何在目标设置为 iOS 模拟器的情况下在 Xcode 6 中编译 iOS «Metal» 游戏? error: can't exec 'metal' (No such file or directo
将一些基本的 OpenGL ES 2.0 着色器移植到 Metal 着色器时,我不知道如何将 glsl 中的 in/inout/out 限定符转换为 Metal 着色器语言 (MSL)。例如, //O
我不想使用texture1d_array。我可以简单地传递一个 float 组吗?我将把它写入我的内核函数中。 最佳答案 为了写入内核函数内的 float 组,您需要向内核提供一个缓冲区参数。该参数应
我不想使用texture1d_array。我可以简单地传递一个 float 组吗?我将把它写入我的内核函数中。 最佳答案 为了写入内核函数内的 float 组,您需要向内核提供一个缓冲区参数。该参数应
我有一组 Metal 纹理作为纹理集存储在 Xcode Assets 目录中。我正在使用 MTKTextureLoader.newTexture(name:scaleFactor:bundle:opt
Apple 系统中似乎至少有六个矩阵库。其中之一是 simd 库,其类型在 CPU 和 GPU 代码中的工作方式相同。 import simd let mat = float3x3(...) let
有谁知道 Apple 的旧版本 Metal Feature Set Table 的可用性?文件? 当前的 Metal 3.0 文档仅引用 beta MTLGPUFamily 和 MTLSoftware
我是一名优秀的程序员,十分优秀!