将自定义 SKShader 应用于 SKScene,使用 Swift 在 iOS 8 SpriteKit 中对整个渲染场景进行像素化 [英] Applying a custom SKShader to SKScene that pixelates the whole rendered scene in iOS 8 SpriteKit with Swift

查看:34
本文介绍了将自定义 SKShader 应用于 SKScene,使用 Swift 在 iOS 8 SpriteKit 中对整个渲染场景进行像素化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 SKScene 上创建全屏像素化效果.我了解到应该有两种选择:

I'm trying to create a full-screen pixelation effect on SKScene. I've learned that there should be two options to do this:

  • 使用 GLES 2.0 的自定义 SKShader.
  • 使用核心图像过滤器.

我尝试添加一个自定义 SKShader,它应该通过像素化来修改整个屏幕.我不确定这是否可能,但来自 SKScene 的文档(它是 SKEffectNode 的子类)建议这样做:

I've tried to add a custom SKShader that should modify the whole screen by pixelating it. I'm not sure that if it's possible, but documentation from SKScene (which is a subclass of SKEffectNode) suggests it:

SKEffectNode 对象将其子对象渲染到缓冲区中,然后可选地将 Core Image 过滤器应用于此渲染输出.

An SKEffectNode object renders its children into a buffer and optionally applies a Core Image filter to this rendered output.

可以将 SKShader 分配给 SKScene,如 GameScene : SKScene:

It's possible to assign a SKShader to the SKScene, as in GameScene : SKScene:

override func didMoveToView(view: SKView) {
    let shader = SKShader(fileNamed: "pixelation.fsh")
    self.shader = shader
    self.shouldEnableEffects = true
}

...但似乎渲染的缓冲区没有作为 u_texture 传递给 GLES:

... but it seems that the rendered buffer is not passed as the u_texture to the GLES:

void main()
{
    vec2 coord = v_tex_coord;
    coord.x = floor(coord.x * 10.0) / 10.0;
    coord.y = floor(coord.y * 10.0) / 10.0;
    vec4 texture = texture2D(u_texture, coord);
    gl_FragColor = texture;
}

...所以之前的着色器不起作用.

... so the previous shader doesn't work.

如果我将该着色器分配给基于纹理的 SKSpriteNode,它可以工作.

If I assign that shader to a texture-based SKSpriteNode, it works.

那么,在所有节点都被渲染之后,是否可以修改整个帧缓冲区(例如对其进行像素化)作为后处理措施?

So is it possible to modify the whole frame buffer (and for example pixelate it) as a post-processing measure after all the nodes have been rendered?

编辑:我找到了一种在 OS X 中使用 Core Image 滤镜进行像素化的方法(如何将 CIPixellate Core Image Filter 添加到 Sprite Kit 场景中?),但复制该实现不会在 iOS 上产生任何结果.根据 documents CIPixellate 应该是在 OS X v10.4 及更高版本和 iOS 6.0 及更高版本中可用..

Edit: I found a way to do the pixelation using Core Image filters in OS X (How do you add a CIPixellate Core Image Filter to a Sprite Kit scene?), but copying that implementation doesn't yield any results on iOS. According to the documents CIPixellate should be Available in OS X v10.4 and later and in iOS 6.0 and later..

推荐答案

为了让你的 .shaderSKScene 上运行,你需要设置 shouldEnableEffects 在场景中设置为 true(SKEffectNode 也是如此).

In order to get your .shader running on SKScene, you need to set shouldEnableEffects to true on the scene (same thing goes for SKEffectNode).

虽然从技术上讲,这有效"(应用了着色器),但在之后的场景渲染中存在一个错误,会稍微调整大小.

While technically, that "works" (the shader is applied), there's a bug in the rendering of the scene afterwards that gets slightly resized.

所以到目前为止,使用 CoreImage 过滤器是最好的方法.

So using CoreImage filters is, so far, the best way to go.

这篇关于将自定义 SKShader 应用于 SKScene,使用 Swift 在 iOS 8 SpriteKit 中对整个渲染场景进行像素化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆