ShaderLab - 第一天 - Shader基础知识

来源:互联网 发布:网络传输协议有哪些 编辑:程序博客网 时间:2024/05/08 21:14

本文为ShaderLab系列学习文章,文中内容为Unity5.X游戏开发技术详解和典型案例,希望对正在学习或者想要学习ShaderLab的人有所帮助,如文章有任何错误还请读者帮忙指正,谢谢!


第一天:ShaderLab基础

1.Shader

什么是Shader:Shader是一个着色器程序的跟命令,每一个着色器程序都必须定义唯一一个Shader,其中定义了材质如何使用这个着色器渲染对象。Shader命令语法如下。

Shader "ShaderName"{        [Properties]        SubShader{......}        [Fallback]}

1:Shader为关键字,定义这是一个Shader着色器,ShaderName为自己定义的Shader的名称,Properties为材质的属性列表,后面紧跟随着SubShader列表,最后面可以添加Fallback代码块。

2:着色器拥有一个Properties的列表。任何定义在着色器程序中的属性都会显示在属性查看器中,典型的有颜色、纹理或者任何被着色器所使用的数据。

3:着色器程序中包含至少一个子着色器,即SubShader,当加载一个着色器程序时,unity将遍历这个列表,获取第一个能够被用户机器支持的子着色器,如果没有一个着色器被支持,unity将尝试降级着色器,即Fallback操作。


2:着色器的三种形态

1:固定管线着色器

固定管线着色器是在老一代GPU能力有限是,对着色器的约束性比较高的一种形态。为了市场占有率,新一代的显卡仍然对齐有所选择的支持,但是未来将逐渐淘汰。

示例:

Shader "Custom/BaseForm1"{Properties{//定义的属性快_Color ("MainColor", Color) = (1,1,1,0.5) //定义主颜色数值_SpecColor("Sec Color", Color) = (1,1,1,1)//定义高光颜色数值_Emission("Emission Color", Color) = (0,0,0,0)//定义自发光颜色数值_Shininess("Shininess", Range(0.01, 1)) = 0.7//定义高光系数数值_MainTex("Base (RGB)", 2D) = "White" {}//定义纹理数值}SubShader{Pass{Material{//材质块Diffuse[_Color]//漫反射Ambient[_Color]//环境光Shininess[_Shininess]//高光系数Specular[_SpecColor]//高光Emission[_Emission]//自发光}Lighting On//开启光照SeparateSpecular On//允许高光使用不同于主颜色的颜色SetTexture[_MainTex]{//处理纹理块constantColor[_Color]//定义颜色值Combine texture * primary DOUBLE, texture * constant//计算最终颜色}}}}

从以上代码我们可以看出一些关于Shader代码的格式,因为我们主要不是用这个所以这里不多介绍,有兴趣的可以自己查看一些资料学习。


2:顶点片元着色器

顶点片元着色器为可编程着色器,相对于固定管线着色器可以给开发人员更大的发挥空间,但是缺点为不能直接和光照交互。着色器程序用CG或HLSL语言编写,嵌入在着色器的渲染通道块中。Cg程序代码片段被编写在CGPROGRAM和ENDCG之间。

顶点着色器中顶点数据必须以一个结构体的形式提交给Cg/HLSL顶点程序,几个常用的顶点结构体在"UnityCG.cginc"文件中,大多数情况下使用它们就足够了,当然也可以自己定义结构体。


下面以一个水的波纹效果制作来加深对顶点片元着色器的理解。

Shader "Custom/MyWater" {//定义了一个着色器,名称为MyWaterProperties {//属性列表,用来指定这段代码将有哪些输入_MainTex ("Base (RGB)", 2D) = "white" {}//定义一个2D纹理属性,默认白色_Aim1("Aim1",Vector) = ( 3, 0, 3, -2.5) //波源位置_Aim2("Aim2",Vector) = ( 5, 0, -5, 2.0)      _Aim3("Aim3",Vector) = (-3, 0, -3, 1.0)      _Aim4("Aim4",Vector) = (-5, 0, 5,  0.5)_High("High",Float) = 1}SubShader {//子着色器Pass{//通道CGPROGRAM//开始标记#pragma vertex verf//定义顶点着色器#pragma fragment frag//定义片元着色器#include "UnityCG.cginc"//引用Unity自带的函数库sampler2D _MainTex;//2D纹理属性float4 _Aim1;float4 _Aim2;float4 _Aim3;float4 _Aim4;float4 _MainTex_ST;float _High;struct v2f {//定义一个结构体float4 pos:POSITION;//声明顶点位置float2 uv:TEXCOORD0;//声明纹理};v2f verf(appdata_base v)//顶点着色器{v2f o;//声明一个结构体对象//计算当前顶点与_Aim1、_Aim2、_Aim3、_Aim4的距离float dis1 = distance(v.vertex.xyz,_Aim1.xyz);float dis2 = distance(v.vertex.xyz,_Aim2.xyz);float dis3 = distance(v.vertex.xyz,_Aim3.xyz);float dis4 = distance(v.vertex.xyz,_Aim4.xyz);//计算当前顶点的高度float H = sin(dis1*_Aim1.w+_Time.z *_High)/5;//计算正弦波的高度H += sin(dis2*_Aim2.w + _Time.z*_High)/10;//叠加正弦波的高度H += sin(dis3*_Aim3.w + _Time.z*_High)/15;//叠加正弦波的高度H += sin(dis4*_Aim4.w + _Time.z*_High)/10;//叠加正弦波的高度o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);o.pos = mul(_Object2World,v.vertex);//将顶点转换到世界坐标的矩阵o.pos.y = H;//顶点的Y值赋为Ho.pos = mul(_World2Object,o.pos);//将顶点转换到自身坐标的矩阵o.pos = mul(UNITY_MATRIX_MVP,o.pos);//计算顶点位置return o;//返回顶点着色器对象}fixed4 frag(v2f i):COLOR{float4 texCol = tex2D(_MainTex,i.uv);//获取顶点对应UV的染色return texCol;//返回顶点染色}ENDCG//着色器结束标志} } FallBack "Diffuse"//降级着色器(备用的着色器)}


3:表面着色器

因为顶点片元着色器缺点是不能直接和光照交互,为了能让开发人员方便的处理光照,unity提供了表面着色器,表面着色器代码也是使用CG或者HLSL语言编写的。下面将通过在Unity中之间新建的着色器来看一下表面着色器的结构。


Shader "Custom/BaseForm2" {  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//定义金属材质系数数值  }  SubShader {    Tags { "RenderType"="Opaque" }//标签    LOD 200//LOD数值    CGPROGRAM    #pragma surface surf Standard fullforwardshadows//表面着色器编译指令    #pragma target 3.0//着色器编译目标    sampler2D _MainTex;//2D纹理属性    struct Input {//定义输入参数结构体      float2 uv_MainTex;//纹理UV坐标    };    half _Glossiness;//定义高光系数属性    half _Metallic;//定义金属材质系数属性    fixed4 _Color;//定义主颜色属性    void surf (Input IN, inout SurfaceOutputStandard o) {//表面着色器函数      fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;//根据UV坐标从纹理提取颜色      o.Albedo = c.rgb;//设置颜色      o.Metallic = _Metallic;//设置金属材质系数      o.Smoothness = _Glossiness;//设置高光系数      o.Alpha = c.a;//设置透明度    }    ENDCG  }   FallBack "Diffuse"//降级着色器}

今天先学到这里了,明天继续吧~

0 0
原创粉丝点击