shader学习基础之四(语法规范以及光照模型)

来源:互联网 发布:剑网3菊花插件dbm数据 编辑:程序博客网 时间:2024/06/05 11:04

基础篇(四)

shader结构解析:

Shader “Custom/Diffuse Texture” { 着色器 “名称”
Properties
属性定义

{                  _Color ("Color", Color) = (1,1,1,1)                                        内部变量名("界面名称",属性类型)=属性默认值;                 _MainTex ("Albedo (RGB)", 2D) = "white" {}                 _Glossiness ("Smoothness", Range(0,1)) = 0.5                 _Metallic ("Metallic", Range(0,1)) = 0.0 }

属性类型:
Range(min,max)=number 一个介于最小值和最大值之间的浮点数,一般用来当作调整Shader某些特性的参数(比如透明度渲染的截止值可以是从0至1的值等);
Color=(number,number,number,number) 一种颜色,由RGBA(红绿蓝和透明度)四个量来定义;
2D=”name”{options} 一张2的阶数大小(256,512之类)的贴图。这张贴图将在采样后被转为对应基于模型UV的每个像素的颜色,最终被显示出来;
Rect=”name”{options} 一个非2阶数大小的贴图
Cube=”name”{options} 即Cube map texture(立方体纹理),简单说就是6张有联系的2D贴图的组合,主要用来做反射效果(比如天空盒和动态反射),也会被转换为对应点的采样;
Vector=(number,number,number,number) 定义一个四维数
Float=number 定义任意一个浮点数;
{option} 可能的选择有ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal中的一个,这些都是OpenGL中TexGen的模式
name可以是空字符串或者“white”,”black”,”gray”,”bump”中的一个


SubShader {
子着色器


tags 着色器修饰 硬件将通过判定这些标签来决定什么时候调用该着色器。包括以下类型:

RenderType 渲染类型:
Opaque: 不透明。最常用一种。(Normall,Selfllluminated,Reflective,terrain shaders);
Transparent: 半透明物体。(Transparent,Particle,Font,terrain addItive pass shaders);
TransparentCutout: 透明遮罩shader.(Transparent Cutout,two pass vegetation shaders)
Background: 天空shaders;
Overlay :GUITexture,Halo,Flare shaders.
TreeOpaque: terrain engine tree shaders.
TreeTransparentCutout: terrain engine tree levaes.
TreeBillboard: terrain engine billboarded trees.
Grass: terrain engine grass
GrassBillboard: terrain engine billboarded grass.

Queue 指定渲染顺序队列:
Background 通常用于SkyBox;
Geometry 最常用的一种,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
AlphaTest - 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
Transparent 以从后往前的顺序渲染透明物体
Overlay 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)


“ForceNoShadowCasting”=”True” 从不产生阴影


“IgnoreProjector”=”True” 不被Projectors影响


Tags { "RenderType"="Opaque" }   

LOD是Level of Detail的缩写,在这里例子里我们指定了其为200(其实这是Unity的内建Diffuse着色器的设定值)。这个数值决定了我们能用什么样的Shader。

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      

LOD 200


这里还会标注RenderState.设定显示各种状态:
Cull ( Back,Front,Off) 设置多边形剔除模式
ZTest (Less,Greater,LEqual,GEqua,Equal,NotEqual,Always) 默认是LEqual.
ZWrite (On,Off) 设置深度写模式,是否此物体的像素深度会被记录(默认记录) Off,通常用于半透明物体。
AlphaTest(Less,Greater,LEqual,GEqual,Equal,NotEqual,Always) 开启alpha测试
Blend SourceB./endMode DestB/endMode 设置alpha混合模式。(以下为相关属性说明)
One 值为1,使用此设置来让源或是目标颜色完全的通过。
Zero 值为0 ,使用此设置来删除源或目标值。
SroColor 此阶段的值是乘以源颜色的值。
SrcAlpha 此阶段的值是乘以源alpha的值。
DstColor 此阶段的值是乘以帧缓冲区源颜色的值。
DstAlpha 此阶段的值是乘以帧缓冲区源alpha的值。
OneMinusSrcColor 此阶段的值是乘以(1-source color)
OneMinusSrcAlpha 此阶段的值是乘以(1-source alpha)
OneMinusDstColor 此阶段的值是乘以(1-destination color)
OneMinusDstAlpha 此阶段的值是乘以(1-destination alpha)
例如:

      Blend SrcAlpha OneMinusSrcAlpha  //Alpha blending       Blend One One  //Additive       Blend One OneMinusDstColor// Soft Additive       Blend  DstColor Zero  //Multiplicative       Blend DstColor SrcColor  //2x Multiplicative 

Fog { Fog Bolck} 设置雾效参数 以下相关属性说明:
Mode(off,Global,Linear,Exp,Exp2) 模式
Color(number,number,number,number) 颜色
Density number 密度
Range number 范围
ColorMask RGB(A,0) 设置颜色写遮罩。设置为0将关闭所有颜色通道的渲染
Offset name1,name2 设置深度偏移
Color name 设置当顶点光照关闭时所使用的颜色
SeparateSpecular (On,Off) 开启或关闭顶点光照相关的平行高光颜色
ColorMaterial (AmbientAndDiffuse,Emission) 当计算顶点光照时使用每顶点颜色
Material { Material Bolck} 定义一个使用顶点光照管线的材质
Lighting (On,Off) 开启或关闭顶点光照

开始标记,表明从这里开始是一段CG程序


CGPROGRAM
Physically based Standard lighting model, and enable shadows on all light types


声明编译指令: 声明一个shader方法。(我们要写一个表面Shader,方法名是”surf”,使用Standard fullforwardshadows作为光照模型)
#pragma surface name 声明一个以name为名字的函数表面shader;
#pragma vertex name 声明一个个以name为名字的函数的顶点程序
#pragma fragment name- 声明一个个以name为名字的函数的片段程序。
#pragma fragmentoption option - 添加选项到编译的OpenGL 片段程序。 通过 ARB 片段程序 可以查询到所允许的规范的选项列表。 这个指令对顶点程序或者不是以OpenGL为编译目标的程序无效。
#pragma target name -着色器目标编译。详情请参考 着色器目标。
#pragma only_renderers space separated names - 仅用给定的渲染器编译着色器。默认情况下用所有的渲染器都编译着色器。
#pragma exclude_renderers space separated names -不用给定的渲染器编译着色器。 默认情况下用所有的渲染器都编译着色器。
#pragma glsl - 用桌面OpenGL平台编译着色器时,转换成GLSL里面的Cg/HLSL(而不是默认设置的ARB顶点/片段程序)。


#pragma surface surf Standard fullforwardshadows
Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0 //编译着色器模式3.0


2D纹理类型(变量名与属性定义相同)
属性中Cloror和Vector类型对应CG中float4类型; //属性中Range和Float对应CG中float或half类型;
属性中2D纹理对应CG中Sampler2D类型;
属性中Cube纹理对应GC中SamplerCUBEH类型;
属性中Rect纹理对应GC中SamplerRect类型;


sampler2D _MainTex;   

struct结构体

unity自定义的顶点输入结构体,当然我们也可以自定义struct appdata_base {     float4 vertex : POSITION;     float3 normal : NORMAL;     float4 texcoord : TEXCOORD0;  };  struct appdata_tan {    float4 vertex : POSITION;    float4 tangent : TANGENT;    float3 normal : NORMAL;    float4 texcoord : TEXCOORD0;  };  struct appdata_full {    float4 vertex : POSITION;    float4 tangent : TANGENT;    float3 normal : NORMAL;    float4 texcoord : TEXCOORD0;    float4 texcoord1 : TEXCOORD1;    fixed4 color : COLOR;   #if defined(SHADER_API_XBOX360)   half4 texcoord2 : TEXCOORD2;   half4 texcoord3 : TEXCOORD3;   half4 texcoord4 : TEXCOORD4;   half4 texcoord5 : TEXCOORD5;  #endif }; 

//顶点输出结构体struct v2f{    float2 uv : TEXCOORD0;    float3 worldLightDir:TEXCOORD1;    float3 worldViewDir:TEXCOORD2;    float3 worldNormal:TEXCOORD3;    float4 vertex : SV_POSITION;};

half _Glossiness; //half类型指的是半精度浮点数,精度最低,运算性能相对比高精度浮点数高一些,因此被大量使用。

 half _Metallic;  fixed4 _Color;

顶点入口函数 appdata_full—unity自带的输入结构

v2f vert (appdata_full v){                v2f o;                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);                //计算世界空间中的光的方向                o.worldLightDir = normalize(UnityWorldSpaceLightDir(v.vertex));                //计算世界空间中的视角的方向                o.worldViewDir = normalize(UnityWorldSpaceViewDir(v.vertex));                   //计算世界空间中的法线的方向                o.worldNormal = normalize(mul(_World2Object,v.normal));                           return o;}

片断入口函数

fixed4 frag (v2f i) : SV_Target{                //从顶点传过来的各种方向                float3 worldLightDir = i.worldLightDir;                float3 worldViewDir = i.worldViewDir;                float3 worldNormal = i.worldNormal;                //环境光                float3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;                //纹理采样,获取材质颜色                fixed4 albedo = tex2D(_MainTex, i.uv);                      //获取漫反射系数                   float diff = max(0,dot(worldLightDir,worldNormal));                //半漫反射系数                diff = diff * 0.5 + 0.5;                //漫反射颜色计算                float diffcolor = _LightColor0.rgb * diff * albedo.rgb;                //半角向量                float3 halfdir = normalize( worldLightDir + worldViewDir);                 //高光系数                  float spec = pow(max(0,dot( halfdir,worldNormal)),_Gloss);                //高光颜色                float3 speccolor = _LightColor0.rgb * _Specular.rgb * spec;                //最终颜色                float4 color = float4((diffcolor + speccolor + ambient) * _Color,1.0);                  //输出                        return color;            } ENDCG                                                                      //结束标记,表明从这里结束CG程序         } FallBack "Diffuse"                                                              //FallBack "name"   回滚到指定shader                                                                                         //FallBack Off     没有回滚 }
原创粉丝点击