【风宇冲】Unity3D教程宝典之Shader篇:第十四讲Surface Shader

创文章如需转载请注明:转载自 风宇冲Unity3D教程学院

                              Shader第十四讲   Surface  Shader

   用Shader来实现光照是比较复杂的,有不同的光类型,不同的阴影选项,不同的Render Path(forward和Deferred)。 Unity只是把光照模型封装处理了,Shader的代码还是用CG/HLSL编写的。


                        例一:最简单的Surface Shader

 

  1. Shader "Custom/T_3_0" {
  2. Properties {
  3. _MainTex ("Base (RGB)", 2D) = "white" {}
  4. }
  5. SubShader {
  6. CGPROGRAM
  7. #pragma surface surf Lambert

  8. sampler2D _MainTex;

  9. struct Input {
  10. float2 uv_MainTex;
  11. } ;

  12. void surf (Input IN, inout SurfaceOutput o) {
  13. half4 c = tex2D (_MainTex, IN.uv_MainTex);
  14. o.Albedo = c.rgb;
  15. o.Alpha = c.a;
  16. }
  17. ENDCG
  18. }  
  19. }
表面处理函数从顶点处理函数(这里自动顶点处理)接收参数Input IN,输出SurfaceOutput o至光照模型(这里是Lambert)。
这里我们就做了三件事:
(1)通过uv取得了贴图对应uv的颜色c
  (2)把c.rgb赋给o.Albedo
  (3) 把c.a赋给o.Alpha
这就完成了。之后让任一物体使用该Shader,则不管加什么光都能正确显示。真的很简单!


                               表面处理函数surf的输入及输出

(1)输入
  1. struct Input {
  2. float2 uv_MainTex;
  3. float3 viewDir;
  4. float4 anyName:COLOR;
  5. float4 screenPos;
  6.         float3 worldPos;
  7. float3 worldRefl;

  8. } ;
uv_MainTex: uv
viewDir: 入视角
screenPos:裁剪空间位置
worldPos:世界空间位置


(2)输出

 

  • struct SurfaceOutput {
  •     half3 Albedo;
  •     half3 Normal;
  •     half3 Emission;
  •     half Specular;
  •     half Gloss;
  •     half Alpha;
  • };
Albedo:漫反射颜色
Normal: 法线
Emission:自发光颜色
Specular:镜面反射系数
Gloss:
Alpha:透明值

                                         Surface Shader参数

Surface Shader可以通过加参数实现额外的控制,例如加顶点处理函数,alpha混合等。
注意:
如果使用的 光照模型是Unity自带的Lambert或者BlinnPhong:
alpha混合,alpha混合等功能必须使用Surface Shader参数。
之前例如AlphaTest Greater 0.3 等代码就不能再加了。如果加了的话,光照失效,物体为一片漆黑。

如果使用的光照模型是自定义光照模型
只要在surf中给o.Alpha正常赋值(如赋贴图颜色的a值),那么之前例如AlphaTest Greater 0.3 等代码依然可以照常使用。具体相关代码可以参考下一讲中的代码。


(1)alpha混合
直接加参数Alpha即可

#pragma surface surf BlinnPhong alpha

(2)alphatest

加入一个变量,这里起名为_Cutoff, 然后在#pragma surface结尾处加上alphatest:_Cutoff。

效果是alpha值大于_Cutoff时,才会输出颜色

 

 

  1. Shader "Custom/T_3_0" {
  2. Properties {
  3. _MainTex ("Base (RGB)", 2D) = "white" {}
  4. _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
  5. }
  6. SubShader {
  7. CGPROGRAM
  8. #pragma surface surf Lambert alphatest:_Cutoff
  9. sampler2D _MainTex;

  10. struct Input {
  11. float2 uv_MainTex;
  12. } ;

  13. void surf (Input IN, inout SurfaceOutput o) {
  14. half4 c = tex2D (_MainTex, IN.uv_MainTex);
  15. o.Albedo = c.rgb;
  16. o.Alpha = c.a;
  17. }
  18. ENDCG
  19. }  
  20. }

(3)顶点函数

例:臃肿的模型

实现方法,将顶点向法线方向延伸一段距离

【风宇冲】Unity3D教程宝典之Shader篇:第十四讲Surface <wbr>Shader

 

 

  1.   Shader "Example/Normal Extrusion" {
  2.     Properties {
  3.       _MainTex ("Texture", 2D) = "white" {}
  4.       _Amount ("Extrusion Amount", Range(-1,1)) = 0.5
  5.     }
  6.     SubShader {
  7.       Tags { "RenderType" = "Opaque" }
  8.       CGPROGRAM
  9.       #pragma surface surf Lambert vertex:vert
  10.       struct Input {
  11.           float2 uv_MainTex;
  12.       };
  13.       float _Amount;
  14.       void vert (inout appdata_full v) {
  15.           v.vertex.xyz += v.normal * _Amount;
  16.       }
  17.       sampler2D _MainTex;
  18.       void surf (Input IN, inout SurfaceOutput o) {
  19.           o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
  20.       }
  21.       ENDCG
  22.     
  23.     Fallback "Diffuse"
  24.   }

(4)finalcolor

finalcolor:ColorFunction

对颜色输出作最后的更改

 

 
 
  1. Shader "Example/Tint Final Color" {
  2.     Properties {
  3.       _MainTex ("Texture", 2D) = "white" {}
  4.       _ColorTint ("Tint", Color) = (1.0, 0.6, 0.6, 1.0)
  5.     }
  6.     SubShader {
  7.       CGPROGRAM
  8.       #pragma surface surf Lambert finalcolor:mycolor
  9.       struct Input {
  10.           float2 uv_MainTex;
  11.       };
  12.       fixed4 _ColorTint;
  13.       void mycolor (Input IN, SurfaceOutput o, inout fixed4 color)
  14.       {
  15. //在这里对最后输出的颜色color进行修改
  16.           color *= _ColorTint;
  17.       }
  18.       sampler2D _MainTex;
  19.       void surf (Input IN, inout SurfaceOutput o) {
  20.            o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
  21.       }
  22.       ENDCG
  23.     } 
  24.  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值