UE4中低成本的折射效果
想做个水晶材质, 网上搜了搜, 一些是长这样的:
另一些是长这样的:
都不满意.
如果直接拿做玻璃的做法(Translucent+SurfaceForwardShading), 会有半透明排序问题, 为了解决这个问题还要再加个CustomDepth, 性能不用说了全是泪
正常的水晶应该是类似毛玻璃的效果, 表面光滑强反射, 内部因为杂质会影响透光率, 另外还有折射. 比如这个光追版本的:
恰巧在twitter上看到一个TA做了个"不透明的透明效果"
https://www.zhihu.com/video/1178043435621171200他的Blog上放了个Demo, 还是挺惊艳的
这个采样ReflectionProbe来模拟折射的思路挺好玩, 后来才想起来ARM之前也出一个类似的Demo (Ice Cave):
总结一下就是:
- 通过采样local cubemap来模拟光线穿过半透明材质的折射效果
- 通过采样local cubemap mipmap来模似毛玻璃效果(类似PBR Roughness)
- 模型实际上还是opaque的, 所以不存在透明材质的缺点(排序, 性能等)
- 性能开销低, 因为就是采样个cubemap
- 比较适合折射率高的物体, 因为这就是个近似, 数学上来说是不正确的
- 在UE4中可以复用场景中的ReflectionProbe, 所以使用起来很方便
第一步, 加个CustomShadingModel, 参考
把计算环境反射的R向量修改成CameraToPixel:
不透明物体变"透明"了, 通过物体看到了ReflectionProbe的Cubemap, 因为分辨率比较低(默认128可以修改分辨率), 所以都是模糊的. 可以看到跟实际位置是有偏差的, 所以前面也提了为什么适合折射率高的物体. 参考这篇文章加入光线折射算法:
float IOR = GBuffer.CustomData.x;
float t = lerp(0.225, IOR, dot(N, V));
R = lerp(CameraToPixel, -N, t);
R = normalize(R);
基本的折射效果有了, 但是像玻璃不光是有折射的, 还有反射效果, 所以这里需要两层的环境采样, 类似ClearCoat材质, 那就照着它的Shading来一遍:
中间踩了个坑, Mesh和Material窗口都有奇怪的黑色, 主场景里没有:
RenderDoc查明是DFAO造成的, 关掉就好了:
边缘还有些错误的反射, 再把SSR干掉:
效果终于是那么回事了, 放到场景里:
嗯? 影子不太对劲, 再做个假的半透明阴影(使用Mask Dither):
最终效果:
https://www.zhihu.com/video/1178053520354504704BaseColor调成绿色时怎么看怎么觉得亲切, 后来才想起来, 原来是这样...