3d 如何在glsl中复制photoshop斜面/浮雕边框效果

3d 如何在glsl中复制photoshop斜面/浮雕边框效果,3d,glsl,shader,fragment-shader,3d,Glsl,Shader,Fragment Shader,我一直试图找到一些关于如何用GLSL着色器复制photoshop斜面效果的信息 我已经找到了一些示例着色器,但我似乎无法理解它。我偶然发现了这个问题, 这达到了预期的效果,但我不知道如何将其转化为着色器 如果您有任何建议,我们将不胜感激。首先,我要警告您,根据您的GPU和所需的质量,这可能会很难安装到着色器中,但您可以尝试一下 我将这个问题分为两个独立的问题: 查找到最近孔的距离和方向 基于距离/方向对像素进行着色 广告1. 您希望找到alpha低于某个阈值的最近像素。测试着色器开

我一直试图找到一些关于如何用GLSL着色器复制photoshop斜面效果的信息

我已经找到了一些示例着色器,但我似乎无法理解它。我偶然发现了这个问题, 这达到了预期的效果,但我不知道如何将其转化为着色器


如果您有任何建议,我们将不胜感激。

首先,我要警告您,根据您的GPU和所需的质量,这可能会很难安装到着色器中,但您可以尝试一下

我将这个问题分为两个独立的问题:

  • 查找到最近孔的距离和方向
  • 基于距离/方向对像素进行着色
广告1.

您希望找到alpha低于某个阈值的最近像素。测试着色器开始的像素,然后测试其邻居(3x3网格,无中心),然后测试其邻居(5x5),依此类推。。。继续此操作,直到找到像素或超出倒角的大小

这是棘手的部分。没有太多的数学运算,但是你有很多纹理读取和
if-else
,这是GPU不喜欢的。当您增加边框大小时,性能下降得非常快。GPU在执行着色器时似乎具有某种“超时”功能,因此,如果时间过长,即使完美工作的GPU也可能会被默默地杀死。这些限制在GPU和/或驱动程序之间可能有所不同,因此很难说在您的机器上运行的代码是否在另一台机器上运行。这很难确定,但可以做到

广告2.

就距离和方向而言,你几乎完成了。如果距离大于边框大小,则当前像素不是边框,否则将方向与某个灯光方向(在示例中位于左上方)进行比较,然后决定边框是亮还是暗。 你也可以使用距离来影响明暗强度,这样你就可以得到圆形的坡度而不是平坦的坡度

所有这些都只是一种最简单的方法。您可以尝试将其拆分为渲染过程、进行一些预计算、缩小纹理比例、将mip贴图用作四叉树等,以加快代码的速度

编辑您的评论:

只要您不打算修改每帧的数据,就可以进行大量的预计算

假设你有一个纹理,你的洞是白色的,其余的是黑色的,你想软化这个图像。您编写一个着色器,对当前像素进行采样(我们称之为
pix
),对其8个相邻像素进行采样并对其进行平均(我们称之为
avg
),然后调用:

result = max( pix, avg );
这样,您将涂抹周围的白色,但决不会使已经是白色的像素变暗。连续运行此着色器几次以获得更大的涂抹。现在,如果你反转颜色,你会得到距离值,对吧:)

(无需反转即可完成,使用
alpha
通道和
min
代替
max
,我只是觉得这种方式更容易描述)

此涂片的形状取决于
avg
值的样本模式。我告诉过你使用3x3网格,但你可以在这里进行实验,使用更多的圆形

此距离值的渐变将为您提供方向


您可以进一步获得并预计算着色数据。可以使用每个像素要添加或删除的值计算纹理。将此纹理打包到0-255范围。然后,在渲染过程中,您可以对该纹理进行采样,从中减去0.5(移动到[-0.5,0.5]范围),然后添加到源纹理。

谢谢您的回答。到目前为止,我只使用了单独的纹理和PS浮雕效果,并用默认着色器渲染它们。但是,假设我使用了你建议的方法。您指出性能可能是一个问题(让我们忽略超时/机器问题)。您是否认为仅使用着色器将一组纹理渲染到屏幕外缓冲区一次,然后重用该缓冲区是可行的选择?(假设渲染的缓冲区不变)。还是在cpu上通过常规编程实现这一点更好?