iOS Metal Shader-纹理读取和写入访问权限? [英] iOS Metal Shader - Texture read and write access?

查看:289
本文介绍了iOS Metal Shader-纹理读取和写入访问权限?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用金属着色器在屏幕上绘制许多粒子.每个粒子都有其自己的位置(可以改变),通常两个粒子具有相同的位置.如何检查写入的texture2d在特定位置还没有像素? (我想确保仅在尚未绘制粒子的情况下才在特定位置绘制粒子,因为如果在同一位置绘制许多粒子,我会出现难看的闪烁)

我尝试了outTexture.read(particlePosition),但是由于纹理访问限定符access::write,这显然不起作用.

是否可以同时具有对texture2d的读写访问权限? (如果没有,我怎么还能解决我的问题?)

解决方案

有几种方法可以在这里工作.在并发系统编程中,您所说的称为先写胜利.

1)如果粒子只需要阻止其他粒子被绘制(并且在同一渲染过程中不会被场景中的其他元素遮挡),则可以将特殊值写入深度缓冲区以表示片段已被写入特定坐标.例如,您将打开深度测试(使用深度比较功能Equal),将深度缓冲区清除为某个较远的值(如1.0),然后将0.0的值写入片段函数中的深度缓冲区.随后对给定像素的任何写入将无法通过深度测试,并且不会被绘制.

2)使用帧缓冲区回读.在iOS上,Metal允许您通过使用[[color(0)]]将参数分配给片段函数来读取当前绑定的主渲染缓冲区.此参数将在渲染缓冲区中包含当前颜色值,您可以对其进行测试以确定是否已将其写入.这确实需要将纹理清除为预定的颜色,否则片段功能将永远不会产生这种颜色,因此它比上述方法受到更多限制,并且性能可能更低.

无论您是渲染到可绘制的纹理以直接显示在屏幕上,还是应用于某些屏幕外纹理,上述所有方法都适用.

I'm using a metal shader to draw many particles onto the screen. Each particle has its own position (which can change) and often two particles have the same position. How can I check if the texture2d I write into does not have a pixel at a certain position yet? (I want to make sure that I only draw a particle at a certain position if there hasn't been drawn a particle yet, because I get an ugly flickering if many particles are drawn at the same positon)

I've tried outTexture.read(particlePosition), but this obviously doesn't work, because of the texture access qualifier, which is access::write.

Is there a way I can have read and write access to a texture2d at the same time? (If there isn't, how could I still solve my problem?)

解决方案

There are several approaches that could work here. In concurrent systems programming, what you're talking about is termed first-write wins.

1) If the particles only need to preclude other particles from being drawn (and aren't potentially obscured by other elements in the scene in the same render pass), you can write a special value to the depth buffer to signify that a fragment has already been written to a particular coordinate. For example, you'd turn on depth test (using the depth compare function Equal), clear the depth buffer to some distant value (like 1.0), and then write a value of 0.0 to the depth buffer in the fragment function. Any subsequent write to a given pixel will fail to pass the depth test and will not be drawn.

2) Use framebuffer read-back. On iOS, Metal allows you to read from the currently-bound primary renderbuffer by attributing a parameter to your fragment function with [[color(0)]]. This parameter will contain the current color value in the renderbuffer, which you can test against to determine whether it has been written to. This does require you to clear the texture to a predetermined color that will never otherwise be produced by your fragment function, so it is more limited than the above approach, and possibly less performant.

All of the above applies whether you're rendering to a drawable's texture for direct presentation to the screen, or to some offscreen texture.

这篇关于iOS Metal Shader-纹理读取和写入访问权限?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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