如何创建一个着色器以使用距中心点的度数偏移进行遮罩?
我有点迷失了,这与 另一个问题 我曾询问过有关片段着色器的问题,但超出了它。
我有一个正交场景(尽管这可能不相关),此处的场景绘制为黑色,并且我有一个使用着色器绘制的广告牌精灵,我将其显示为红色。我有一个我知道并定义自己的点,A,由蓝点表示,位于 2d 坐标空间中的某个 x,y 坐标处。 (屏幕左下角是原点)。我需要以编程方式屏蔽红色广告牌,其中指定 0% 到 100%,其中 0% 完全完整,100% 完全屏蔽。我可以将 0-100%(0 到 1.0)传递给着色器,或者我可以预先计算一个角度,这两种解决方案都可以。
(在这里您可以看到使用“0%”遮罩绘制的场景)
因此,当我设置“15%”时,我希望显示以下内容:
(在这里您可以看到使用“15%”遮罩绘制的场景)
当我设置“45%”时,我希望显示以下内容:
(在这里您可以看到使用“45%”遮罩绘制的场景)
这是“80%”的示例:
我认为总体思路是传入一个统一的“A”vec2d,并在片段着色器中确定该片段是否位于从“A”到屏幕底部到 a 线的区域内这是从那里顺时针偏移的正确角度。如果在该区域内,则丢弃该片段。 (如果保留的话,丢弃比将 alpha 设置为 0.0 或 1.0 更有意义,对吧?)
但是我怎样才能真正实现这一点呢?我不明白如何用着色器来实现该算法。 (我使用的是 OpenGL ES 2.0)
I'm a little bit lost, and this is somewhat related to another question I've asked about fragment shaders, but goes beyond it.
I have an orthographic scene (although that may not be relevant), with the scene drawn here as black, and I have one billboarded sprite that I draw using a shader, which I show in red. I have a point that I know and define myself, A, represented by the blue dot, at some x,y coordinate in the 2d coordinate space. (Lower-left of screen is origin). I need to mask the red billboard in a programmatic fashion where I specify 0% to 100%, with 0% being fully intact and 100% being fully masked. I can either pass 0-100% (0 to 1.0) in to the shader, or I could precompute an angle, either solution would be fine.
( Here you can see the scene drawn with '0%' masking )
So when I set "15%" I want the following to show up:
( Here you can see the scene drawn with '15%' masking )
And when I set "45%" I want the following to show up:
( Here you can see the scene drawn with '45%' masking )
And here's an example of "80%":
The general idea, I think, is to pass in a uniform 'A' vec2d, and within the fragment shader I determine if the fragment is within the area from 'A' to bottom of screen, to the a line that's the correct angle offset clockwise from there. If within that area, discard the fragment. (Discarding makes more sense than setting alpha to 0.0 or 1.0 if keeping, right?)
But how can I actually achieve this?? I don't understand how to implement that algorithm in terms of a shader. (I'm using OpenGL ES 2.0)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决这个问题的一种方法是计算
gl_FragCoord
(我希望 ES 2.0 中存在!)和点(必须确保该点位于屏幕坐标中)之间的差异,并使用 atan 函数有两个参数,给你一个角度。如果角度不是您喜欢的某个值(大于最小值且小于最大值),则杀死该碎片。当然,杀死碎片并不是最高效的做法。 (稍微复杂一些)三角形解决方案可能仍然更快。
编辑:
为了更好地解释“不完全是性能最高的事情”,请考虑杀死片段仍然会导致片段着色器运行(它只会在之后丢弃结果)并且干扰早期深度/模板片段拒绝。
像 whoplisp 建议的那样构建三角形扇形需要更多工作,但不会处理任何不可见的片段,不会干扰深度/模板拒绝,并且在某些情况下也可能看起来更好(例如 MSAA)。
One solution to this would be to calculate the difference between
gl_FragCoord
(I hope that exists under ES 2.0!) and the point (must be sure the point is in screen coords) and using the atan function with two parameters, giving you an angle. If the angle is not some value that you like (greater than minimum and less than maximum), kill the fragment.Of course, killing fragments is not precisely the most performant thing to do. A (somewhat more complicated) triangle solution may still be faster.
EDIT:
To better explain "not precisely the most performant thing", consider that killing fragments still causes the fragment shader to run (it only discards the result afterwards) and interferes with early depth/stencil fragment rejection.
Constructing a triangle fan like whoplisp suggested is more work, but will not process any fragments that are not visible, will not interfere with depth/stencil rejection, and may look better in some situations, too (MSAA for example).
为什么不在红色矩形上画一些黑色三角形呢?
Why don't you just draw some black triangles ontop of the red rectangle?