Unity Shader入门总结(一)

最近断断续续学习了一些Unity Shader的内容,总结一下,主要学习资料是siki学院的课程。

Unity Shader基本结构

Shader "Unlit/002" //Shader路径
{
    Properties //Shader属性 可在面板修改
    {
        _Int("Int",Int) = 2
        _Float("Float",float) = 1.5
        _Range("Range",range(0.0,2.0))= 1.0
        _Color("Color",Color) = (1,1,1,1)
        _Vector("Vector",Vector) = (1,4,3,8)
        _MainTex("Texture", 2D) = "white" {}
        _Cube("Cube",Cube) = "white"{}
        _3D("3D",3D) = "black"{}
    }
    SubShader  //子着色器,可以有多个,如果第一个SubShader无法运行就执行第二个,以此类推
    {
        Tags { "RenderType"="Opaque" }  //标签,可选
        LOD 100  //LOD

        Pass //Pass通道,可以有多个
        {
            CGPROGRAM //CG语言开始
            #pragma vertex vert  //定义顶点着色器的函数名为vert
            #pragma fragment frag  //定义片元着色器的函数名为frag    

            #include "UnityCG.cginc"  //包含Unity提供的头文件

            //POSITION表示将模型顶点坐标传入v,SV_POSITION表示顶点着色器的输出是裁剪空间顶点坐标
            float4 vert(float4 v:POSITION):SV_POSITION
            {
                return UnityObjectToClipPos(v);  //将模型坐标转为裁剪空间坐标
            }

            //SV_TARGET表示片元着色器输出颜色到帧缓存中
            fixed4 frag():SV_TARGET
            {
                return fixed4(1,1,1,1);  //直接返回白色
            }
            ENDCG //CG语言结束
        }
    }
    Fallback "VertexLit" //如果以上SubShader都无法使用,则使用VertexLit这个Shader
}

这个最简单的Shader将顶点坐标传入顶点着色器,转换成裁剪空间坐标后输出给片元着色器,片元着色器不做任何处理,直接将每个像素置为白色,效果如图:

结构体的使用

Shader "Unlit/003"
{
    Properties
    {
        _Color("Color" , Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //只有在CGPROGRAM内再次定义一个与属性块内名字与类型相同的变量,属性块对应的变量才能起作用
            fixed4 _Color;

            struct a2v//传入顶点着色器的结构体
            {
                //用模型顶点填充v变量
                float4 vertex:POSITION;
                //用模型的法线填充n变量
                float3 normal:NORMAL;
                //用模型的第一套uv填充texcoord
                float4 texcoord: TEXCOORD0;
            };

            struct v2f//顶点着色器输出给片元着色器的结构体
            {
                //SV_POSITION语义告诉unity : pos为裁剪空间中的位置信息
                float4 pos:SV_POSITION;
                //COLOR0 语义可以储存颜色信息
                fixed3 color:COLOR0;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.color = v.normal * 0.5 +fixed3(0.5,0.5,0.5);
                return o;
            }

            fixed4 frag(v2f i):SV_TARGET
            {
                fixed3 c = i.color;
                c*=_Color.rgb;
                return fixed4(c, 1);
            }

            ENDCG
        }
    }
}

Shader中使用结构体和C语言类似,然后我们就可以使用结构体来进行顶点着色器和片元着色器的数据传输,上面这个Shader中,在顶点着色器里将法线向量映射到[0,1]区间,然后保存在v2f的color变量里传给片元着色器,片元着色器将color与Shader属性里的_Color相叠加输出。

可以看到右边颜色偏蓝,左边偏红,上边偏绿,这是将法线向量作为颜色输出的结果,x分量较大就会偏红,其他两个分量同理。

漫反射Shader

Shader "Unlit/005"
{
    Properties
    {
        _Diffuse("Diffuse", Color) = (1,1,1,1)

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc" //引入灯光相关头文件

            fixed4 _Diffuse;

            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed3 color: Color;
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;  //获得环境光颜色
                fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); //将法线转到世界空间
                fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz); //获得第一个平行光的方向
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal,worldLight));  //lambert光照模型计算
                o.color = diffuse + ambient;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return fixed4(i.color,1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

appdata_base是Unity在UnityCG.cginc中提供的结构体,包含顶点、法线和UV信息。

在顶点着色器中使用Lambert光照模型(关于光照模型的原理这篇先不提)计算漫反射光照,_LightColor0表示场景第一个灯光的颜色,灯光颜色乘以物体固有色乘以世界空间法线和世界空间灯光位置的点积再加上环境光即得到最终的顶点颜色。

也可以在片元着色器中计算光照,如何取舍取决于追求性能还是质量,一般来说顶点数量是小于像素数量的,所以如果追求更好的性能就在顶点着色器中计算,如果想要更好的质量就在片元着色器中计算。

用片元着色器计算漫反射:

Shader "Unlit/006"
{
    Properties
    {
        _Diffuse("Diffuse", Color) = (1,1,1,1)

    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            fixed4 _Diffuse;

            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed3 worldNormal: TEXCOORD0;
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                fixed3 worldNormal = UnityObjectToWorldNormal( v.normal);
                o.worldNormal = worldNormal;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0,dot(worldLightDir,i.worldNormal));
                fixed3 color = ambient + diffuse;
                return fixed4(color,1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

高光反射Shader

Shader "Unlit/008"
{
    Properties
    {
        _Diffuse("Diffuse", Color) = (1,1,1,1)
        _Specular("Specular", Color) = (1,1,1,1)
        _Gloss("Gloss", Range(1,256)) = 5
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            fixed4 _Diffuse;
            fixed4 _Specular;
            float _Gloss;

            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed3 color: Color;
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);

                fixed3 worldPos = mul(unity_ObjectToWorld, v.vertex);

                //漫反射
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
                fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
                fixed3 worldLight = UnityWorldSpaceLightDir(worldPos);
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal,worldLight));

                //高光反射
                fixed3 reflectDir = normalize(reflect(-worldLight,worldNormal));
                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(reflectDir,viewDir)),_Gloss);//Phong光照模型计算

                o.color = diffuse + ambient + specular;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return fixed4(i.color,1);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

高光反射计算使用Phong光照模型,计算反射向量reflectDir时需要注意将WorldLight取反才是正确的入射光方向,观察向量viewDir使用UnityWorldSpaceViewDir得到即可。

Blinn-Phong高光反射

Shader "Unlit/010"
{
   Properties
    {
        _Diffuse("Diffuse", Color) = (1,1,1,1)
        _Specular("Specular", Color) = (1,1,1,1)
        _Gloss("Gloss", Range(1,256)) = 5
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            fixed4 _Diffuse;
            fixed4 _Specular;
            float _Gloss;

            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed3 worldNormal: TEXCOORD0;
                float3 worldPos: TEXCOORD1;
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                fixed3 worldNormal = UnityObjectToWorldNormal( v.normal);
                o.worldNormal = worldNormal;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
                //漫反射
                fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0,dot(worldLightDir,i.worldNormal));

                //高光反射
                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
                fixed3 halfDir = normalize(worldLightDir + viewDir);
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(i.worldNormal,halfDir)),_Gloss);

                fixed3 color = ambient + diffuse + specular;
                return fixed4(color,1);
            }
            ENDCG
        }
    }
}

另一种高光反射计算方法,使用灯光向量和观察向量的和halfDir与世界法线进行计算,saturate用于将值限定在0-1之间,这种计算得出的结果高光会更亮一些。

纹理采样

Shader "Unlit/011"
{
     Properties
    {
        _MainTex("MainTex", 2D) = "white" {}
        _Diffuse("Diffuse", Color) = (1,1,1,1)
        _Specular("Specular", Color) = (1,1,1,1)
        _Gloss("Gloss", Range(1,256)) = 5
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            sampler2D _MainTex;
            //用一个纹理加上_ST表示该纹理的缩放和偏移
            //_MainTex_ST.xy存储的是缩放值,而_MainTex_ST.zw存储的是偏移值
            float4 _MainTex_ST;
            fixed4 _Diffuse;
            fixed4 _Specular;
            float _Gloss;

            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed3 worldNormal: TEXCOORD0;
                float3 worldPos: TEXCOORD1;
                float2 uv : TEXCOORD2;
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                fixed3 worldNormal = UnityObjectToWorldNormal( v.normal);
                o.worldNormal = worldNormal;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                //用Unity内置的TRANSFORM_TEX得到纹理坐标
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);//v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                //纹理颜色,用tex2D进行采样
                fixed3 albedo = tex2D(_MainTex, i.uv).rgb;

                //漫反射
                fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
                fixed3 diffuse = _LightColor0.rgb * albedo * _Diffuse.rgb * (dot(worldLightDir,i.worldNormal)*0.5+0.5);

                //高光反射
                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
                fixed3 halfDir = normalize(worldLightDir + viewDir);
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(i.worldNormal,halfDir)),_Gloss);

                fixed3 color = ambient + diffuse + specular;
                return fixed4(color,1);
            }
            ENDCG
        }
    }
}

纹理采样Unity提供了相关的方法,TRANSFORM_TEX和tex2D用于计算纹理坐标和纹理颜色,注意必须要声明_MainTex_ST。

法线纹理映射

切线空间法线纹理映射

Shader "Unlit/012"
{
     Properties
    {
        _MainTex("MainTex", 2D) = "white" {}
        _BumpMap("Normal Map", 2D) = "bump" {}
        _BumpScale("Bump Scale", float) = 1
        _Diffuse("Diffuse", Color) = (1,1,1,1)
        _Specular("Specular", Color) = (1,1,1,1)
        _Gloss("Gloss", Range(1,256)) = 5
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _BumpMap;
            float4 _BumpMap_ST;
            float _BumpScale;
            fixed4 _Diffuse;
            fixed4 _Specular;
            float _Gloss;

            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed3 lightDir: TEXCOORD0;
                float3 viewDir: TEXCOORD1;
                float2 uv : TEXCOORD2;
                float2 normalUv : TEXCOORD3;
            };

            v2f vert (appdata_tan v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                o.normalUv = TRANSFORM_TEX(v.texcoord, _BumpMap);

                //求副切线向量
                //float3 binormal = cross(v.normal,v.tangent.xyz) * v.tangent.w;
                //float3x3 rotation = float3x3(v.tangent.xyz, binormal, v.normal);
                TANGENT_SPACE_ROTATION;

                //求切线空间光源方向及视角方向
                o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;
                o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz;

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed3 tangentLightDir = normalize(i.lightDir);
                fixed3 tangentviewDir = normalize(i.viewDir);

                fixed4 packedNormal = tex2D(_BumpMap,i.normalUv);

                //需要将法线贴图设置成normal map
                fixed3 tangentNormal = UnpackNormal(packedNormal);
                tangentNormal.xy *= _BumpScale;

                //环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                //纹理颜色
                fixed3 albedo = tex2D(_MainTex, i.uv).rgb;

                //漫反射
                fixed3 diffuse = _LightColor0.rgb * albedo * _Diffuse.rgb * (dot(tangentLightDir,tangentNormal)*0.5+0.5);

                //高光反射
                fixed3 halfDir = normalize(tangentLightDir + tangentviewDir);
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(tangentNormal,halfDir)),_Gloss);

                fixed3 color = ambient + diffuse + specular;
                return fixed4(color,1);
            }
            ENDCG
        }
    }
}

世界空间法线纹理映射

Shader "Unlit/013"
{
       Properties
    {
        _MainTex("MainTex", 2D) = "white" {}
        _BumpMap("Normal Map", 2D) = "bump" {}
        _BumpScale("Bump Scale", float) = 1
        _Diffuse("Diffuse", Color) = (1,1,1,1)
        _Specular("Specular", Color) = (1,1,1,1)
        _Gloss("Gloss", Range(1,256)) = 5
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _BumpMap;
            float4 _BumpMap_ST;
            float _BumpScale;
            fixed4 _Diffuse;
            fixed4 _Specular;
            float _Gloss;

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 uv : TEXCOORD0;
                float4 TtiW0 : TEXCOORD1;
                float4 TtiW1 : TEXCOORD2;
                float4 TtiW2 : TEXCOORD3;
            };

            v2f vert (appdata_tan v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
                o.uv.zw = TRANSFORM_TEX(v.texcoord, _BumpMap);

                //计算世界坐标下的顶点位置,法线,切线,副法线
                float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
                fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
                fixed3 worldBinormal = cross(worldNormal,worldTangent) * v.tangent.w;

                //按列摆放得到从切线空间到世界空间的变换矩阵
                o.TtiW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
                o.TtiW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
                o.TtiW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //求世界坐标
                float3 worldPos = float3(i.TtiW0.w,i.TtiW1.w,i.TtiW2.w);

                //计算时间空间下的光照和视角
                fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));

                //获得法线纹理
                fixed4 packedNormal = tex2D(_BumpMap,i.uv.zw);
                fixed3 tangentNormal = UnpackNormal(packedNormal);
                tangentNormal.xy *= _BumpScale;

                //切线空间法线转换到世界坐标
                fixed3 worldNormal = normalize(float3(dot(i.TtiW0.xyz, tangentNormal),dot(i.TtiW1.xyz, tangentNormal),dot(i.TtiW2.xyz, tangentNormal)));

                //环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                //纹理颜色
                fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb;

                //漫反射
                fixed3 diffuse = _LightColor0.rgb * albedo * _Diffuse.rgb * (dot(lightDir,worldNormal)*0.5+0.5);

                //高光反射
                fixed3 halfDir = normalize(lightDir + viewDir);
                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(worldNormal,halfDir)),_Gloss);

                fixed3 color = ambient + diffuse + specular;
                return fixed4(color,1);
            }
            ENDCG
        }
    }
}

原文地址:https://www.cnblogs.com/LiveForGame/p/12181921.html

时间: 2024-10-25 06:34:56

Unity Shader入门总结(一)的相关文章

Unity Shader入门精要读书笔记(一)序章

本系列的博文是笔者读<Unity Shader入门精要>的读书笔记,这本书的章节框架是: 第一章:着手准备. 第二章:GPU流水线. 第三章:Shader基本语法. 第四章:Shader数学基础. 第五章:利用简单的顶点/片元着色器来实现辅助技巧. 第六章:基本光照模型. 第七章:法线纹理.遮罩纹理等基础纹理. 第八章:透明度测试和透明度混合. 第九章:复杂光照实现. 第十章:高级纹理(立方体纹理等). 第十一章:纹理动画.顶点动画. 第十二章:屏幕特效. 第十三章:深度纹理. 第十四章:非真

Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础

摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐标系下进行的. 一个二维的笛卡尔坐标系包含了两个部分的信息: 一个特殊的位置,即原点,它是整个坐标系的中心. 两条过原点的互相垂直的矢量,即X轴和Y轴.这些坐标轴也被称为是该坐标的矢量. OpenGL 和 DirectX 使用了不同的二维笛卡尔坐标系.如下图所示: 2)三维笛卡尔坐标系 在三维笛卡尔坐标系中,

Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照

转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交:一些光线被物体吸收了,而另一些光线被散射到其他方向. 最后,摄像机吸收了一些光,产生了一张图像. 在光学中,我们使用辐照度来量化光.对于平行光来说,它的辐照度可通过计算在垂直于l的单位面积上单位时间内穿过的能量来得到.在计算光照模型时,我们需要知道一个物体表面的辐照度,而物体表面往往是和l不垂直的,我们可以

Unity Shader入门教程(一)

参考文献:http://www.360doc.com/content/13/0923/15/12282510_316492286.shtml Unity Shader是着色器,将纹理.网格信息输入,得到材质的一段程序,具体是个什么东西,还需要亲自实践才知道.一个Unity大神推荐我:如果要学计算机图形编程(游戏编程的基础),可以先学习UnityShader,往后再学习OpenGL和DX.不说废话,依我的风格,都是直接看实例,笔者的教程偏向于傻瓜式的,应该适合入门. 前提:安装了Unity和VS,

Unity Shader入门

这篇文章是我在学习蛮牛的一套关于Shader教程(http://www.unitytrain.cn/course/96)后的简单总结,个人感觉这套教程并不是以高级Shader编程为目的的,更像是授人以渔的宗旨.下面我会分为三个部分:Shader简述.图形学基础,Cg简介为大家介绍Shader的相关内容,也算是做一个总结. 一:Shader简述     a.先说一下GPU与CPU的区别,简单说:GPU主要负责跟显示相关的数据处理,而CPU主要负责操作系统和应用程序.为什么不把显示相关的数据直接交给

Unity Shader入门精要学习笔记 - 第3章 Unity Shader 基础

来源作者:candycat   http://blog.csdn.net/candycat1992/article/ 概述 总体来说,在Unity中我们需要配合使用材质和Unity Shader才能达到需要的效果.一个最常见的流程是. 1)创建一个材质 2)创建一个Unity Shader,并把它赋给上一步创建的材质 3)把材质赋给要渲染的对象 4)在材质面板中调整Unity Shader的属性,以得到满意的效果 下图显示了Unity Shader和材质是如何一起工作来控制物体的渲染的. Uni

Unity Shader入门教程(二)最基本的Diffuse和Normal样例

本教程参考了<猫都能学会的Unity3dShaderLab教程.CHM>, 1.请上网搜索并下载此文件. 2.随后再下载里面提到的素材: http://vdisk.weibo.com/s/y-NNpUsxhYhZI 第一组实验(复习课,实现最简单的漫反射 [该组实验参考了官网示例中的Normal-Diffuse.shader例子]): 第1.1步:创建一个名为"NormalDiffuse"的shader 第1.2步:看到其中有一些已有的内容,不妨全部删掉(除了第一行),这样

Unity Shader入门教程(四)反射光斑的实现

本节内容介绍PhongModel(也就是上文说的反射光的计算模型),采用的计算方法是BlinPhong(也即是用视线方向V+光源方向L的和,与N做点积,随后幂化得到高光反射系数)下图采用了csdn博文http://blog.csdn.net/u010133610/article/details/52206654中的一张插图. 第1.1步:新建shader和material,正如我前面的教程所说的那样. 第1.2步:代码如下: ▼代码开始 Shader "Custom/Learn2" {

Unity Shader 入门

To be more specific, a Shader defines: The method to render an object. This includes using different methods depending on the graphics card of the end user. Any vertex and fragment programs used to render. Some texture properties that are assignable