在此《守望先锋》游戏视频中,角色的盾牌在其他物体的几何形状附近的区域点亮为白色。
请注意靠近地板,墙壁和支柱的蓝色护罩上的白色边缘。
我相信盾有自己的模型,并且效果是通过着色器完成的,但是我迷失了试图弄清楚如何将“近”的概念转换为着色器编程的想法。
在此《守望先锋》游戏视频中,角色的盾牌在其他物体的几何形状附近的区域点亮为白色。
请注意靠近地板,墙壁和支柱的蓝色护罩上的白色边缘。
我相信盾有自己的模型,并且效果是通过着色器完成的,但是我迷失了试图弄清楚如何将“近”的概念转换为着色器编程的想法。
Answers:
概述:
创建没有屏蔽的场景深度图。您可以免费有效地获得此功能,因为无论如何,透明对象通常是在以后的过程中渲染的。否则,您可以通过使用深度着色器将场景无遮罩渲染到RTT上来创建深度图。
正常渲染场景,将深度图传递到盾形着色器。
在着色器中,计算场景深度与屏蔽片段深度之间的差异,并使用该差异修改片段颜色。
让我们详细研究片段着色器代码:
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应用于片段颜色。
您可以制作一个弯曲的盾牌,添加等离子的“能量盾牌”外观(演示),或仅显示交叉点(演示)来探索效果。
天空你的显卡是极限!
我不知道您正在使用哪个引擎(如果有)。或您使用的是哪种语言。不过,您可以在网上找到的大多数内容都很难从一种环境移植到另一种环境以实现您想要的。
当然,在线上也有可以为您提供帮助的材料。请参阅与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个相关问题的链接,它们可能会对您想要实现的目标背后的概念有很大的帮助:
最后,如果您碰巧正在使用其中任何一个引擎,则在Unity和Unreal Engine各自的虚拟存储中都有很多不错的盾牌着色器实现。当然,它们通常是有偿资产,但在购买后几乎总是开源的,而且通常很便宜。即使您没有碰巧使用这些引擎,这些资产也可以帮助您游玩和学习。
希望能帮助到你。