• unity之背景高斯模糊


     1 local RenderTexture = CS.UnityEngine.RenderTexture
     2 local Rect =CS.UnityEngine.Rect
     3 local Screen =CS.UnityEngine.Screen
     4 local Texture2D = CS.UnityEngine.Texture2D
     5 local TextureFormat = CS.UnityEngine.TextureFormat
     6 local GaussianBlurBg = {}
     7 
     8 --主要思路:从屏幕读取像素 保存在texture2d中
     9 --核心API:texture2d:ReadPixels(renderWidth, renderHeight, TextureFormat.RGB24, false, true)
    10 
    11 ---输出图片
    12 GaussianBlurBg.ExportTexture = function()
    13     local cameraArr = GaussianBlurBg.GetCurrCamera()    
    14     local renderWidth,renderHeight = GaussianBlurBg.DrawingSize()
    15     return GaussianBlurBg.ScreenCapture(cameraArr,renderWidth,renderHeight)
    16 end
    17 
    18 --获取相机组
    19 GaussianBlurBg.GetCurrCamera = function()
    20     local cameraArr = {}
    21     local UIMgrIns = UIManager:Instance()
    22     table.insert(cameraArr, UIMgrIns.UICamera)
    23     table.insert(cameraArr, UIMgrIns.MainCamera)
    24     return cameraArr
    25 end
    26 
    27 --算出渲染大小
    28 GaussianBlurBg.DrawingSize = function()    
    29     --高宽比
    30     local proportion = (Screen.height * 1.0 / Screen.width)
    31     --乘以0.1 是为了更小 
    32     local renderWidth = math.min(100,math.ceil(Screen.width * 0.1))
    33     --乘以高宽比是为了与原比例一致
    34     local renderHeight = math.ceil(renderWidth * proportion)
    35     return renderWidth,renderHeight
    36 end
    37 
    38 --屏幕读取像素渲染到一张图片上
    39 GaussianBlurBg.ScreenCapture = function(cameraArr,renderWidth,renderHeight)
    40     if cameraArr == nil or #cameraArr == nil then return nil end
    41     local camerList,cameraMap,oldTargetTexture = {},{},{}
    42     for _, v in pairs(cameraArr) do
    43         if not IsNull(v) and cameraMap[v] == nil then
    44             cameraMap[v] = v
    45             table.insert(camerList, v)
    46         end
    47     end
    48     if #camerList <= 0 then return nil end
    49     if type(renderWidth) ~= "number" or renderWidth <= 0 then renderWidth = 100 end
    50     if type(renderHeight) ~= "number" or renderHeight <= 0 then renderHeight = 100 end
    51     local renderTex = RenderTexture.GetTemporary(renderWidth, renderHeight, 0)
    52     --缓存原先的渲染相机及渲染目标
    53     for _, came in pairs(camerList) do        
    54         if not IsNull(came) and came.gameObject.activeSelf then
    55             table.insert(oldTargetTexture, { came = came, targetTexture = came.targetTexture })
    56             came.targetTexture = renderTex
    57             came:Render()
    58         end
    59     end
    60     RenderTexture.active = renderTex
    61     local _tex = Texture2D(renderWidth, renderHeight, TextureFormat.RGB24, false, true)
    62     _tex:ReadPixels(Rect(0, 0, renderWidth, renderHeight), 0, 0)
    63     _tex:Apply(false, false)
    64     --要还原 否则丢失渲染目标
    65     for _, v in pairs(oldTargetTexture) do
    66         if not IsNull(v.came) then
    67             v.came.targetTexture = v.targetTexture
    68         end
    69     end
    70     RenderTexture.active = nil
    71     RenderTexture.ReleaseTemporary(renderTex)
    72     return _tex
    73 end
    74 
    75 exports.GaussianBlurBg = GaussianBlurBg
    76 return GaussianBlurBg

    模糊 shader

      1 Shader "Effect/ImageBlur"
      2 {
      3     Properties
      4     {
      5         _MainTex("Texture", 2D) = "white" {}
      6         //ugui mask
      7         [HideInInspector]_StencilComp("Stencil Comparison", Float) = 8
      8         [HideInInspector]_Stencil("Stencil ID", Float) = 0
      9         [HideInInspector]_StencilOp("Stencil Operation", Float) = 0
     10         [HideInInspector]_StencilWriteMask("Stencil Write Mask", Float) = 255
     11         [HideInInspector]_StencilReadMask("Stencil Read Mask", Float) = 255
     12         [HideInInspector]_ColorMask("Color Mask", Float) = 15
     13         //================================================================================
     14         _BlurSize("Blur Size", Float) = 2
     15         _Brightness("Brightness", Float) = 1    //调整亮度
     16         _Saturation("Saturation", Float) = 1    //调整饱和度
     17         _Contrast("Contrast", Float) = 1        //调整对比度
     18     }
     19 
     20         CGINCLUDE
     21 
     22 #include "UnityCG.cginc"
     23 
     24         sampler2D _MainTex;
     25         uniform half4 _MainTex_TexelSize;
     26         uniform float _BlurSize;
     27         half _Brightness;
     28         half _Saturation;
     29         half _Contrast;
     30 
     31         static const half weight[4] = { 0.0205, 0.0855, 0.232, 0.324 };
     32         static const half4 coordOffset = half4(1.0h, 1.0h, -1.0h, -1.0h);
     33 
     34         struct appdata_t
     35         {
     36             float4 vertex   : POSITION;
     37             float4 color    : COLOR;
     38             float2 texcoord : TEXCOORD0;
     39         };
     40 
     41         struct v2f_blurSGX
     42         {
     43             float4 pos:SV_POSITION;
     44             half2 uv:TEXCOORD0;
     45             float4 color    : COLOR;
     46             half4 blurFactor:TEXCOORD1;
     47         };
     48 
     49         v2f_blurSGX vert_BlurHorizontal(appdata_t v)
     50         {
     51             v2f_blurSGX o;
     52             o.pos = UnityObjectToClipPos(v.vertex);
     53             o.uv = v.texcoord.xy;
     54             o.blurFactor.xy = _MainTex_TexelSize.xy * 2 * _BlurSize;
     55             o.color = v.color;
     56             return o;
     57         }
     58 
     59 
     60         fixed4 Tex2DBlurring(sampler2D tex, half2 texcood, half2 blur)
     61         {
     62             //快速模糊
     63             //const int KERNEL_SIZE = 3;
     64             //const float KERNEL_[3] = { 0.4566, 1.0, 0.4566 };
     65 
     66             //中等模糊
     67             //const int KERNEL_SIZE = 5;
     68             //const float KERNEL_[5] = { 0.2486, 0.7046, 1.0, 0.7046, 0.2486 };
     69 
     70             //高级模糊
     71             const int KERNEL_SIZE = 7;
     72             const float KERNEL_[7] = { 0.1719, 0.4566, 0.8204, 1.0, 0.8204, 0.4566, 0.1719 };
     73             float4 o = 0;
     74             float sum = 0;
     75             float2 shift = 0;
     76             for (int x = 0; x < KERNEL_SIZE; x++)
     77             {
     78                 shift.x = blur.x * (float(x) - KERNEL_SIZE / 2);
     79                 for (int y = 0; y < KERNEL_SIZE; y++)
     80                 {
     81                     shift.y = blur.y * (float(y) - KERNEL_SIZE / 2);
     82                     float2 uv = texcood + shift;
     83                     float weight = KERNEL_[x] * KERNEL_[y];
     84                     sum += weight;
     85                     uv.x = clamp(uv.x, 0.02, 0.98);
     86                     uv.y = clamp(uv.y, 0.02, 0.98);
     87                     o += tex2D(tex, uv) * weight;
     88                 }
     89             }
     90             fixed4 renderTex = (o / sum);
     91             //brigtness亮度直接乘以一个系数,也就是RGB整体缩放,调整亮度
     92             fixed3 finalColor = renderTex * _Brightness;
     93             //saturation饱和度:首先根据公式计算同等亮度情况下饱和度最低的值:
     94             fixed gray = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b;
     95             fixed3 grayColor = fixed3(gray, gray, gray);
     96             //根据Saturation在饱和度最低的图像和原图之间差值
     97             finalColor = lerp(grayColor, finalColor, _Saturation);
     98             //contrast对比度:首先计算对比度最低的值
     99             fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
    100             //根据Contrast在对比度最低的图像和原图之间差值
    101             finalColor = lerp(avgColor, finalColor, _Contrast);
    102             //返回结果,alpha通道不变
    103             return fixed4(finalColor, renderTex.a);
    104         }
    105         
    106         fixed4 frag_Blur(v2f_blurSGX i) :SV_Target
    107         {
    108             fixed4 color = Tex2DBlurring(_MainTex,i.uv,i.blurFactor.xy);
    109             color.a = i.color.a;
    110             return color;
    111         }
    112 
    113 
    114             ENDCG
    115 
    116             SubShader
    117         {
    118             //ugui mask No culling or depth
    119             Cull Off ZWrite Off
    120                 Stencil
    121             {
    122                 Ref[_Stencil]
    123                 Comp[_StencilComp]
    124                 Pass[_StencilOp]
    125                 ReadMask[_StencilReadMask]
    126                 WriteMask[_StencilWriteMask]
    127             }
    128 
    129                 Fog{ Mode Off }
    130                 Blend SrcAlpha OneMinusSrcAlpha
    131                 ColorMask[_ColorMask]
    132 
    133                 Pass
    134             {
    135                 CGPROGRAM
    136     #pragma vertex vert_BlurHorizontal
    137     #pragma fragment frag_Blur
    138                 ENDCG
    139             }
    140         }
    141 }

    用法:

    1.创建一个材质球 ,把 ImageBlur.shader 挂上

    2.加一个Raw Image 组件,GaussianBlurBg.ExportTexture 获取的值 赋值给 Raw Image的 tetxure 属性

    效果:

     

     

    总结知识点:
    1.CS.UnityEngine.RenderTexture.GetTemporary:系统api 获取临时渲染纹理
    public static RenderTexture GetTemporary(int width, int height, int depthBuffer);
    参数width、height 不能小于等于0
    2.Camera.targetTexture 给摄像机设置渲染图片
    3.Camera:Render() 手动渲染摄像机
    4.Texture2D
    5.Texture2D:ReadPixels // ReadPixels 从屏幕读取像素保存到纹理数据中
    6.Texture2D:Apply() 对上述更改的应用
    public void Apply([DefaultValue("true")] bool updateMipmaps, [DefaultValue("false")] bool makeNoLongerReadable);
    7.Rendertexture的分配和销毁上有一个地方需要注意:
    如果频繁的要new一个rt出来,不要直接new,而是使用RenderTexture提供的GetTemporary和ReleaseTemporary,
    它将在内部维护一个池,反复重用一些大小格式一样的rt资源,因为让GPU为你分配一个新的texture其实是要耗时间的。

  • 相关阅读:
    Silverlight不能调试问题(转摘) Unable to start debugging. Cannot locate Microsoft Internet Explorer.
    Mac OS X 同 Windows 的概念,词汇,热键对比随录,让你更好地过度到Mac OS X
    敏捷度和成熟度
    有什么是安全的吗?
    linux定时任务的设置
    javascript闭包
    (转)JavaScript世界的一等公民 函数
    PHP魔法函数(转)
    JS字符串截取,按字节截取
    linux cp命令
  • 原文地址:https://www.cnblogs.com/zhaolaosan/p/16160147.html
Copyright © 2020-2023  润新知