unity3D技术分享Unity3DUnity Shader分享

Unity Shader 漫反射一 基于顶点着色器

2018-11-15  本文已影响0人  土豆写书

漫反射的定义

  漫反射(简称漫射,英语diffuse reflection)是光线照射在物体粗糙的表面无序地向四周反射的现象,是投射在粗糙表面上的各个方向反射的现象。



// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "My/Shader_diffuse"
{
    Properties
    {
        _Diffuse ("漫反射",color) = ( 1.0,1.0,1.0,1.0 )
    }


        SubShader
    {


        Pass
        {
            Tags{ "LightMode" = "ForwardBase"}

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Lighting.cginc"

            fixed4 _Diffuse;  //颜色属性范围是0~1 所以可以使用 fixed 来存放

            struct a2v{
                float4 vertex:POSITION;
                float3 normal:NORMAL;
            };



            struct v2f{
                float4 pos: SV_POSITION;
                fixed3 color:COLOR0;
            };

            v2f vert (a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //获取环境光颜色
                fixed3 worldNormal = normalize( mul(v.normal, (float3x3)unity_WorldToObject));//顶点的世界坐标系法线
                fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);//光源的世界坐标位置

                                //光源颜色 * 漫反射颜色 * 光源强度
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb*saturate(dot(worldNormal,worldLight));
                
                o.color = ambient + diffuse;
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                return fixed4(i.color, 1.0);
            }

            ENDCG
        }
    }

    Fallback "Diffuse"
}



材质漫反射是绿色.png shader只接受绿色灯光后才会漫反射,当灯光是红色,物体则认为没有任何光源.png 漫反射所有灯光.png 漫反射所有灯光,灯光紫色则反射紫色.png

1.顶点着色器的最基本任务就是把顶点位置从模型空间转换到裁剪空间中
o.pos = UnityObjectToClipPos(v.vertex);

2.计算漫反射需要四个参数
   参数一  材质的漫反射颜色   _Diffuse.rgb
   参数二  顶点的法线并且转换到世界坐标  worldNormal = normalize( mul(v.normal, (float3x3)unity_WorldToObject));
   参数三  光源的颜色强度   dot(worldNormal,worldLight)
   参数四  光源的方向    normalize(_WorldSpaceLightPos0.xyz);
   normalize 函数:向量归一化操作
   saturate 函数:把参数截取到[0,1]
  - 备注1:想要得到正确的光源值需要定义合适的LightMode
  - 备注2:当有多个光源的时候_WorldSpaceLightPos0并不能得到正确的结果


3.最终光照效果 = 环境光+漫反射
 o.color = ambient + diffuse;

4.片元着色器直接输出颜色即可
fixed4 frag (v2f i) : SV_Target {
  return fixed4(i.color, 1.0);
 }

5.回调shader 设置为内置的Diffuse
Fallback "Diffuse"
上一篇下一篇

猜你喜欢

热点阅读