Unity Shader学习:SSAO屏幕环境光遮蔽

主要思路:1.随机采样像素法线半球周围的像素,平均对比与该像素深度是否处在暗处。2.双边滤波去噪点。3.后期AO图与原图混合。

原文链接:https://blog.csdn.net/puppet_master/article/details/82929708


无AO


有AO


AO图

c#部分:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SSAO : MonoBehaviour {public Material SSAOMaterial;private List<Vector4> sampleKernelList = new List<Vector4>();[Range(0f, 0.002f)]public float depthBiasValue = 0f;[Range(0.01f, 1f)]public float sampleKernelRadius = 1.0f;[Range(4,32)]public int sampleKernelCount = 16;[Range(0.0f, 5.0f)]public float AOStrength = 1.0f;[Range(0, 2)]public int downSample = 0;[Range(1, 4)]public int blurRadius = 1;[Range(0f, 0.2f)]public float bilateralFilterStrength = 0.2f;public bool onlyShowAO = false;public enum SSAOPassName{GenerateAO=0,BilateralFilter=1,Composite=2}private Camera currentCamera;void Start () {currentCamera = Camera.main;currentCamera.depthTextureMode = DepthTextureMode.DepthNormals;}private void OnRenderImage(RenderTexture source, RenderTexture destination){//采样点生成GenerateAOSampleKernel();RenderTexture aoRT = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0);SSAOMaterial.SetMatrix("_InverseProjectionMatrix", currentCamera.projectionMatrix.inverse);SSAOMaterial.SetFloat("_DepthBiasValue", depthBiasValue);SSAOMaterial.SetVectorArray("_SampleKernelArray", sampleKernelList.ToArray());SSAOMaterial.SetFloat("_SampleKernelCount", sampleKernelList.Count);SSAOMaterial.SetFloat("_AOStrength", AOStrength);SSAOMaterial.SetFloat("_SampleKernelRadius", sampleKernelRadius);Graphics.Blit(source, aoRT, SSAOMaterial, (int)SSAOPassName.GenerateAO);RenderTexture blurRT = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0);SSAOMaterial.SetFloat("_BilaterFilterFactor", 1.0f - bilateralFilterStrength);SSAOMaterial.SetVector("_BlurRadius", new Vector4(blurRadius, 0, 0, 0));Graphics.Blit(aoRT, blurRT, SSAOMaterial, (int)SSAOPassName.BilateralFilter);SSAOMaterial.SetVector("_BlurRadius", new Vector4(0, blurRadius, 0, 0));if (onlyShowAO){Graphics.Blit(blurRT, destination, SSAOMaterial, (int)SSAOPassName.BilateralFilter);}else{Graphics.Blit(blurRT, aoRT, SSAOMaterial, (int)SSAOPassName.BilateralFilter);SSAOMaterial.SetTexture("_AOTex", aoRT);Graphics.Blit(source, destination, SSAOMaterial, (int)SSAOPassName.Composite);}RenderTexture.ReleaseTemporary(aoRT);RenderTexture.ReleaseTemporary(blurRT);}private void GenerateAOSampleKernel(){if (sampleKernelCount==sampleKernelList.Count){return;}sampleKernelList.Clear();for (int i = 0; i < sampleKernelCount; i++){Vector4 vec = new Vector4(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f), 1f);vec.Normalize();float scale = ((float)i) / sampleKernelCount;//调整分布的曲线scale = Mathf.Lerp(0.01f, 1.0f, scale * scale);vec *= scale;sampleKernelList.Add(vec);}}
}

shader部分:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SSAO : MonoBehaviour {public Material SSAOMaterial;private List<Vector4> sampleKernelList = new List<Vector4>();[Range(0f, 0.002f)]public float depthBiasValue = 0f;[Range(0.01f, 1f)]public float sampleKernelRadius = 1.0f;[Range(4,32)]public int sampleKernelCount = 16;[Range(0.0f, 5.0f)]public float AOStrength = 1.0f;[Range(0, 2)]public int downSample = 0;[Range(1, 4)]public int blurRadius = 1;[Range(0f, 0.2f)]public float bilateralFilterStrength = 0.2f;public bool onlyShowAO = false;public enum SSAOPassName{GenerateAO=0,BilateralFilter=1,Composite=2}private Camera currentCamera;void Start () {currentCamera = Camera.main;currentCamera.depthTextureMode = DepthTextureMode.DepthNormals;}private void OnRenderImage(RenderTexture source, RenderTexture destination){//采样点生成GenerateAOSampleKernel();RenderTexture aoRT = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0);SSAOMaterial.SetMatrix("_InverseProjectionMatrix", currentCamera.projectionMatrix.inverse);SSAOMaterial.SetFloat("_DepthBiasValue", depthBiasValue);SSAOMaterial.SetVectorArray("_SampleKernelArray", sampleKernelList.ToArray());SSAOMaterial.SetFloat("_SampleKernelCount", sampleKernelList.Count);SSAOMaterial.SetFloat("_AOStrength", AOStrength);SSAOMaterial.SetFloat("_SampleKernelRadius", sampleKernelRadius);Graphics.Blit(source, aoRT, SSAOMaterial, (int)SSAOPassName.GenerateAO);RenderTexture blurRT = RenderTexture.GetTemporary(source.width >> downSample, source.height >> downSample, 0);SSAOMaterial.SetFloat("_BilaterFilterFactor", 1.0f - bilateralFilterStrength);SSAOMaterial.SetVector("_BlurRadius", new Vector4(blurRadius, 0, 0, 0));Graphics.Blit(aoRT, blurRT, SSAOMaterial, (int)SSAOPassName.BilateralFilter);SSAOMaterial.SetVector("_BlurRadius", new Vector4(0, blurRadius, 0, 0));if (onlyShowAO){Graphics.Blit(blurRT, destination, SSAOMaterial, (int)SSAOPassName.BilateralFilter);}else{Graphics.Blit(blurRT, aoRT, SSAOMaterial, (int)SSAOPassName.BilateralFilter);SSAOMaterial.SetTexture("_AOTex", aoRT);Graphics.Blit(source, destination, SSAOMaterial, (int)SSAOPassName.Composite);}RenderTexture.ReleaseTemporary(aoRT);RenderTexture.ReleaseTemporary(blurRT);}private void GenerateAOSampleKernel(){if (sampleKernelCount==sampleKernelList.Count){return;}sampleKernelList.Clear();for (int i = 0; i < sampleKernelCount; i++){Vector4 vec = new Vector4(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f), 1f);vec.Normalize();float scale = ((float)i) / sampleKernelCount;//调整分布的曲线scale = Mathf.Lerp(0.01f, 1.0f, scale * scale);vec *= scale;sampleKernelList.Add(vec);}}
}

Unity Shader学习:SSAO屏幕环境光遮蔽相关推荐

  1. Unity shader学习之屏幕后期处理效果之高斯模糊

    高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...

  2. Unity Shader学习:SSR屏幕空间反射

    Unity Shader学习:SSR屏幕空间反射 本文在前向渲染模式下实现,延迟渲染更适合SSR,这里只简单的实现下,未作更深入的优化. 思路:沿视线和法线的反射向量步进光线,判断打到物体(这里用的是 ...

  3. Unity Shader 学习笔记(33) 全局光照(GI)、反射探针、线性空间和伽马空间、高动态范围(HDR)

    Unity Shader 学习笔记(33) 全局光照(GI).反射探针.线性空间和伽马空间.高动态范围(HDR) 参考书籍:<Unity Shader 入门精要> [<Real-Ti ...

  4. Unity Shader学习:动态模糊(shutter angle方式)

    Unity Shader学习:动态模糊 动态模糊一般有帧混合和motion vector两种,这里主要介绍motion vector的方法. Keijiro源码:https://github.com/ ...

  5. Unity Shader学习:水墨效果

    Unity Shader学习:水墨效果 偶然在网上看到9级铁甲蛹大神的水墨风格后处理觉得挺有意思,参照着实现一下,还是涉及到之前油画效果的算法,叫什么滤波暂时不清楚,应该用来处理手绘效果挺多的. 水墨 ...

  6. 《Unity Shader入门精要》学习笔记第5章 开始Unity Shader学习之旅

    本文章用于帮助自己学习,因此只记录一些个人认为比较重要或者还不够熟悉的内容. 原作者:http://blog.csdn.net/candycat1992/article/ 第五章 开始Unity Sh ...

  7. Unity Shader学习:动态雾

    Unity Shader学习:动态雾 先将相机近裁面四个角向量传给shader,再通过观察空间下的深度值和相机位置算出像素在世界坐标系的位置,通过世界空间高度值来设定雾的范围和浓度,然后通过噪声和uv ...

  8. Unity Shader学习:油画效果

    Unity Shader学习:油画效果 油画效果在学习浅墨大神的文章时看到的比较有趣,但是原文中也没详细的算法介绍如何实现,这里就先直接拿来用吧,UI和屏幕后处理都可以用,算法也看的不是很明白,好像是 ...

  9. Unity Shader学习-高光反射

    Unity Shader学习-高光反射 高光反射计算公式 高光反射 = 光源的色彩和强度 * 材质的高光反射系数 * pow(max(0,视角方向 · 反射方向),_Gloss) 视角方向 = ref ...

最新文章

  1. MATLAB判断三角形成立的编程,Triangulation 划分三角形网络时用到的大量算法和测试例程 matlab 259万源代码下载- www.pudn.com...
  2. 在实习面试的过程的当中,常见的面试题(自己面试一路走来,所出现的频率较高的面试题总结)
  3. 将AI落地到福州、贵阳的「幕后推手」,到底在想些什么?
  4. Mysql查看某个表大小
  5. Linux Kernel 5.8 发布,华为内核代码贡献全球持续领先
  6. C++ Struct和Union区别
  7. mysql5.5函数大全_mysql 函数大全
  8. 游戏必备组件_电脑必备软件~强大到~ 相识恨晚的感觉
  9. ZYNQ 实现IEEE1588方法
  10. 高斯滤波(Gauss filtering)
  11. 矩阵乘法求导计算公式推导
  12. Ubuntu设置快捷键截图
  13. Star Way To Heaven 题解
  14. 嵌入式开发需要学mysql吗_学习嵌入式开发需要学习哪些课程?如何学习?
  15. Android关于安兔兔手机信息造假的问题。
  16. プログラム・ライブラリ
  17. 阿里云漏洞敏捷管理自动化报告
  18. 基于SpringBoot视频学习系统|视频点播系统的设计与实现【Java毕业设计·安装调试·代码讲解·文档报告】
  19. HDU 2112-HDU Today
  20. Mahout(机器学习引擎)

热门文章

  1. 练手小项目(1)——智能聊天机器人
  2. 如何使用python编程抢京东优惠券 知乎_学好Python爬取京东知乎价值数据
  3. 微信小程序漏洞:可下载任意微信小游戏源代码
  4. win32根据进程名获取进程ID或者终止进程
  5. 一文搞懂马尔可夫链 (Markov Chain)
  6. 程序员的数学——傅里叶变换
  7. 配置全面升级!骨传导耳机机皇——南卡Runner Pro 4新发布!
  8. 【JavaSE】逻辑控制
  9. 树莓派之老的方式重刷Raspbian系统-2015
  10. python tkinter Entry的使用