查看: 1458|回复: 0
打印 上一主题 下一主题

[其他] Unity Surface Shader总结(转载)

[复制链接]
may    

8830

主题

81

听众

7万

积分

首席设计师

Rank: 8Rank: 8

纳金币
52336
精华
343

最佳新人 热心会员 灌水之王 活跃会员 突出贡献 荣誉管理 论坛元老

跳转到指定楼层
楼主
发表于 2016-2-21 07:27:45 |只看该作者 |倒序浏览
先看一个简单的surface shader:
  1. Shader "Custom/Diffuse Texture" {  
  2.     Properties {
  3.         _MainTex ("Base (RGB)", 2D) = "white" {}
  4.     }
  5.     SubShader {
  6.         Tags { "RenderType"="Opaque" }
  7.         LOD 200

  8.         CGPROGRAM
  9.         #pragma surface surf Lambert

  10.         sampler2D _MainTex;

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

  14.         void surf (Input IN, inout SurfaceOutput o) {
  15.             half4 c = tex2D (_MainTex, IN.uv_MainTex);
  16.             o.Albedo = c.rgb;
  17.             o.Alpha = c.a;
  18.         }
  19.         ENDCG
  20.     }
  21.     FallBack "Diffuse"
  22. }
复制代码
每段分析总结:
1.Properties{}
  _Name("Display Name", type) = defaultValue[{options}]
_Name - 属性的名字,简单说就是变量名,在之后整个Shader代码中将使用这个名字来获取该属性的内容;
Display Name - 这个字符串将显示在Unity的材质编辑器中作为Shader的使用者可读的内容;
type - 这个属性的类型,可能的type所表示的内容有以下几种:
    Color - 一种颜色,由RGBA(红绿蓝和透明度)四个量来定义;
    2D - 一张2的阶数大小(256,512之类)的贴图。这张贴图将在采样后被转为对应基于模型UV的每个像素的颜色,最终被显示出来;
    Rect - 一个非2阶数大小的贴图;
    Cube - 即Cube map texture(立方体纹理),简单说就是6张有联系的2D贴图的组合,主要用来做反射效果(比如天空盒和动态反射),也会被转换为对应点的采样;
    Range(min, max) - 一个介于最小值和最大值之间的浮点数,一般用来当作调整Shader某些特性的参数(比如透明度渲染的截止值可以是从0至1的值等);
    Float - 任意一个浮点数;
    Vector - 一个四维数;
defaultValue 定义了这个属性的默认值,
    Color - 以0~1定义的rgba颜色,比如(1,1,1,1);
    2D/Rect/Cube - 对于贴图来说,默认值可以为一个代表默认tint颜色的字符串,可以是空字符串或者"white","black","gray","bump"中的一个
    Float,Range - 某个指定的浮点数
    Vector - 一个4维数,写为 (x,y,z,w)
{option}它只对2D,Rect或者Cube贴图有关 ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal

2.Tags{}  Tags { "RenderType"="Opaque" } 告诉了系统应该在渲染非透明物体时调用我们
  "RenderType" = "Transparent",表示渲染含有透明效果的物体时调用
  "IgnoreProjector"="True"(不被Projectors影响)
  "ForceNoShadowCasting"="True"(从不产生阴影)
  "Queue"="xxx"(指定渲染顺序队列)
   预定义的Queue有:
       Background - 最早被调用的渲染,用来渲染天空盒或者背景
       Geometry - 这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
       AlphaTest - 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
       Transparent - 以从后往前的顺序渲染透明物体
       Overlay - 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)


3.LOD
  LOD很简单,它是Level of Detail的缩写

4.#pragma surface surfaceFunction lightModel [optionalparams]
  有3种类型的光照模型的原型我们可以选择:
     1.half4 LightingName(SurfaceOutput s, half3 lightDir,half atten){} 在前置渲染不需要观察者方向的场合
     2.half4 LightingName(SurfaeOutput s, half3 lightDir,half3 viewDir,half atten){} 在前置渲染需要观察者方向的场合
     3.half4 LightingName_PressPass(SurfaceOutput s,half4 light){} Unity被配置成延迟渲染的时候需要的

5.sampler2D _MainTex
  更简单地理解,sampler2D就是GLSL中的2D贴图的类型,相应的,还有sampler1D,sampler3D,samplerCube等等格式

6.写surface shader,我们先是:
 1.在SubShader中用#pragma surface surf_func来定义要用到的方法;
 2.上述方法第一个参数是一个struct Input,里面可以填上shader需要从外部送进来的数据,比如UV数据;
  Unity运行的时候,会根据这个结构知道该给本shader喂哪些数据。Input中可以填的值:
  float3 viewDir
  float4 变量用COLOR这个语义关键词来后置修饰
  float4 screenPos
  float3 worldPos
  float3 worldRefl
       float3 worldNormal
  除了这些值,用户可以让Unity喂入uv值,这个只要在对应的贴图的名字前面加上uv_这个前缀。
  第二个参数是一个Unity预定义的结构,前面用inout修饰,表示这个结构是个输入输出都会用到的东西。
  struct SurfaceOutput
  {
            fixed3 Albedo;     //像素的颜色
            fixed3 Normal;    //像素的法向值
            fixed3 Emission; //像素的发散颜色
            half Specular;     //像素的镜面高光
            fixed Gloss;        //像素的发光强度
            fixed Alpha;       //像素的透明度
  }



分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏1 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-28 17:23 , Processed in 0.096957 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部