美文网首页
UnityShader 全屏界面变灰

UnityShader 全屏界面变灰

作者: zzqlb | 来源:发表于2020-04-19 22:31 被阅读0次

    之前的面试的时候有被问到,像4月4号清明节的时候,很多软件的界面都变成灰色,想要实现这个有什么思路,当时由于紧张,没有什么思路,后面想想,用屏幕后处理是可以实现的,像很多游戏,主角死亡后,游戏画面变灰,会不会也是这么实现的呢?话不多说,直接上代码:
    CS代码:
    首先我要准备渲染RenderTexture的材质,这里我们使用一个可以在屏幕后处理中使用的通用基类。

    using UnityEngine;
    using System.Collections;
    
    [ExecuteInEditMode]
    [RequireComponent (typeof(Camera))]
    public class PostEffectsBase : MonoBehaviour {
        protected void Start() {
            CheckResources();
        }
        
        protected void CheckResources() {
            bool isSupported = CheckSupport();
            
            if (isSupported == false) {
                NotSupported();
            }
        }
    
        // 检测设备是否支持屏幕特效和渲染纹理
        protected bool CheckSupport() {
            if (SystemInfo.supportsImageEffects == false || SystemInfo.supportsRenderTextures == false) {
                Debug.LogWarning("This platform does not support image effects or render textures.");
                return false;
            }
            
            return true;
        }
    
        protected void NotSupported() {
            enabled = false;
        }
    
        // 创建新的材质去渲染动态纹理
        protected Material CheckShaderAndCreateMaterial(Shader shader, Material material) {
            if (shader == null) {
                return null;
            }
            
            if (shader.isSupported && material && material.shader == shader)
                return material;
            
            if (!shader.isSupported) {
                return null;
            }
            else {
                material = new Material(shader);
                material.hideFlags = HideFlags.HideAndDontSave;
                if (material)
                    return material;
                else 
                    return null;
            }
        }
    }
    

    创建一个我们操作界面变灰的脚本,继承自PostEffectsBase,同时将该脚本挂到摄像机上。

    using UnityEngine;
    using System.Collections;
    
    [ExecuteInEditMode]
    public class SceneGray : PostEffectsBase
    {
        //设置渲染的shader
        public Shader curShader;
        //灰度程度0~1,0为原来颜色,1为灰色
        public float grayScaleAmount = 1.0f;
        //新创建的材质
        private Material curMaterial;
    
        Material material
        {
            get
            {
                if (curMaterial == null)
                {
                    curMaterial = CheckShaderAndCreateMaterial(curShader,curMaterial);
                }
                return curMaterial;
            }
        }
        //屏幕后处理函数,设置shader参数
        void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
        {
            if (curShader != null)
            {
                material.SetFloat("_LuminosityAmount", grayScaleAmount);
                Graphics.Blit(sourceTexture, destTexture, material);
            }
            else
            {
                Graphics.Blit(sourceTexture, destTexture);
            }
        }
        //设置灰度程度
        void Update()
        {
            grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0, 1.0f);
        }
        //删除新建的材质
        void OnDisable()
        {
            if (curMaterial)
            {
                DestroyImmediate(curMaterial);
            }
        }
    }
    

    shader代码:

    Shader "Custom/GrayColor" {
        Properties {
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _grayScale("_grayScale",Float) = 1.0
        }
        SubShader {
            Pass {  
                ZTest Always Cull Off ZWrite Off
                
                CGPROGRAM  
                #pragma vertex vert  
                #pragma fragment frag  
                  
                #include "UnityCG.cginc"  
                  
                sampler2D _MainTex;  
                half _grayScale;
                  
                struct v2f {
                    float4 pos : SV_POSITION;
                    half2 uv: TEXCOORD0;
                };
                  
                v2f vert(appdata_img v) {
                    v2f o;
                    o.pos = UnityObjectToClipPos(v.vertex);
                    o.uv = v.texcoord;   
                    return o;
                }
            
                fixed4 frag(v2f i) : SV_Target {
                    fixed4 renderTex = tex2D(_MainTex, i.uv); 
                    //置灰后的灰色值
                    float gray = dot(renderTex.rgb, float3(0.299, 0.587, 0.114));
                    fixed4 grayColor = fixed4(gray, gray, gray,renderTex.a);
                    //将原来的颜色与灰色做插值运算
                    fixed4 finalColor = lerp(renderTex,grayColor,_grayScale);
                    return finalColor;
                }  
                  
                ENDCG
            }  
        }
        
        Fallback Off
    }
    

    最终效果:


    GrayScaleAmount=0.png GrayScaleAmount=1.png

    相关文章

      网友评论

          本文标题:UnityShader 全屏界面变灰

          本文链接:https://www.haomeiwen.com/subject/jegibhtx.html