Shader_2

LOD

LOD 很简单,它是Level of Detail的缩写,在这里例子里我们指定了其为200(其实这是Unity的内建Diffuse着色器的设定值)。这个数值决定了我们能用什么样的 Shader。在Unity的Quality Settings中我们可以设定允许的最大LOD,当设定的LOD小于SubShader所指定的LOD时,这个SubShader将不可用。Unity 内建Shader定义了一组LOD的数值,我们在实现自己的Shader的时候可以将其作为参考来设定自己的LOD数值,这样在之后调整根据设备图形性能 来调整画质时可以进行比较精确的控制。

  • VertexLit及其系列 = 100
  • Decal, Reflective VertexLit = 150
  • Diffuse = 200
  • Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
  • Bumped, Specular = 300
  • Bumped Specular = 400
  • Parallax = 500
  • Parallax Specular = 600
  • Shader本体

    前面杂项说完了,终于可以开始看看最主要的部分了,也就是将输入转变为输出的代码部分。为了方便看,请容许我把上面的SubShader的主题部分抄写一遍

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CGPROGRAM
    #pragma surface surf Lambert
      
    sampler2D _MainTex;
      
    struct Input {
       float2 uv_MainTex;
    };
      
    void surf (Input IN, inout SurfaceOutput o) {
       half4 c = tex2D (_MainTex, IN.uv_MainTex);
       o.Albedo = c.rgb;
       o.Alpha = c.a;
    }
    ENDCG
    还是逐行来看,首先是CGPROGRAM。这是一个开始标记,表明从这里开始是一段CG程序(我们在写Unity的Shader时用的是Cg/HLSL语言)。最后一行的ENDCG与CGPROGRAM是对应的,表明CG程序到此结束。

接下来是是一个编译指令:#pragma surface surf Lambert,它声明了我们要写一个表面Shader,并指定了光照模型。它的写法是这样的

#pragma surface surfaceFunction lightModel [optionalparams]

  • surface - 声明的是一个表面着色器
  • surfaceFunction - 着色器代码的方法的名字
  • lightModel - 使用的光照模型。
我们声明了一个表面着色器,实际的代码在surf函数,使用Lambert(也就是普通的diffuse)作为光照模型。
//=========!!!!!!!!!!!!
我很想知道还有哪些其他写法,
这个 猫都能学会的Unity3D Shader入门指南 实在是看不下去了,实在是太概括了
换教材!
http://www.jianshu.com/p/7b9498e58659
//=========

Pass的Tag

Shader "ShaderLab Tutorials/TestShader" {
    SubShader {
        Pass
        {
            Tags{ "LightMode"="ForwardBase" }
            //...
        }
    }
}

和SubShader有自己专属的Tag类似,Pass也有Pass专属的Tag。
其中最重要Tag是 "LightMode",指定Pass和Unity的哪一种渲染路径(“Rendering Path”)搭配使用。这里需要描述的Tag取值可包括:

  • Always,永远都渲染,但不处理光照
  • ShadowCaster,用于渲染产生阴影的物体
  • ShadowCollector,用于收集物体阴影到屏幕坐标Buff里。

其他渲染路径相关的Tag详见下面章节“Unity渲染路径种类”。
具体所有Tag取值,可参考ShaderLab syntax: Pass Tags

!!!!!!!!!!!!!!!!!!还有哪些啊,说全啊!!!!!!!!!!!!!!!!!!

FallBack

Shader "ShaderLab Tutorials/TestShader"{
    SubShader { Pass {} }

    FallBack "Diffuse" // "Diffuse"即Unity预制的固有Shader
    // FallBack Off //将关闭FallBack
}

当本Shader的所有SubShader都不支持当前显卡,就会使用FallBack语句指定的另一个Shader。FallBack最好指定Unity自己预制的Shader实现,因其一般能够在当前所有显卡运行。

Shader中的数据类型

有3种基本数值类型:floathalffixed
这3种基本数值类型可以再组成vector和matrix,比如half3是由3个half组成、float4x4是由16个float组成。

  • float:32位高精度浮点数。
  • half:16位中精度浮点数。范围是[-6万, +6万],能精确到十进制的小数点后3.3位。
  • fixed:11位低精度浮点数。范围是[-2, 2],精度是1/256。
数据类型影响性能
  • 精度够用就好。
    • 颜色和单位向量,使用fixed
    • 其他情况,尽量使用half(即范围在[-6万, +6万]内、精确到小数点后3.3位);否则才使用float
  • 不要将低精度fixed类型转换为更高的精度,否则会产生性能问题。
  • 低精度fixed不要使用“swizzle”(即形如myFixed4.xyzwmyFixed2.xyxy,中文不知咋译,“搅和
    访问”?),否则会产生性能问题。

    作者donaldwu说:swizzle在编写Shader里是经常用到的,但到底怎样才算swizzle?myFixed4.x算不算?myFixed4.xyzw算不算?myFixed4.xyxy算不算?还是都算?
    这个目前没有找到权威的定义,所以为了不要影响效率,建议fixed尽量不要出现上面任意一种形式。

Shader形态

Shader形态之1:固定管线

固定管线是为了兼容老式显卡。都是顶点光照。之后固定管线可能是被Unity抛弃的功能,所以最好不学它、当它不存在。特征是里面出现了形如下面Material块、没有CGPROGRAMENDCG块。

Shader "ShaderLab Tutorials/TestShader"
{
    Properties {
    _Color ("My Color", Color) = (.34, .85, .92, 1) // color
    }

    // Fixed Pipeline
    SubShader
    {
        Pass
        {
            Material{
            Diffuse [_Color]
            Ambient [_Color]
            }

            Lighting On
        }
    }
}

Shader形态之2:可编程Shader

Shader "ShaderLab Tutorials/TestShader"
{
    Properties {}

    SubShader
    {
        Pass
        {
          // ... the usual pass state setup ...

          CGPROGRAM
          // compilation directives for this snippet, e.g.:
          #pragma vertex vert
          #pragma fragment frag

          // the Cg/HLSL code itself
          float4 vert(float4 v:POSITION) : SV_POSITION{
              return mul(UNITY_MATRIX_MVP, v);
          }
          float4 frag() : COLOR{
              return fixed4(1.0, 0.0, 0.0, 1.0);
          }
          ENDCG
          // ... the rest of pass setup ...
          }
    }
}
  • 功能最强大、最自由的形态。
  • 特征是在Pass里出现CGPROGRAMENDCG
  • 编译指令#pragma。详见官网Cg snippets。其中重要的包括:
编译指令 示例/含义
#pragma vertex name
#pragma fragment name
替换name,来指定Vertex Shader函数、Fragment Shader函数。
#pragma target name 替换name(为2.03.0等)。设置编译目标shader model的版本。
#pragma only_renderers name name ...
#pragma exclude_renderers name name...
#pragma only_renderers gles gles3
#pragma exclude_renderers d3d9 d3d11 opengl
只为指定渲染平台(render platform)编译
  • 引用库。通过形如#include "UnityCG.cginc"引入指定的库。常用的就是UnityCG.cginc了。其他库详见官网Built-in shader include files
  • ShaderLab内置值。Unity给Shader程序提供了便捷的、常用的值,比如下面例子中的UNITY_MATRIX_MVP就代表了这个时刻的MVP矩阵。详见官网ShaderLab built-in values
  • Shader输入输出参数语义(Semantics)。在管线流程中每个阶段之间(比如Vertex Shader阶段和FragmentShader阶段之间)的输入输出参数,通过语义字符串,来指定参数的含义。常用的语义包括:COLORSV_PositionTEXCOORD[n]。完整的参数语义可见HLSL Semantic(由于是HLSL的连接,所以可能不完全在Unity里可以使用)。
  • 特别地,因为Vertex Shader的的输入往往是管线的最开始,Unity为此内置了常用的数据结构:
数据结构 含义
appdata_base vertex shader input with position, normal, one texture coordinate.
appdata_tan vertex shader input with position, normal, tangent, one texture coordinate.
appdata_full vertex shader input with position, normal, tangent, vertex color and two texture coordinates.
appdata_img vertex shader input with position and one texture coordinate.
!!!!!!!!!!!!!!!不行了,又看不懂了.....
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值