当前位置:   article > 正文

Unity Shader学习(一)_unity #pragma surface surf lambert addshadow #prag

unity #pragma surface surf lambert addshadow #pragma shader_feature redify_o

一 Unity Shader分为:

(1)Standard Surface Shader:会产生一个包含标准光照模型的表面着色器

(2)Unlit Shader :会产生一个不包含光照但包含雾效的基本顶点/片元着色器 

(3)Image Effect Shader:为实现各种屏幕后处理效果提供了一个基本模版

(4)Compute Shader:会产生一种特殊的Shader文件,这类Shader利用GPU的并行性来进行一些与常规渲染流水线无关的事情。

二 Unity Shader的基本结构:

(1)Shader "ShaderName"{

Properties{

//属性

 }

SubShader{

//显卡A使用的子着色器 表面着色器 顶点着色器 片元着色器 固定函数着色器等

[Tags]//标签设置

[RenderSetup]//状态设置

Pass{

//定义一次完整的渲染流程,Pass过多影响性能

[Name]

[Tags]

[RenderSetup]

//other code

// UsePass "MyShader/MYPASS" 这样去调用其他的Shader Pass

 }

  }

SubShader{

//显卡B使用的子着色器

  }

Fallback "VertexLit"

 }

一个Unity Shader至少包含一个SunShader,加载Shader时Unity会扫描所有的SubShader,选择第一个可以在目标平台上使用的SubShader,如果都不支持调用Fallback制定的Shader。

(2)RenderSetup渲染状态设置:

Cull:Cull Back | Front | Off 剔除背面 正面 关闭剔除

ZTest:ZTest Less Greater | LEqual | GEqual | Equal | NotEqual | Always 设置深度测试时使用的函数

ZWrite:ZWrite On | Off 开始关闭深度写入 

Blend:Blend SrcFactor DstFactor 开启并设置混合模式

(3)Tags标签设置:

Queue 设定渲染顺序,指定物体属于哪一个渲染队列,保证透明物体在所有不透明物体后被渲染 Tags{"Queue" = "Transparent"}

RenderType 对着色器进行分类,例如是一个不透明着色器还是透明着色器 Tags{"RenderType" = "Opaque"}

DisableBatching 指定是否批处理 Tags{"DiableBatching"="True"}

ForceNoShadowCasting 控制使用SubShader的物体是否会投影阴影 Tags{"ForceNoShadoeCasting" = "True"}

IgnoreProjector 该物体是否受欢Projector影响 通常用于半透明物体 Tags{"IgnoreProjector " = "True"}

CanUseSpriteAtlas 是否用于精灵

PreviewType 材质面板如何预览该材质 Tags{"PreviewType"="Plane"}

(4)

Pass中的标签不同于SubShader中的标签,这些标签可以告诉引擎我们希望怎样来渲染物体 

Pass 的标签类型

LightMode Pass在Unity中的渲染流水线的角色 Tags{"LightMode"="ForwardBase"}

RequireOptions 用于指定满足某些渲染条件时才渲染该Pass 目前只支持 SoftVegetation

(5)表面着色器是Unity自己创造的着色器 在 CGPROGRAM 和 ENDCG中间,写在SubShader内

Shader "Unity Shaders Book/Chapter 3/Redify" {
    Properties {
        _MainTex ("Base (RGB)"2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf Lambert addshadow
        #pragma shader_feature REDIFY_ON

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };
        
        void surf (Input IN, inout SurfaceOutput o) {
            half4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;

            #if REDIFY_ON
            o.Albedo.gb *= 0.5;
            #endif
        }
        ENDCG
    } 
    CustomEditor "CustomShaderGUI"
}

(6)顶点/片元着色器写在Pass内,灵活性更高

Shader "Unity Shaders Book/Chapter 5/Simple Shader" {
    Properties {
        _Color ("Color Tint"Color) = (1111)
    }
    SubShader {
        Pass {
            CGPROGRAM

            #pragma vertex vert//通知Unity使用了哪些函数包含顶点着色器
            #pragma fragment frag//通知Unity使用了哪些函数包含片元着色器
            
            uniform fixed4 _Color;

            struct a2v {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };
            
            struct v2f {
                float4 pos : SV_POSITION;
                fixed3 color : COLOR0;
            };
            
            v2f vert(a2v v) {//输入的结构是a2v,包含了顶点的位置,法线和纹理
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);//o 为顶点着色器和片元着色器的通信
                o.color = v.normal * 0.5 + fixed3(0.50.50.5);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target {
                fixed3 c = i.color;
                c *= _Color.rgb;
                return fixed4(c, 1.0);//输出的颜色
            }

            ENDCG
        }
    }
}

三 Unity中常用的包含文件:

UnityCG.cginc 包含了常使用的帮助函数宏河结构体等

UnityShaderVariables.cginc Unity Shader自动包含进来的 包括UNITY_MATRIX_MVP

Lighting.cginc 包含了各种内置的光照模型,如果是表面着色器会自动包含进来

四 Unity支持的语义

应用阶段传递模型数据给顶点着色器时Unity支持的常用语义

POSITION float4 顶点位置

NORMAL float3 顶点法线

TANGENT float4 顶点切线

TEXCOORn float2 或float4 顶点纹理坐标系

COLOR 顶点颜色

顶点着色器传递给片元着色器的常用语义

SV_POSITION 裁剪空间中的顶点坐标

COLOR0 输出第一组顶点颜色 不必要

COLOR1 输出第二组顶点颜色 不必要

TEXCOORD0~TEXCOORD1 输出纹理坐标 不必要

片元着色器输出给UNITY支持的语义

例 fixed4 frag(v2f i) : SV_Target

SV_Target 输出值会存储到渲染目标render target 中

注意:一个语义如 v2f的pos,可以使用的寄存器只能处理4个浮点值,如果使用矩阵float3 * 4,需要使用更多的空间,可以把这些变量拆分成多个变量。

Cg/HLSL支持的3种精度类型

float 最高精度浮点数,使用32位存储

half 中等精度浮点数,使用16位存储,-60000~~+60000

fixed 最低精度浮点数,使用11位存储,-2.0~~2.0

五 Shader调试

1.可以根据鼠标所在的每一个点的颜色值进行调试

OnPostRender is called after a camera has finished rendering the scene

void OnPostRender() {
        if (m_grab) {
            m_screenRenderTexture = new Texture2D(Screen.width, Screen.height);
            m_screenRenderTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
            m_screenRenderTexture.Apply();
            m_pickedColor = m_screenRenderTexture.GetPixel(Mathf.FloorToInt(m_pixelPosition.x), Mathf.FloorToInt(m_pixelPosition.y));
            m_grab = false;
        }
    }

2,帧调试器

frame debug



下一篇开始真正的写Unity Shader












声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/107861
推荐阅读
相关标签
  

闽ICP备14008679号