折射玻璃着色器


10

我有一个无限的六边形地板,是通过在镶嵌细分着色器对中镶嵌点网格生成的:

在此处输入图片说明

请注意,这是一个扁平的线框-“阴影”是一种照明技巧:

在此处输入图片说明

现在,我想使它看起来像是厚的折射玻璃,但是不确定如何进行。

我想到的第一件事是

  1. 设置包含所请求的“厚度”块的制服
  2. 在计算光照时,请使用斯涅尔定律来计算光线穿过十六进制块的光程长度(如果实际上与“厚度”制服说的一样厚),并求和该长度上的alpha。这样可以提高透明度,但不能处理内部反射/ TIR等问题。

在此处输入图片说明

我还没有尝试过,所以我不确定视觉效果如何。

最终,对于这个特定级别,我试图在光盘战役中使用《 Tron:Legacy》中使用的六角形玻璃地板外观。(有关示例,请参见此图像。)

有什么建议吗?


1
您能否进一步说明您要达到的目标?Tron镜头主要显示反射,AFAICT而不是折射-在大多数镜头中您无法真正看透地板。假设您不只是想要一个发亮的表面,还想从地板上看到什么?您要显示一个底层地板纹理吗?地板下是否有整个场景(例如在Tron中)?还是您希望它更像磨砂玻璃,在其中看不到清晰的图像,但具有次表面散射效果?
内森·里德

地下散射,尽管我不知道这就是所谓的。使谷歌搜索更容易。:)
3Dave 2014年

Answers:


4

GPU Gems中的这篇文章深入探讨了折射,可以给出非常不错的结果

(a)完全透明(b)反射玻璃

从最基本的意义上讲

基本折射技术的第一步是将场景几何图形渲染为纹理,跳过所有折射网格。该纹理可用于确定哪些对象在折射对象后面可见,这些对象将在后续遍中渲染。我们将此纹理表示为S。

第二步是渲染折射网格,从纹理S中查找值,并应用一个摄动来模拟折射外观。可以使用法线贴图N来实现摄动,其中使用了法线贴图的红色和绿色(XY)分量并将其缩放一些小值,以将位移添加到投影的纹理坐标中。这种方法很容易在着色器中实现:

  1. 获取纹理N
  2. 使用按较小值(例如0.05)缩放的XY分量
  3. 将此位移值添加到S的投影纹理坐标中

下面的清单显示了演示此方法的着色器

half4 main(float2 bumpUV : TEXCOORD0,
  float4 screenPos : TEXCOORD1,
  uniform sampler2D tex0,
  uniform sampler2D tex1,
  uniform float4 vScale) : COLOR
{
  // fetch bump texture, unpack from [0..1] to [-1..1]
  half4 bumpTex=2.0 * tex2D(tex0, bumpUV.xy) - 1.0;

  // displace texture coordinates    
  half2 newUV = (screenPos.xy/screenPos.w) + bumpTex.xy * vScale.xy;

  // fetch refraction map
  return tex2D(tex1, newUV);
}

下图说明了这三个步骤

上面的着色器中列出的三个步骤

同一篇文章中有更先进的技术,可以使外观更具吸引力


为了在Unity中获得类似的效果,您可能需要看看The Refraction Shader Wiki页面


3

我将以您显示的图像作为我如何想象效果的参考。我能想到的算法很简单:

  1. 将环境渲染为立方体贴图纹理,以模拟环境反射。
  2. 将立方体贴图纹理应用到一个平面,该平面表示折射地板下的图层。不要渲染飞机。
  3. 将平面渲染为纹理,即普通2D纹理。
  4. 将纹理传递到用于渲染折射底面的折射着色器。
  5. 现在使用折射着色器渲染折射网格物体/地板。

关于折射着色器,为了模拟您可以做的玻璃

  • 使用菲涅耳项可以模拟反射和折射。
  • 使用法线/法线贴图进行纹理提取。

我只是想到了这个主意,因此没有进行测试。我确信它需要做更多的工作,也许下班后我会做。


有趣的方法-我必须在那上面炖一会儿。感谢您的输入。
3Dave
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.