zoukankan      html  css  js  c++  java
  • Pass的通用指令开关

    LOD:

    设置:单个设置Shader.maximumLOD、全局设置Shader.globalMaximumLOD、QualitySettings里面的Maximum LODLevel
    原理:小于指定值的shader和subshader才能被使用。
    应用:有时候一些显卡虽然支持很多特性,但是效率很低,此时就可以用LOD来进行控制。
    内置shader的LOD值:
      VertexLit kind of shaders = 100
      Decal, Reflective VertexLit = 150
      Diffuse = 200
      Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
      Bumped, Specular = 300
      Bumped Specular = 400
      Parallax = 500
      Parallax Specular = 600

    注释:Shader自身的LOD会覆盖全局的LOD。

        public Shader targetShader;
    
        private void Start () 
        {
            // 全局的值会被Shader本地址覆盖
            Shader.globalMaximumLOD = 300;
            if (targetShader != null)
            {
                targetShader.maximumLOD = 600;
            }
        }

    RenderQueue:

        mtrl.renderQueue = 1000;

      shader中使用ZTest Always,可以让被遮住的物体也渲染。

    AlphaTest:

      固定管线:使用AlphaTest命令

      动态管线:使用clip(alpha - cutoff)指令来实现

      Alpha检测在ps完成计后,即将写入帧之前,通过和一个固定的数值比较,来决定当前ps的计算结果到底要不要写入帧中。

    // inside SubShader
    Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }
    
    // inside CGPROGRAM in the fragment Shader:
    clip(textureColor.a - alphaCutoffValue);

      AlphaTest抗锯齿:

    // inside SubShader
    Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }
    
    // inside Pass
    AlphaToMask On

    AlphaBlend:

      shader渲染的最后一步,决定怎样将当前计算结果写入到帧缓存中。

      命令集:

      Blend BlendOp AlplaToMask

    // inside SubShader
    Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }
    
    // inside Pass
    ZWrite Off
    Blend SrcAlpha OneMinusSrcAlpha

       AlphaBlend会有一系列和绘制顺序相关的问题,涉及到的知识点如下:

      (1)Unity通过Queue保证所有的不透明物体Geometry都会在半透明物体Transparent之前被渲染,(Queue标签决定了这个对象的渲染队列);

      (2)Unity保证所有Transparent队列的物体,按distance(物体的远近,不是像素的)从后往前渲染;

      (3)distance的计算方式:使用网格的几何中心点来进行半透明物体的排序。

      对于部分遮挡的物体,还是会产生不正确的遮挡效果。因此我们要么分割网格,要么使用Alpha Test或者开启ZWrite来替代。

    AlphaTest和AlphaBlend的性能比较:

      官方文档在这里:https://docs.unity3d.com/Manual/SL-ShaderPerformance.html

      翻译如下:

      固定管线的AlphaTest和可编程管线的clip()函数,在不同平台有不同性能表现:

      (1)多数平台上,AlphaTest这种整个剔除透明像素的做法能获得一点点性能优势;

      (2)在ios和android这样基于PowerVR GUPs的设备上,AlphaTest是非常耗资源的,不要企图使用它来做性能优化,因为它会让游戏更慢(是因为直接丢掉像素,让GPUs的某些优化策略没法执行了)。

      所以结论是:手机上尽量使用AlphaBlend而不是AlphaTest。

     ColorMask:

      ColorMask RGB | A | 0 | any combination of R, G, B, A

      ColorMask也是耗费比较大的操作,只在确实需要时使用。

     ZWrite/ZTest:

      ZWrite On | Off

      ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always

      关于相机的深度贴图_CameraDepthTexture:

      (1)默认材质都自带RenderType的Tag;

      (2)自定义sahder只有添加RenderType标签才会将深度写到_CameraDepthTexture。

     Offset:

      对Z深度的偏移。

      可以让像素看起来更靠前或更靠后,当两个面重叠时,可以手动指定谁相对靠前一些,而且不会战胜z-fitting。

      Offset只会对ZTest的条件做修正,但是并不会改变最后的Z缓冲。

     GrabPass:

      抓取当前屏幕当做贴图使用。

    Shader "James/VP Shader/GrabPass"
    {
        Properties 
        {
            _MainTex("MainTex", 2D) = "white" {}
        }
        SubShader 
        {
            // 在所有不透明几何体之后自画,这一点很重要
            Tags { "Queue" = "Transparent" }
            GrabPass { "_MyGrab" }
            Pass
            {
                CGPROGRAM
                #pragma vertex vs
                #pragma fragment ps
                #include "UnityCG.cginc"
    
                struct v2f
                {
                    float4 pos : SV_POSITION;
                    float3 color : COLOR0;
                    float2 uv : TEXCOORD0;
                };
    
                sampler2D _MainTex;
                float4 _MainTex_ST;
                sampler2D _MyGrab;
    
                v2f vs(appdata_base v)
                {
                    v2f o;
                    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                    o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                    return o;
                }
    
                float4 ps(v2f i):COLOR
                {
                    float4 texColor = tex2D(_MainTex, i.uv);
                    float4 grabColor = tex2D(_MyGrab, i.uv);
                    return texColor * grabColor;
                }
                ENDCG
            }
        } 
        FallBack "Diffuse"
    }

     Fog:

      雾效实现的三种方式:

      (1)全局雾

      RenderSettings.fog = true;
      RenderSettings.fogColor = Color.red;
      RenderSettings.fogMode = FogMode.Linear;
      RenderSettings.fogStartDistance = 0;
      RenderSettings.fogEndDistance = 10;

      (2)Fog指令

      Fog{ Mode Linear Color(1, 0, 0) Range 0, 10 }

      (3)Shader计算方式

    Shader "James/VP Shader/Fog"
    {
        Properties {
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _FogColor("FogColor", Color) = (1, 1, 1, 1)
            _Density("Density", Range(0, 10)) = 1
            _NearDistance("NearDistance", Float) = 0
            _FarDistance("FarDistance", Float) = 10
        }
        SubShader {
            Tags { "RenderType"="Opaque" }
            Fog { Mode Off }
            Pass
            {
                CGPROGRAM
                #pragma vertex vs
                #pragma fragment ps
                #include "UnityCG.cginc"
    
                struct v2f
                {
                    float4 pos : SV_POSITION;
                    float3 color : COLOR0;
                    float2 uv : TEXCOORD0;
                    float4 depth : TEXCOORD1;
                };
    
                sampler2D _MainTex;
                float4 _MainTex_ST;
                float4 _FogColor;
                float _Density;
                float _NearDistance;
                float _FarDistance;
    
                v2f vs(appdata_base v)
                {
                    v2f o;
                    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                    o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                    o.depth = mul(UNITY_MATRIX_MV, v.vertex);
                    o.depth.z = -o.depth.z;
                    o.depth.w = (_FarDistance - _NearDistance) * o.depth.w;
                    return o;
                }
    
                float4 ps(v2f i):COLOR
                {
                    float4 texColor = tex2D(_MainTex, i.uv);
                    float fg = 0;
                    if(i.depth.z > _NearDistance && i.depth.z < _FarDistance)
                    {
                        fg = i.depth.z / i.depth.w;
                    }
                    else if(i.depth.z > _FarDistance)
                    {
                        fg = _FarDistance / i.depth.w;
                    }
                    return fg * _Density * _FogColor * texColor;
                }
                ENDCG
            }
        } 
        FallBack "Diffuse"
    }

     Stencil:

      Stencil-Test在Z-Test和Alpha-Test之前,如果模板检测不通过,则像素直接被丢掉而不会执行fragment函数。

    Shader "James/VP Shader/Stencil"
    {
        Properties {
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _refVal("Stencil Ref Value",int)=0
        }
        SubShader {
            Tags { "RenderType"="Opaque" }
            ZTest Always
            Stencil
            {
                Ref [_refVal]
                Comp GEqual
                Pass Replace
                Fail keep
                ZFail keep
            }
            Pass
            {
                CGPROGRAM
                #pragma vertex vs
                #pragma fragment ps
                #include "UnityCG.cginc"
    
                struct v2f
                {
                    float4 pos : SV_POSITION;
                    float3 color : COLOR0;
                    float2 uv : TEXCOORD0;
                };
    
                sampler2D _MainTex;
                float4 _MainTex_ST;
    
                v2f vs(appdata_base v)
                {
                    v2f o;
                    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                    o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                    return o;
                }
    
                float4 ps(v2f i):COLOR
                {
                    float4 texColor = tex2D(_MainTex, i.uv);
                    return texColor;
                }
                ENDCG
            }
        } 
        FallBack "Diffuse"
    }
  • 相关阅读:
    npm start 时报 node_modules/nan 错误
    webpack 插件依赖
    reducer-form 数组字段 在removeField/removeField 之后 dirty 不改变的问题
    sass 入门教程
    解决国内gem不能用的问题
    nrm 快速切换 NPM 源
    数值补全指定位数
    文本溢出使用省略号
    css/js效果笔记
    用MyEclipse,只要一开css文件就报错,按下任何键都报错
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/4723813.html
Copyright © 2011-2022 走看看