Unity3D Shader(10)——Fragment Shader(漫反射、phong效果、blinnPhong效果、阴影、halfLambert、渐变纹理)

来源:互联网 发布:九天封神翅膀进阶数据 编辑:程序博客网 时间:2024/05/18 05:52

各种shader 小问题请咨询扣扣:2540,33230 


Fragment Shader的效果要好于vertex shader,前者基于面,然后逐像素处理对象,后者基于顶点来处理对象,缺点就是前者计算相对复杂,会多耗费一些资源。

首先对应着vertex shader(看之前的博客),来看一下Fragment的漫反射的效果。

Fragment Shader的主要计算在Frag方法里计算,Vert方法主要起传递数据的作用,而vertex shader主要在Vert方法里计算。

Shader "Custom/FragmentShader" {SubShader {PASS{tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert          #pragma fragment frag        #include "UnityCG.cginc"        #include "Lighting.cginc"        struct v2f{        float4 pos:POSITION;        float3 normal1:TEXCOORD0;        float4 vertex1:TEXCOORD1;        };          v2f vert(appdata_base v){        v2f o;        o.pos=UnityObjectToClipPos(v.vertex);        o.normal1=v.normal;        o.vertex1=v.vertex;           return o;        }        float4 frag(v2f IN):COLOR{        float4 col= UNITY_LIGHTMODEL_AMBIENT;        float3 N=UnityObjectToWorldNormal(IN.normal1);        float3 L=normalize(WorldSpaceLightDir(IN.vertex1));        float diffuseScale=saturate(dot(N,L));        col+=_LightColor0*diffuseScale;        return col;        }ENDCG}}FallBack "Diffuse"}

2、将上面代码稍微修改一下,即在frag方法里增加Phong的计算就可以得到Phong的效果,原理请看上篇博文。具体代码如下:

properties{_SpecularColor("SpecularColor",color)=(1,1,1,1)_Shininess("Shininess",range(1,8))=4}SubShader {PASS{tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert          #pragma fragment frag        #include "UnityCG.cginc"        #include "Lighting.cginc"        float4 _SpecularColor;        float _Shininess;        struct v2f{        float4 pos:POSITION;        float3 normal1:TEXCOORD0;        float4 vertex1:TEXCOORD1;        };          v2f vert(appdata_base v){        v2f o;        o.pos=UnityObjectToClipPos(v.vertex);        o.normal1=v.normal;        o.vertex1=v.vertex;           return o;        }        float4 frag(v2f IN):COLOR{        float4 col= UNITY_LIGHTMODEL_AMBIENT;        float3 N=UnityObjectToWorldNormal(IN.normal1);        float3 L=normalize(WorldSpaceLightDir(IN.vertex1));        float diffuseScale=saturate(dot(N,L));        col+=_LightColor0*diffuseScale;        //Phong运算        float3 V=normalize(WorldSpaceViewDir(IN.vertex1));        float3 R=2*dot(N,L)*N-L;        float specularScale=saturate(dot(R,V));        col+=_SpecularColor*pow(specularScale,_Shininess);        return col;        }ENDCG}}FallBack "Diffuse"}


3、同样的,在Phong效果的基础上,再修改一下,即可以得到BlinnPong的效果。

Shader "Custom/FragmentShader" {properties{_SpecularColor("SpecularColor",color)=(1,1,1,1)_Shininess("Shininess",range(1,8))=4}SubShader {PASS{tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert          #pragma fragment frag        #include "UnityCG.cginc"        #include "Lighting.cginc"        float4 _SpecularColor;        float _Shininess;        struct v2f{        float4 pos:POSITION;        float3 normal1:TEXCOORD0;        float4 vertex1:TEXCOORD1;        };          v2f vert(appdata_base v){        v2f o;        o.pos=UnityObjectToClipPos(v.vertex);        o.normal1=v.normal;        o.vertex1=v.vertex;           return o;        }        float4 frag(v2f IN):COLOR{        float4 col= UNITY_LIGHTMODEL_AMBIENT;        float3 N=UnityObjectToWorldNormal(IN.normal1);        float3 L=normalize(WorldSpaceLightDir(IN.vertex1));        float diffuseScale=saturate(dot(N,L));        col+=_LightColor0*diffuseScale;        //Phong运算        //float3 V=normalize(WorldSpaceViewDir(IN.vertex1));        //float3 R=2*dot(N,L)*N-L;        //float specularScale=saturate(dot(R,V));        //col+=_SpecularColor*pow(specularScale,_Shininess);        //BlinnPhong运算        float3 V=normalize(WorldSpaceViewDir(IN.vertex1));        float3 H=normalize(V+L);        float specularScale=saturate(dot(H,V));        col+=_SpecularColor*pow(specularScale,_Shininess);        return col;        }ENDCG}}FallBack "Diffuse"}


4、从上面的代码,可以看到,上面并没有阴影的描述,所以需要增加一个阴影,这个阴影用光照深度来描述(atten),将上面的代码再修改一下

Shader "Custom/FragmentShader" {properties{_SpecularColor("SpecularColor",color)=(1,1,1,1)_Shininess("Shininess",range(1,8))=4}SubShader {PASS{tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert          #pragma fragment frag        #pragma multi_compile_fwdbase        #include "UnityCG.cginc"        #include "Lighting.cginc"        #include "AutoLight.cginc"        float4 _SpecularColor;        float _Shininess;        struct v2f{        float4 pos:POSITION;        float3 normal1:TEXCOORD0;        float4 vertex1:TEXCOORD1;        LIGHTING_COORDS(2,3)        };          v2f vert(appdata_base v){        v2f o;        o.pos=UnityObjectToClipPos(v.vertex);        o.normal1=v.normal;        o.vertex1=v.vertex;        TRANSFER_VERTEX_TO_FRAGMENT(o)           return o;        }        float4 frag(v2f IN):COLOR{        float4 col= UNITY_LIGHTMODEL_AMBIENT;        float3 N=UnityObjectToWorldNormal(IN.normal1);        float3 L=normalize(WorldSpaceLightDir(IN.vertex1));        float diffuseScale=saturate(dot(N,L));        col+=_LightColor0*diffuseScale;        //Phong运算        //float3 V=normalize(WorldSpaceViewDir(IN.vertex1));        //float3 R=2*dot(N,L)*N-L;        //float specularScale=saturate(dot(R,V));        //col+=_SpecularColor*pow(specularScale,_Shininess);        //BlinnPhong运算        float3 V=normalize(WorldSpaceViewDir(IN.vertex1));        float3 H=normalize(V+L);        float specularScale=saturate(dot(H,V));        col+=_SpecularColor*pow(specularScale,_Shininess);        //增加阴影        float atten=LIGHT_ATTENUATION(IN);        col.rgb*=atten;        return col;        }ENDCG}}FallBack "Diffuse"}
阴影效果如下:



从上面的效果可以看出,背面比较黑,如果想背面也显示不那么黑,就可以用Half Lambert光照模型

Shader "Custom/Shader" {Properties {_Color ("Color", Color) = (1,1,1,1)}SubShader {pass{Tags { "RenderType"="Opaque" }LOD 200CGPROGRAM// Physically based Standard lighting model, and enable shadows on all light types// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "UnityCG.cginc"struct v2f {float4 pos:SV_POSITION;float3 V:Texcoord0;float3 N:Texcoord1; };fixed4 _Color;v2f vert(appdata_base v){ v2f o; o.pos=UnityObjectToClipPos(v.vertex); o.N=v.normal; o.V=WorldSpaceLightDir( v.vertex); return o;}float frag(v2f IN):color {float4 col;float diff=dot(IN.N,IN.V)*0.5+0.5;col=_LightColor0*diff;return col; }ENDCG}}FallBack "Diffuse"}


渐变纹理(摘自http://blog.csdn.net/u013354943/article/details/52788010)

Shader "LT/RampTexture"{    Properties    {        _Color("Color Tint",Color) = (1,1,1,1)        _RampTex("Ramp Tex",2D) = "white" {}    //渐变纹理        _Specular("Specular",Color) = (1,1,1,1)        _Gloss("Gloss",Range(8.0,256)) = 20    }    SubShader    {        Pass        {            Tags { "LightMode"="ForwardBase" }//定义该Pass在光照流水线中的角色光照模式注意要设置为Forward            CGPROGRAM            #pragma vertex vert            #pragma fragment frag                        #include "UnityCG.cginc"            #include "Lighting.cginc"            fixed4 _Color;            sampler2D _RampTex;            fixed4 _Specular;            float4 _RampTex_ST;            float _Gloss;            struct appdata            {                float4 vertex : POSITION;                float2 uv : TEXCOORD0;                float3 normal : NORMAL;            };            struct v2f            {                float2 uv : TEXCOORD0;                float4 vertex : SV_POSITION;                float3 worldNormal : TEXCOORD1;                float3 worldPos : TEXCOORD2;            };                        v2f vert (appdata v)            {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                o.worldNormal = UnityObjectToWorldNormal(v.normal);                o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;                o.uv = TRANSFORM_TEX(v.uv, _RampTex);   //内置的宏计算平铺和偏移位置                return o;            }                        fixed4 frag (v2f i) : SV_Target            {                fixed3 worldNormal =normalize(i.worldNormal);                fixed3 worldLightDir =normalize(UnityWorldSpaceLightDir(i.worldPos));                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz ;                                //法线和方向和光照方向的点积做一次0.5倍的缩放和一个0.5大小的偏移来计算兰伯特部分halfLambert,得到结果在【0,1】之间                fixed halfLambert = 0.5 *dot(worldNormal,worldLightDir) +0.5;                //用halfLambert构建一个纹理坐标,并对这个纹理坐标对_RampTex进行采样。                //由于_RampTex实际是一个一维纹理(纵轴方向上颜色不变),所以纹理坐标的UV方向我们都使用了halfLambert,                fixed3 diffuseColor = tex2D(_RampTex, fixed2(halfLambert,halfLambert)).rgb * _Color.rgb;                //漫反射颜色 = 渐变纹理采样得到的颜色 * 材质颜色                fixed3 diffuse  = _LightColor0 * diffuseColor ;                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));                fixed3 halfDir = normalize(worldLightDir + viewDir);                            fixed3 specular = _LightColor0.rbg * _Specular.rgb *pow(max(0,dot                       (worldNormal,halfDir)),_Gloss);                fixed4 col = fixed4( diffuse+  specular + ambient,1.0);                return col;            }            ENDCG        }    }    Fallback "Specular"}






阅读全文
0 0
原创粉丝点击