Unity实现标准光照模型的Shader代码

来源:互联网 发布:淘宝大学vip课有效果吗 编辑:程序博客网 时间:2024/05/16 11:49

本文展示实现标准光照模型(只关心场景里最亮的那一个平行光光源)下的光照效果。即自发光(Emissive)、环境光(Ambient)、漫反射(Diffuse)、高光(Specular)这四种光效的叠加,其中高光有两种实现方式Phong和Blinn-Phong,选择调用方法即可。

下面介绍面板参数:

_XXX_Color表示材质反射该光照的颜色,如果是黑色则表示忽略该光照;

_Calculate_Vertex决定使用顶点光照还是像素光照(大于1还是小于1);

_Lambert_Enhance是漫反射光照增强,如果值为0.5,就是常说的Half Lambert光照模型;

_Gloss是高光反射扩散度,值越小光斑越大。

下面分别是顶点光照和像素光照的效果:


最后上Shader代码:

Shader "Test/S001"{Properties{_Calculate_Vertex ("_Calculate_Vertex", Range (0, 2)) = 0_Emissive_Color("_Emissive_Color", Color) = (1, 1, 1, 1)_Ambient_Color("_Ambient_Color", Color) = (1, 1, 1, 1)_Diffuse_Color("_Diffuse_Color", Color) = (1, 1, 1, 1)_Specular_Color("_Specular_Color", Color) = (1, 1, 1, 1)_Lambert_Enhance ("_Lambert_Enhance", Range (-1, 1)) = 0_Gloss ("_Gloss", Range (1, 256)) = 1}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;float4 tangent : TANGENT;float2 uv : TEXCOORD0;float4 color : COLOR;};struct v2f{float4 vertex : SV_POSITION;fixed3 wnormal : TEXCOORD4;float4 wvertex : TEXCOORD5;float2 uv : TEXCOORD0;fixed3 cFinal : COLOR0;fixed3 cVertex : COLOR1;fixed3 cEmissive : COLOR2;fixed3 cAmbient : COLOR3;fixed3 cDiffuse : COLOR4;fixed3 cSpecular : COLOR5;};fixed4 _Emissive_Color;fixed4 _Ambient_Color;fixed4 _Diffuse_Color;fixed4 _Specular_Color;fixed _Lambert_Enhance;half _Gloss;int _Calculate_Vertex;//---------------------------------------------------------------------------------------------------------------------------------fixed3 CalculateEmissiveColor(){return _Emissive_Color;}fixed3 CalculateAmbientColor(){return UNITY_LIGHTMODEL_AMBIENT * _Ambient_Color;}fixed3 CalculateDiffuseColor(float3 normalDir, float3 lightDir, fixed3 lightColor, fixed3 diffuseColor){return saturate(dot(normalize(normalDir), normalize(lightDir)) * (1 - _Lambert_Enhance) + _Lambert_Enhance) * lightColor * diffuseColor;}fixed3 CalculateSpecularColor_Phong(float3 normalDir, float3 lightDir, float3 viewDir, fixed3 lightColor, fixed3 specularColor){normalDir = normalize(normalDir);lightDir = normalize(lightDir);viewDir = normalize(viewDir);float3 reflectDir = normalize(dot(normalDir, lightDir) * 2 * normalDir - lightDir);//reflectDir = normalize(reflect(-lightDir, normalDir)); 同上.return pow(saturate(dot(reflectDir, viewDir)), _Gloss) * lightColor * specularColor;}fixed3 CalculateSpecularColor_BlinnPhong(float3 normalDir, float3 lightDir, float3 viewDir, fixed3 lightColor, fixed3 specularColor){normalDir = normalize(normalDir);lightDir = normalize(lightDir);viewDir = normalize(viewDir);float3 midDir = normalize(lightDir + viewDir);return pow(saturate(dot(midDir, normalDir)), _Gloss) * lightColor * specularColor;}//---------------------------------------------------------------------------------------------------------------------------------v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;o.cVertex = v.color;float3 wnormal = mul(unity_ObjectToWorld, v.normal);float3 wvertex = mul(unity_ObjectToWorld, v.vertex);if (_Calculate_Vertex > 0){o.cEmissive = CalculateEmissiveColor();o.cAmbient = CalculateAmbientColor();o.cDiffuse = CalculateDiffuseColor(wnormal, _WorldSpaceLightPos0, _LightColor0, _Diffuse_Color);o.cSpecular = CalculateSpecularColor_BlinnPhong(wnormal, _WorldSpaceLightPos0, _WorldSpaceCameraPos.xyz - wvertex, _LightColor0, _Specular_Color);o.cFinal = o.cEmissive + o.cAmbient + o.cDiffuse + o.cSpecular;}o.wnormal = wnormal;o.wvertex = float4(wvertex, 1);return o;}fixed4 frag (v2f i) : SV_Target{float3 wnormal = normalize(i.wnormal);float3 wvertex = i.wvertex;if (_Calculate_Vertex < 1){i.cEmissive = CalculateEmissiveColor();i.cAmbient = CalculateAmbientColor();i.cDiffuse = CalculateDiffuseColor(wnormal, _WorldSpaceLightPos0, _LightColor0, _Diffuse_Color);i.cSpecular = CalculateSpecularColor_BlinnPhong(wnormal, _WorldSpaceLightPos0, _WorldSpaceCameraPos.xyz - wvertex, _LightColor0, _Specular_Color);i.cFinal = i.cEmissive + i.cAmbient + i.cDiffuse + i.cSpecular;}return fixed4(i.cFinal, 1);}ENDCG}}}
参考:《Unity Shader 入门精要》,感谢作者妹子。

0 0
原创粉丝点击