PixelKit
适用于iOS、macOS和tvOS的实时图形框架
运行于RenderKit - 由Metal驱动 - 受TouchDesigner启发
示例: 相机效果 - 绿幕 - Hello Pixels应用 - 代码参考 - 代码示例 - 代码演示
信息: 网站 - 坐标空间 - 混合运算符 - 效果便利函数 - 高比特模式 - 应用
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|---|---|---|---|---|
相机 | 深度相机 | 图片 | 视频 | 屏幕截图 | 流输入 |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|---|---|---|---|---|---|---|---|---|
颜色 | 圆形 | 矩形 | 多边形 | 弧线 | 直线 | 渐变 | 噪声 | 文本 | 金属 |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|---|---|---|---|---|---|---|---|---|
等级 | 模糊 | 边缘 | 阈值 | 量化 | 转换 | kaleidoscope | 扭曲 | 反馈 | 延迟 |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|---|---|---|---|---|---|---|---|---|
通道混合 | 色键 | 角定位 | 色相饱和度 | 裁剪 | 黑白转换 | 范围 | 锐化 | 斜率 | 棕褐色 |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|---|---|---|---|---|---|---|---|---|---|
混合 | 交叉 | 查找表 | 位移 | 重映射 | 重排序 | 分辨率 | 转换 | 夹具 | 冻结 | 闪光灯 |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|---|---|---|---|---|---|---|
混合 | 亮度等级 | 亮度模糊 | 时光机 | 数组 | AirPlay | 录制 | 流输出 |
安装
Swift Package
.package(url: "https://github.com/hexagons/PixelKit.git", from: "1.0.0")
请注意,SwiftPM 还不支持资源文件,因此您需要在您的应用程序中链接 Metal 库。
获取您平台上的最新 Metal 库这里并将其添加到您的捆绑包中。
然后在 AppDelegate.swift
中,在 application colorWithLaunchOptions
方法中,添加以下内容:
pixelKitMetalLibURL = Bundle.main.url(forResource: "PixelKitShaders-<platform>", withExtension: "metallib")!
CocoaPods
CocoaPods 是 Cocoa 项目的依赖项管理器。有关使用和安装说明,请访问他们的网站。要使用 CocoaPods 将 PixelKit
集成到您的 Xcode 项目中,请在您的 Podfile
中指定它。
pod 'PixelKit', '~> 1.0.0'
然后导入
import PixelKit
请注意,PixelKit 仅在 macOS Catalina 上 Xcode 11 的 iOS 13 中提供模拟器支持。在 Xcode 10 及以下版本中,iOS 上的 Metal 只能在物理设备上运行。
要获取对摄像头的访问权限,在 macOS 上,请在您的 Xcode 项目设置中,在“App 权限”下的“相机”中勾选“Camera”。
要访问所有依赖项功能
import LiveValues
import RenderKit
设置
UIKit
import UIKit
import LiveValues
import RenderKit
import PixelKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let circlePix = CirclePIX(at: .fullscreen)
let blurPix = BlurPIX()
blurPix.input = circlePix
blurPix.radius = 0.25
let finalPix: PIX = blurPix
finalPix.view.frame = view.bounds
view.addSubview(finalPix)
}
}
SwiftUI
import SwiftUI
import LiveValues
import RenderKit
import PixelKit
struct ContentView: View {
var body: some View {
BlurPIXUI {
CirclePIXUI()
}
.radius(0.25)
.edgesIgnoringSafeArea(.all)
}
}
实时值文档
教程
用Swift入门PixelKit
在PixelKit中入门Metal
Swift & PixelKit中的绿幕技术
VertexKit & PixelKit中的粒子效果
示例
Hello Pixels App
代码参考
代码示例
代码演示
示例:相机效果
import LiveValues import RenderKit import PixelKit
let camera = CameraPIX()
let levels = LevelsPIX()
levels.input = camera
levels.brightness = 1.5
levels.gamma = 0.5
let hueSat = HueSaturationPIX()
hueSat.input = levels
hueSat.sat = 0.5
let blur = BlurPIX()
blur.input = hueSat
blur.radius = 0.25
let res: Resolution = .custom(w: 1500, h: 1000)
let circle = CirclePIX(at: res)
circle.radius = 0.45
circle.bgColor = .clear
let finalPix: PIX = blur & (camera * circle)
finalPix.view.frame = view.bounds
view.addSubview(finalPix.view)
这也可以使用Effect ConvenienceFuncs来完成
let pix = CameraPIX()._brightness(1.5)._gamma(0.5)._saturation(0.5)._blur(0.25)
SwiftUI
struct ContentView: View {
var content: PIXUI {
HueSaturationPIXUI {
LevelsPIXUI {
ResPIXUI {
CameraPIXUI()
}
}
.gamma(0.5)
.brightness(LiveFloat(1.5))
}
.saturation(LiveFloat(0.5))
}
var body: some View {
BlendsPIXUI {
BlurPIXUI {
RawPIXUI(pix: content.pix)
}
.radius(0.25)
BlendsPIXUI {
CirclePIXUI()
.bgColor(.clear)
.radius(0.25)
RawPIXUI(pix: content.pix)
}
.blendMode(.multiply)
}
.blendMode(.over)
}
}
![]() |
![]() |
![]() |
![]() |
![]() |
---|
记得在你的info.plist中添加NSCameraUsageDescription
示例:绿幕技术
import LiveValues import RenderKit import PixelKit
let cityImage = ImagePIX()
cityImage.image = UIImage(named: "city")
let supermanVideo = VideoPIX()
supermanVideo.load(fileNamed: "superman", withExtension: "mov")
let supermanKeyed = ChromaKeyPIX()
supermanKeyed.input = supermanVideo
supermanKeyed.keyColor = .green
let blendPix = BlendPIX()
blendPix.blendingMode = .over
blendPix.inputA = cityImage
blendPix.inputB = supermanKeyed
let finalPix: PIX = blendPix
finalPix.view.frame = view.bounds
view.addSubview(finalPix.view)
这也可以使用混合运算符和Effect ConvenienceFuncs来完成
let pix = cityImage & supermanVideo._chromaKey(.green)
SwiftUI
struct ContentView: View {
var body: some View {
BlendsPIXUI {
ImagePIXUI(image: UIImage(named: "city")!)
ChromaKeyPIXUI {
VideoPIXUI(fileNamed: "superman", withExtension: "mov")
}
.keyColor(.green)
}
.blendMode(.over)
}
}
![]() |
![]() |
![]() |
![]() |
---|
这是Pixel Nodes 绿幕项目的表示。
示例:深度相机
import LiveValues import RenderKit import PixelKit
let cameraPix = CameraPIX()
cameraPix.camera = .front
let depthCameraPix = DepthCameraPIX.setup(with: cameraPix)
let levelsPix = LevelsPIX()
levelsPix.input = depthCameraPix
levelsPix.inverted = true
let lumaBlurPix = cameraPix._lumaBlur(with: levelsPix, radius: 0.1)
let finalPix: PIX = lumaBlurPix
finalPix.view.frame = view.bounds
view.addSubview(finalPix.view)
DepthCameraPIX
在 PixelKit v0.8.4
中添加,需要 iPhone X 或更高版本。
注意使用 DepthCameraPIX
的 setup(with:filter:)
方法。
它会处理方向、颜色以及启用 CameraPIX
上的深度。
要访问0.0和1.0范围之外的深度值
开启 16位
模式,如下所示: PixelKit.main.render.bits = ._16
示例:多摄像头
let cameraPix = CameraPIX()
cameraPix.camera = .back
let multiCameraPix = MultiCameraPIX.setup(with: cameraPix, camera: .front)
let movedMultiCameraPix = multiCameraPix._scale(by: 0.25)._move(x: 0.375 * (9 / 16), y: 0.375)
let finalPix: PIX = camearPix & movedMultiCameraPix
finalPix.view.frame = view.bounds
view.addSubview(finalPix.view)
注意 MultiCameraPIX
需要 iOS 13。
坐标空间
PixelKit 坐标空间垂直轴(高度为1.0)归一化,原点(0.0,0.0)位于中心。
请注意,与原生的UIKit视图相比,垂直轴翻转且原点移动,这在PixelKit中处理图形时更方便。完整的旋转由1.0定义
中心: CGPoint(x: 0, y: 0)
左下角: CGPoint(x: -0.5 * aspectRatio, y: -0.5)
右上角: CGPoint(x: 0.5 * aspectRatio, y: 0.5)
提示: Resolution
有一个 .aspect
属性
let aspectRatio: LiveFloat = Resolution._1080p.aspect
混合运算符
混合 PIX 的快捷方便的方法
这包括支持的 BlendingMode
运算符
& |
!& |
+ |
- |
* |
** |
!** |
% |
~ |
° |
---|---|---|---|---|---|---|---|---|---|
.over | .under | .add | .subtract | .multiply | .power | .gamma | .difference | .average | cosine |
<> |
>< |
++ |
-- |
<-> |
>-< |
+-+ |
---|---|---|---|---|---|---|
.minimum | .maximum | .addWithAlpha | .subtractWithAlpha | inside | outside | exclusiveOr |
let blendPix = (CameraPIX() !** NoisePIX(at: .fullHD(.portrait))) * CirclePIX(at: .fullHD(.portrait))
注意使用 Live 值时,一行 if else 语句用 <?>
& <=>
编写
let a: LiveFloat = 1.0
let b: LiveFloat = 2.0
let isOdd: LiveBool = .seconds % 2.0 < 1.0
let ab: LiveFloat = isOdd <?> a <=> b
默认的全局混合运算符填充模式是 .aspectFit
,更改方法如下
PIX.blendOperators.globalPlacement = .aspectFill
实时值
实时值可以是常数(let
)并且仍然具有变化值。实时值可以使用 .live
或 .seconds
静态属性轻松动画化。
实时值
CGFloat
-->LiveFloat
Int
-->LiveInt
Bool
-->LiveBool
CGPoint
-->LivePoint
CGSize
-->LiveSize
CGRect
-->LiveRect
静态属性
LiveFloat.live
LiveFloat.seconds
LiveFloat.secondsSince1970
LiveFloat.touch
/LiveFloat.mouseLeft
LiveFloat.touchX
/LiveFloat.mouseX
LiveFloat.touchY
/LiveFloat.mouseY
LivePoint.touchXY
/LiveFloat.mouseXY
LiveFloat.gyroX
LiveFloat.gyroY
LiveFloat.gyroZ
LiveFloat.accelerationX/Y/Z
LiveFloat.magneticFieldX/Y/Z
LiveFloat.deviceAttitudeX/Y/Z
LiveFloat.deviceGravityX/Y/Z
LiveFloat.deviceHeading
函数
liveFloat.delay(seconds: 1.0)
liveFloat.filter(seconds: 1.0)
liveFloat.filter(frames: 60)
静态函数
LiveFloat.noise(range: -1.0...1.0, for: 1.0)
LiveFloat.wave(range: -1.0...1.0, for: 1.0)
效果便捷函数
- pix._reRes(to: ._1080p * 0.5) -> ResPIX
- pix._reRes(by: 0.5) -> ResPIX
- pix._brightness(0.5) -> LevelsPIX
- pix._darkness(0.5) -> LevelsPIX
- pix._contrast(0.5) -> LevelsPIX
- pix._gamma(0.5) -> LevelsPIX
- pix._invert() -> LevelsPIX
- pix._opacity(0.5) -> LevelsPIX
- pix._blur(0.5) -> BlurPIX
- pix._edge() -> EdgePIX
- pix._threshold(at: 0.5) -> ThresholdPIX
- pix._quantize(by: 0.5) -> QuantizePIX
- pix._position(at: CGPoint(x: 0.5, y: 0.5)) -> TransformPIX
- pix._rotatate(to: .pi) -> TransformPIX
- pix._scale(by: 0.5) -> TransformPIX
- pix._kaleidoscope() -> KaleidoscopePIX
- pix._twirl(0.5) -> TwirlPIX
- pix._swap(.red, .blue) -> ChannelMixPIX
- pix._key(.green) -> ChromaKeyPIX
- pix._hue(0.5) -> HueSaturationPIX
- pix._saturation(0.5) -> HueSaturationPIX
- pix._crop(CGRect(x: 0.25, y 0.25, width: 0.5, height: 0.5)) -> CropPIX
- pix._flipX() -> FlipFlopPIX
- pix._flipY() -> FlipFlopPIX
- pix._flopLeft() -> FlipFlopPIX
- pix._flopRight() -> FlipFlopPIX
- pix._range(inLow: 0.0, inHigh: 0.5, outLow: 0.5, outHigh: 1.0) -> RangePIX
- pix._range(inLow: .clear, inHigh: .gray, outLow: .gray, outHigh: .white) -> RangePIX
- pix._sharpen() -> SharpenPIX
- pix._slope() - > SlopePIX
- pixA._lookup(with: pixB, axis: .x) -> LookupPIX
- pixA._lumaBlur(with: pixB, radius: 0.5) -> LumaBlurPIX
- pixA._lumaLevels(with: pixB, brightness: 2.0) -> LumaLevelsPIX
- pixA._vignetting(with: pixB, inset: 0.25, gamma: 0.5) -> LumaLevelsPIX
- pixA._displace(with: pixB, distance: 0.5) -> DisplacePIX
- pixA._remap(with: pixB) -> RemapPIX
请注意,这些函数会创建新的PIX。
注意避免GPU内存过载,一些函数会创建多个PIX。
MIDI
这里是一个在0.0到1.0范围内的实时MIDI值的示例。
let circle = CirclePIX(at: ._1024)
circle.radius = .midi("13")
circle.color = .midi("17")
您可以通过启用以下类型的日志记录来找到地址
MIDI.main.log = true
高比特模式
一些效果,如< b >DisplacePIX和SlopePIX,可以从更高的比特深度中受益。
默认为8位。更改方法如下:< code >PixelKit.main.render.bits = ._16
在创建任何PIX之前,启用高比特模式。
注意,资源尚未支持更高的比特。
目前资源中存在一些伽马偏移。
金属PIXs
let metalPix = MetalPIX(at: ._1080p, code:
"""
pix = float4(u, v, 0.0, 1.0);
"""
)
let metalEffectPix = MetalEffectPIX(code:
"""
float gamma = 0.25;
pix = pow(input, 1.0 / gamma);
"""
)
metalEffectPix.input = CameraPIX()
let metalMergerEffectPix = MetalMergerEffectPIX(code:
"""
pix = pow(inputA, 1.0 / inputB);
"""
)
metalMergerEffectPix.inputA = CameraPIX()
metalMergerEffectPix.inputB = ImagePIX("img_name")
let metalMultiEffectPix = MetalMultiEffectPIX(code:
"""
float4 inPixA = inTexs.sample(s, uv, 0);
float4 inPixB = inTexs.sample(s, uv, 1);
float4 inPixC = inTexs.sample(s, uv, 2);
pix = inPixA + inPixB + inPixC;
"""
)
metalMultiEffectPix.inputs = [ImagePIX("img_a"), ImagePIX("img_b"), ImagePIX("img_c")]
制服
var lumUniform = MetalUniform(name: "lum")
let metalPix = MetalPIX(at: ._1080p, code:
"""
pix = float4(in.lum, in.lum, in.lum, 1.0);
""",
uniforms: [lumUniform]
)
lumUniform.value = 0.5
应用
像素节点
专用于iPad的实时图形节点编辑器
由PixelKit提供支持
分层相机
一个相机应用程序让您实时使用自选图层滤镜。
结合效果,创建新的酷炫风格。
像素相机
实时相机滤镜。
从图库加载照片。
VJLive
VJLive是一款带有效果的双轨资产播放系统。
资产可以从“照片”加载。实时相机支持。AirPlay支持。
由Anton Heestand,六边形提供