当前位置:   article > 正文

【Unity】运用CommandBuffer实现发光特效_unity发光效果

unity发光效果

首先看下效果:

 我们想要实现以下效果:

  • 发光物体边缘模拟丁达尔效应,产生光芒。
  • 可以被其它物体遮挡。
  • 任意形状物体都可以产生以上效果。

首先确定实现的思路:

1、将发光物体单独绘制一遍,并计算在环境中的遮挡,剔除被遮挡的像素,保存绘制后的纹理

2、将发光物体单独绘制后的纹理,添加模糊效果,并向外扩散。

3、将模糊处理后的纹理,与相机渲染的纹理进行叠加,形成最终的效果。

第一步:

如何将发光的物体单独绘制一遍并保存纹理?这时候就用到Unity中的CommandBuffer了。CommandBuffer可以简单理解为:创建一系列渲染指令,然后在某个阶段执行这些渲染指令。网上有很多相关的教程和案例,在这就不细说了。

我们用CommanBuffer将发光物体全都绘制一遍,然后渲染到一个RenderTexture上:

  1. /// <summary>
  2. /// 绘制需要有模糊效果的物体
  3. /// </summary>
  4. void DrawObjects()
  5. {
  6. drawObjsCmd = new CommandBuffer();
  7. drawObjsCmd.name = "绘制发光物体";
  8. //绘制到一个RenderTexture上
  9. drawObjsCmd.SetRenderTarget(colorTexture);
  10. drawObjsCmd.ClearRenderTarget(true, true, Color.clear);
  11. //绘制所有发光物体
  12. foreach (var item in renderers)
  13. {
  14. if (!item.enabled)
  15. continue;
  16. //设置材质球参数
  17. var colorMat = new Material(postRenderColor);
  18. colorMat.SetFloat("_Scale", item.scale);
  19. colorMat.SetColor("_Color", item.color);
  20. drawObjsCmd.DrawRenderer(item.meshRenderer, colorMat, 0, 0);
  21. }
  22. //执行CommandBuffer
  23. Graphics.ExecuteCommandBuffer(drawObjsCmd);
  24. }

postRenderColor这个shader,具有绘制纯色,并根据深度图计算遮挡关系的功能。

单独绘制发光物体

第二步:模糊效果

关于模糊效果,我们一般采用高斯模糊,关于高斯模糊,本文也不多做细说,网上相关文章也很多,我们直接拿来用即可。但是需要注意的是,为了保证效果,我们可能会对纹理进行多次采样,这时就要注意性能和效果间的平衡。

模糊处理这步,我们单独用一个CommandBuffer进行处理:

  1. /// <summary>
  2. /// 模糊效果
  3. /// </summary>
  4. private void AddGlowCommand()
  5. {
  6. blurCmd = new CommandBuffer();
  7. blurCmd.name = "模糊处理";
  8. //创建一个纹理,用于绘制模糊效果
  9. int temp = Shader.PropertyToID("_TempImage");
  10. blurCmd.GetTemporaryRT(temp, -1, -1, 0, FilterMode.Bilinear);
  11. float dir = 1;
  12. for (int i = 0; i < samplingIteration; i++)
  13. {
  14. //竖向采样一次
  15. blurCmd.SetGlobalVector("_Dir", new Vector4(0, dir, 0, 0));
  16. blurCmd.Blit(colorTexture, temp, blurMat);
  17. //横向采样一次
  18. blurCmd.SetGlobalVector("_Dir", new Vector4(dir, 0, 0, 0));
  19. blurCmd.Blit(temp, colorTexture, blurMat);
  20. //每次采样后,扩展一次模糊中的采样距离,这样效果会更好
  21. dir += glowAdd;
  22. }
  23. blurCmd.SetGlobalTexture("_AddTex", colorTexture);
  24. cam.AddCommandBuffer(CameraEvent.BeforeImageEffects, blurCmd);
  25. }

模糊效果

第三步:叠加

到这里,就快大功告成了,只需通过shader的叠加算法,将相机渲染出的纹理和我们前面模糊处理后的纹理叠加即可:

  1. //shader中的叠加算法
  2. float4 blend(float4 main, float4 add)
  3. {
  4. float4 color = float4(0, 0, 0, 1);
  5. float l = max(max(main.r, main.g), main.b);
  6. color.r = main.r*(1 - add.a*saturate(main.r - add.a)) + add.r;
  7. color.g = main.g*(1 - add.a*saturate(main.g - add.a)) + add.g;
  8. color.b = main.b*(1 - add.a*saturate(main.b - add.a)) + add.b;
  9. return color;
  10. }

 这里我只用了我认为比较好的叠加算法,如果你有更好的算法的话,希望可以留言交流一下。

处理前效果

处理后效果

 最后,附上github链接:GitHub - liuyima/UnityGlow: 发光物体特效

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/114593
推荐阅读
相关标签
  

闽ICP备14008679号