后处理SSAO

//C#using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ScreenSpaceAmbientAcclusion : PostProcessBase
{private Camera mainCamera;public Camera camera {get {if(mainCamera == null){mainCamera= GetComponent<Camera>();}return mainCamera;}}public Shader SSAOShader;private Material ssaoMaterial;public Material ssaoMat{get{ssaoMaterial = CheckShaderAndCreateMaterial(SSAOShader, ssaoMaterial); return ssaoMaterial;}}public Shader BlurShader;private Material blurMaterial;public Material blurMat{get{blurMaterial = CheckShaderAndCreateMaterial(BlurShader, blurMaterial); return blurMaterial;}}void OnEnable(){camera.depthTextureMode |= DepthTextureMode.DepthNormals;   }[Range(1,256)]public int SampleCount;[Range(0.01f, 0.5f)]public float SampleRadius;                      //SSAO 相机空间 随机半径最大值。public Color AOColor = new Color(0.0f,0.0f,0.0f);[Range(0.0f, 0.1f)]public float UVOffset;                          //双边模糊采样UV偏移。[Range(0.0f, 1.0f)]public float BilaterFilterFactor;               //法线比较的敏感度,值越大,法线差别对模糊的影响越小。private void OnRenderImage(RenderTexture src, RenderTexture dest){Matrix4x4 cameraProj = camera.projectionMatrix;ssaoMat.SetMatrix("_Matrix_P",cameraProj);ssaoMat.SetMatrix("_Matrix_IP", cameraProj.inverse);         //传入投影矩阵逆矩阵ssaoMat.SetInt("_SampleCount", SampleCount);ssaoMat.SetFloat("_SampleRadius", SampleRadius);ssaoMat.SetColor("_AOColor", AOColor);RenderTexture buffer0 = RenderTexture.GetTemporary(src.width / 2, src.height / 2, 0);       //downsampleRenderTexture buffer1 = RenderTexture.GetTemporary(src.width / 2, src.height / 2, 0);Graphics.Blit(src, buffer0, ssaoMat, 0);blurMat.SetFloat("_UVOffset",UVOffset);              //模糊AO图blurMat.SetFloat("_BilaterFilterFactor",BilaterFilterFactor);Graphics.Blit(buffer0, buffer1, blurMat,0);Graphics.Blit(buffer1, buffer0, blurMat, 1);blurMat.SetTexture("_AoTex", buffer0);                   //与原图叠加Graphics.Blit(src, dest, blurMat, 2);Graphics.Blit(src, dest, blurMat, 2);}
}
//SSAO shaderShader "may/SSAO"
{Properties{_MainTex("Source Tex", 2D) = "white"{}}SubShader{Cull Off ZWrite Off ZTest Alwayspass{Blend OffCGPROGRAM#pragma vertex vert #pragma fragment frag #include "UnityCG.cginc"sampler2D _MainTex;sampler2D _CameraDepthNormalsTexture;   //深度法线图float4x4 _Matrix_IP;    //逆矩阵float4x4 _Matrix_P;int _SampleCount;       //半球采样点数量float _SampleRadius;    //半球半径fixed4 _AOColor;        //ao的颜色,默认黑色struct a2v {float4 vertex:POSITION;float2 uv:TEXCOORD;};struct v2f {float4 pos:SV_POSITION;float2 uv:TEXCOORD;};v2f vert(a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}float RandomFloat(float2 uv)    //随机{return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);}float3 RandomFloat3(float2 uv)  //随机向量  单位随机向量 * [-1,1]{float3 ranVector;ranVector.x = RandomFloat(uv) * 2 - 1;ranVector.y = RandomFloat(uv*uv) * 2 - 1;ranVector.z = RandomFloat(uv*uv*uv) * 2 - 1;return normalize(ranVector);}fixed4 frag(v2f i):SV_TARGET{//重建世界坐标float depthTex =  DecodeFloatRG(tex2D(_CameraDepthNormalsTexture, i.uv).zw);float3 normalVS = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, i.uv));float4 posNDC = float4(i.uv.x * 2 -1, i.uv.y * 2 -1, depthTex * 2 - 1, 1);float4 posVS = mul(_Matrix_IP, posNDC);posVS = posVS / posVS.w;//在观察空间,定义一个切线空间float3 tangentVS = RandomFloat3(i.uv);float3 binormalVS = normalize(cross(tangentVS, normalVS));tangentVS = cross(normalVS, binormalVS);float3x3 ViewSpaceToTangentSpace = {tangentVS, binormalVS, normalVS};float3x3 TangentSpaceToViewSpace = transpose(ViewSpaceToTangentSpace);int count = 0;  // 没被遮挡采样点数for(int k = 0; k < _SampleCount; k++){float3 randomVector = RandomFloat3(i.uv * (k+1) );                              //偏移量,像素的切线空间 ,注意要保证每次循环产生的向量不同(所以乘k)randomVector.z =abs( randomVector.z ) * 0.8 +0.2;                             //切线空间,偏移量,分量范围: [-1, 1], [-1, 1], [0, 1]randomVector = mul(TangentSpaceToViewSpace, randomVector);randomVector *= _SampleRadius;float4 SamplerPointPosVS = posVS + float4(randomVector, 0); //采样点,相机空间float4 SamplerPointPosCS = mul(_Matrix_P, SamplerPointPosVS);float4 SamplerPointPosNDC = SamplerPointPosCS / SamplerPointPosCS.w;float2 SamplerPointUV = (SamplerPointPosNDC.xy + 1) / 2;float Depth = DecodeFloatRG(tex2D(_CameraDepthNormalsTexture, SamplerPointUV).zw);float4 ndc = float4( SamplerPointUV * 2 -1, Depth * 2 - 1,  1);float4 vs = mul(_Matrix_IP, ndc);vs /= vs.w;if( (-vs.z) - (-SamplerPointPosVS.z) > 0 || (-SamplerPointPosVS.z) - (-vs.z) > _SampleRadius )        // 场景深度图的深度  大于  采样点深度(未被遮挡)   或    采样点深度 大于 场景深度 很多(被遮挡,但是是错开的物体){count++;}}//float4 rowTex = tex2D(_MainTex, i.uv);fixed ao= float(count)/_SampleCount;return lerp( _AOColor, fixed4(1, 1, 1, 1), ao);//          (1-ao)*_AOColor + ao * fixed4(1, 1, 1, 1);    ao做出的遮罩 * ao颜色 + 非ao区域 * 白色}ENDCG}}FallBack "Diffuse"
}
//BilateralBlur    //模糊,但保持图像中的边缘信息Shader "may/BilateralBlur"
{Properties{_MainTex ("Albedo (RGB)", 2D) = "white" {}}SubShader{CGINCLUDE#include "UnityCG.cginc"sampler2D _MainTex;sampler2D _AoTex;sampler2D _CameraDepthNormalsTexture;   //深度法线 float4 _AoTex_TexelSize;float _UVOffset;              //uv偏移量, 0 不偏移, 1 偏移量为窗口的宽/高       5x5采样   float _BilaterFilterFactor;struct a2v{float4 vertex:POSITION;float2 uv:TEXCOORD;};struct v2f_blur{float4 pos:SV_POSITION;float2 uv:TEXCOORD;half2 uvOffset:TEXCOORD1;};struct v2f_Add{float4 pos:SV_POSITION;float2 uv:TEXCOORD;};v2f_blur vert_Horizontal(a2v v){v2f_blur o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.uv;o.uvOffset = half2(_UVOffset, 0);return o;}v2f_blur vert_Vertical(a2v v){v2f_blur o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.uv;o.uvOffset = half2(0, _UVOffset);return o;}float CompareNormal(float3 normal0, float3 normal1){return smoothstep(_BilaterFilterFactor, 1.0, dot(normal0, normal1));}fixed4 frag_blur( v2f_blur i):SV_TARGET{half2 UVOffset = i.uvOffset;half2 uv0 = i.uv - 3 * UVOffset;half2 uv1 = i.uv - 2 * UVOffset;half2 uv2 = i.uv - 1 * UVOffset;half2 uv3 = i.uv;half2 uv4 = i.uv + 1 * UVOffset;half2 uv5 = i.uv + 2 * UVOffset;half2 uv6 = i.uv + 3 * UVOffset;fixed4 color0 = tex2D(_MainTex, uv0);fixed4 color1 = tex2D(_MainTex, uv1);fixed4 color2 = tex2D(_MainTex, uv2);fixed4 color3 = tex2D(_MainTex, uv3);fixed4 color4 = tex2D(_MainTex, uv4);fixed4 color5 = tex2D(_MainTex, uv5);fixed4 color6 = tex2D(_MainTex, uv6);float3 normal0 = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, uv0));float3 normal1 = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, uv1));float3 normal2 = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, uv2));float3 normal3 = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, uv3));float3 normal4 = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, uv4));float3 normal5 = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, uv5));float3 normal6 = DecodeViewNormalStereo(tex2D(_CameraDepthNormalsTexture, uv6));fixed weight0 = CompareNormal(normal3, normal0) * 0.11453744493;fixed weight1 = CompareNormal(normal3, normal1) * 0.19823788546;fixed weight2 = CompareNormal(normal3, normal2) * 0.31718061674;fixed weight3 = 0.37004405286;fixed weight4 = CompareNormal(normal3, normal4) * 0.31718061674;fixed weight5 = CompareNormal(normal3, normal5) * 0.19823788546;fixed weight6 = CompareNormal(normal3, normal6) * 0.11453744493;fixed weight = weight0 + weight1 + weight2 + weight3 + weight4 + weight5 + weight6;fixed4 blurColor = fixed4(0,0,0,0);blurColor += color0 * weight0;blurColor += color1 * weight1;blurColor += color2 * weight2;blurColor += color3 * weight3;blurColor += color4 * weight4;blurColor += color5 * weight5;blurColor += color6 * weight6;//return color5;return blurColor /weight;}v2f_Add vert_Add(a2v v){v2f_Add o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}fixed4 frag_Add( v2f_Add i):SV_TARGET{fixed4 src = tex2D(_MainTex, i.uv);         //原图fixed4 bluredAO = tex2D(_AoTex, i.uv);      //模糊后的AO;return src * bluredAO;}ENDCGZWrite Off ZTest Always Cull Off pass {CGPROGRAM#pragma vertex vert_Horizontal#pragma fragment frag_blurENDCG}pass {CGPROGRAM#pragma vertex vert_Vertical#pragma fragment frag_blurENDCG}pass {CGPROGRAM#pragma vertex vert_Add#pragma fragment frag_AddENDCG}}FallBack "Diffuse"
}

SSAO,HBAO,GTAO

后处理SSAO,双边模糊相关推荐

  1. 模糊处理(下)--高斯模糊,双边模糊以及实现一个简单的磨皮美颜效果(opencv学习记录--4)

    文章目录 1.高斯模糊 1.什么是高斯模糊 2.opencv提供的API 2.双边模糊 1.什么是双边模糊 2.opencv的API 3.磨皮美颜效果的实现 1.实现过程 2.主要代码 3.效果 参考 ...

  2. Python-opencv学习第二十九课:高斯双边模糊

    Python-opencv学习第二十九课:高斯双边模糊 文章目录 Python-opencv学习第二十九课:高斯双边模糊 一.学习部分 二.代码部分 1.引入库 2.读入数据 3.完整代码 三.运行结 ...

  3. OpenCV(C++版本)基础相关(7):直方图均衡化、图像卷积操作、高斯模糊、高斯双边模糊、实时人脸检测案例

    文章目录 二十六.直方图均衡化 26.1 quickopencv.h 26.2 QuickDemo.cpp 26.3 test.cpp 二十七.图像卷积操作 27.1 quickopencv.h 27 ...

  4. 高斯双边模糊_OpenCV 学习:9 双边滤波bilateralFilter

    1 什么是双边滤波? 双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的.具有简单 ...

  5. 【OpenCv】图像模糊(均值模糊,高斯模糊,中值模糊,双边模糊)

    原理: 图像模糊又称为图像平滑,是图像处理中最简单和常用的操作之一,使用该操作就是为了给图像降低噪音.图像模糊处理包括:高斯模糊.均值滤波.中值滤波.双边滤波等.模糊滤波其实就是图像的卷积计算,通常这 ...

  6. OpenCV--028:高斯双边模糊

    双边滤波 双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的.具有简单.非迭代.局 ...

  7. 【Unity Shader】屏幕后处理3.0:均值模糊和高斯模糊

    发现之前学习记录的太过详细,导致整理的过程占用太长的时间了,这篇之后博客重要的是掌握实现过程,关于基础的理论会更多的放上别人写得更好的文章. 参考:[Unity Shader编程]之十五 屏幕高斯模糊 ...

  8. open cv均值 中值 高斯 双边高斯 滤波及模糊

    /* 模糊与消噪 模糊原理(线性滤波) ●Smooth/Blur 是图像处理中最简单和常用的操作之一 ●使用该操作的原因之一-就为了给图像预处理时候减低噪声 ●使用Smooth/Blur操作其背后是数 ...

  9. UnityShader-BilateralFilter(双边滤波,磨皮滤镜)

    前言 最近趁着Steam打折入了好多个游戏,昨天刚刚通关了一个<Ruiner>的游戏. 游戏类似<孤胆枪手>,但是加入了很多技能元素和动作元素,加上游戏本身的卡通渲染+赛博朋克 ...

最新文章

  1. 使用antd UI组件有感
  2. python程序代码大全-调试Python程序代码的几种方法总结
  3. linux用户操作的日志,linux 用户操作记录并录入日志
  4. 详解GPU技术关键参数和应用场景
  5. 【今日CS 视觉论文速览】Thu, 13 Dec 2018
  6. kafka是如何解决粘包拆包的
  7. Linux之HugePages快速配置
  8. HTML元素 - input type=hidden
  9. 苹果面临5G困境!向三星采购碰壁 高通表态:苹果有我们电话
  10. 精致的App登录页设计欣赏给你灵感
  11. 如何快速演变XMind文件
  12. python 变量赋值变成元组
  13. request.GetResponse()超时的解决办法
  14. SAS Planet软件介绍与使用教程
  15. 如何将1080P的腾讯视频QLV格式转换成MP4视频呢
  16. 即时聊天通讯软件安卓+ios双端原生源码
  17. Holt Winter 指数平滑模型
  18. Linux-Ubuntu-4-软件安装
  19. oracle中与归档相关的视图,Oracle OWI 等待事件历史视图及相关视图 - 一沙弥的世界...
  20. 带你认识什么是一级指针、二级指针、三级指针

热门文章

  1. GB2312和BIG5,Unicode/UTF8等编码之间的互相转化
  2. 火狐浏览器书签工具栏图标_在Firefox书签工具栏中浓缩书签
  3. android中用点标识路径,Android Bitmap、路径、图片加上文本水印
  4. nexus在docker安装nexus与初始密码问题
  5. (四)Android中的TextView组件
  6. escape在sql语句中的作用
  7. 第六次网页前端培训笔记(JavaScript)
  8. 深入讲解Android!最全的BAT大厂面试题整理,威力加强版
  9. 线性代数(四)-矩阵分块法
  10. 成熟港口人工智能Ceaspectus领跑全球智能港口码头人工智能应用落地,全球No.1集装箱AI企业中集飞瞳建设智慧港口智能码头