当物体靠近表面时,如何编写一个可以点亮的着色器?


15

此《守望先锋》游戏视频中,角色的盾牌在其他物体的几何形状附近的区域点亮为白色。

莱因哈特的盾牌修剪了一些关卡

请注意靠近地板,墙壁和支柱的蓝色护罩上的白色边缘。

我相信盾有自己的模型,并且效果是通过着色器完成的,但是我迷失了试图弄清楚如何将“近”的概念转换为着色器编程的想法。


2
如果您使用的是Unity,那么您可能会感兴趣。检查节上的“十字路口亮点”开始幻灯片26
DMGregory

因此,答案已经在下面进行了介绍,但是现在有一段视频对此进行了解释:youtube.com/watch?
v=C6lGEgcHbWc

Answers:


28

概述:

  1. 创建没有屏蔽的场景深度图。您可以免费有效地获得此功能,因为无论如何,透明对象通常是在以后的过程中渲染的。否则,您可以通过使用深度着色器将场景无遮罩渲染到RTT上来创建深度图。

  2. 正常渲染场景,将深度图传递到盾形着色器。

  3. 在着色器中,计算场景深度与屏蔽片段深度之间的差异,并使用该差异修改片段颜色。

演示版

我编写了一个简单的WebGL演示。

演示的屏幕截图

逐行

让我们详细研究片段着色器代码:

float solidsDepth = texture2D(depthMap, gl_FragCoord.xy / dims).r;

在每个片段上采样深度图。请记住除以视口尺寸,将片段从屏幕空间[0,width / height]转换为规范化[0.0,1.0]坐标。此时,如果您仅将片段颜色设置为采样的深度图像素,它将看起来像这样:

深度图的屏幕截图

深度图是灰度的,因此您可以从任何通道获取值(我r在这里使用)。

float solidsDiff = 1.0 - smoothstep(
    zNear,
    zFar,
    gl_FragCoord.z / gl_FragCoord.w
  ) - solidsDepth;

然后,您可以使用该深度样本来查找场景深度和屏蔽片段深度之间的差异。请记住也要标准化深度,以使其从[zNear,zFar](相机的近平面和远平面)到[0.0,1.0]。smoothstep做得很好。的1.0 -是反转这样的值,该值solidsDiff是1.0时的差值为最大(zFar - zNear)在最小(0.0)和0.0。

请注意,我假设solidsDepth已经在创建深度图的深度着色器中对其进行了标准化。

float alpha = 0.3 + max(0.0, 1.0 - log(100.0 * (solidsDiff - 0.005) + 1.0));

然后,您可以根据深度差修改屏蔽的alpha通道。在这里,我们从的最小alpha开始0.3,然后在接近差时创建一个明显的alpha 急剧增加0.0

- 0.005偏移只是增加了一个白色的余量,使“交集”更浓。尝试修改它!

gl_FragColor = vec4(vec3(1.0), alpha);

最后,将该alpha应用于片段颜色。


增强功能

您可以制作一个弯曲的盾牌,添加等离子的“能量盾牌”外观(演示),仅显示交叉点(演示)来探索效果

天空你的显卡是极限!


哦。我的 好消息。请输入真棒教程。
Blue Bug

5

它只是使用深度图。它先渲染世界,然后渲染盾牌,并在盾牌的渲染z值和深度缓冲区z值之间求差,以将像素着色为更白色。


3

我不知道您正在使用哪个引擎(如果有)。或您使用的是哪种语言。不过,您可以在网上找到的大多数内容都很难从一种环境移植到另一种环境以实现您想要的。

当然,在线上也有可以为您提供帮助的材料。请参阅与Unity相关的讨论:http : //www.superspacetrooper.com/2012/06/tutorial-force-field-weapon-impact-energy-dispersion/和与UE4有关的问题:https://answers.unrealengine。 com / questions / 74858 / dynamic-forcefield-shader.html。对于一个完整的着色器例子,执行该屏蔽效应,从reddit的一个相当最近的辩论中,你可以看到:https://www.reddit.com/r/Unity3D/comments/3edi0n/does_any_one_knows_how_to_make_this_shield_effect/ 而对于一个教程,不与此完全相关,但与兴趣相关的程度足够:http//www.nightbox-studios.com/2015/09/05/assets-shield-effect-scripts-for-texture3d-perlin-noise-shader/

另外,以下是此站点上先前提出的3个相关问题的链接,它们可能会对您想要实现的目标背后的概念有很大的帮助:

太空飞船盾牌耀斑

如何在游戏中实现星球大战能量盾

具有原始球体问题的XNA屏蔽效果

最后,如果您碰巧正在使用其中任何一个引擎,则在Unity和Unreal Engine各自的虚拟存储中都有很多不错的盾牌着色器实现。当然,它们通常是有偿资产,但在购买后几乎总是开源的,而且通常很便宜。即使您没有碰巧使用这些引擎,这些资产也可以帮助您游玩和学习。

希望能帮助到你。


尽管这些链接很有帮助,但该答案基本上只是链接,实际上并不能直接解决问题。最好将链接的相关内容提取为实际的解释。
Anko 2015年

尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接的页面发生更改,仅链接的答案可能无效。- 点评来源
Vaillancourt

@Anko当然,我不好。我通常会提供一个解释和一个链接集合,但是这次您是对的,真正的解释丢失了。那我可能会删除答案。
MAnd

@AlexandreVaillancourt我不喜欢仅从另一个链接复制粘贴而不是将OP重定向到原始源的想法。然后,我认为最好的方法是在评论中提供指向该问题的链接。这样做的问题是,当您知道很多可以提供帮助的材料,但是对于评论来说太大了。但是,由于已经在此处发布了一个很好的解释性答案,因此我将只删除该内容
MAnd
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.