• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

游戏开发

常州游戏开发-Unity Shaders — 访问顶点颜色

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/youxikaifa/2019/0320/417.html

常州游戏开发-Unity Shaders — 访问顶点颜色


Vertex Magic。望文生义,就是学习极点相关的内容。自从看了下面Unity Gems里面的一张图,我对整个Surface Shader的工作流程有了更好的理解,在此再重温一下。
 
 
 
 
 
 
 
能够看出来共有四个阶段咱们能够参与。咱们之前学习的大多是在上图的第二和第三个阶段,也就是编写surf和LightingXXX函数来影响外表上色和光照函数的。在卡通风格的Shader中,咱们也对最终一个更改像素色彩的机
会——finalcolor命令有了一个初步的尝试。而现在,咱们将用一章的时刻来学习怎么利用第一个阶段——极点函数来影响像素色彩。
 
 
 
极点函数是在每个极点被传送到GPU之前被调用一次。它的作用是从模型坐标系中得到三维坐标,然后再转换到其渲染到屏幕时在屏幕坐标系中的二维方位。因此,经过极点函数,咱们能够修改极点的方位、色彩和UV坐
标。一旦咱们完成了对极点的修改后,就会进入到surf函数的执行。与极点函数是逐极点执行的方式不同,surf函数则是逐像素执行的。
 
 
 
经过极点函数,咱们能够创造像海上的波浪、旗号飘动的动态效果,或许运用Shader来给极点上色。这一篇,咱们来学习怎么在一个Surface Shader中创立一个最简略的极点函数!
 
 
 
预备工作
 
 
 
在深入学习极点函数之前,咱们得首要了解怎么经过极点函数得到和存储极点相关信息。
 
 
 
首要,咱们要预备一个现已给极点上色过的模型,以便咱们能够在极点函数中检查极点色彩。为了便利,咱们运用本书自带资源(见文章开头)中第七章的模型资源——VertexColorObject.fbx。咱们把
VertexColorObject.fbx导入Unity,并拖入到一个新的场景中。最终增加一个平行光。
新建一个Shader和Material,能够别离命名为SimpleVertexColor,并将Shader赋给Material,再将Material赋给模型。
 
 
你的场景应该看起来是这样的:
 
 
 
 
 
实现
 
 
 
下面,咱们开端编写Shader。
 
 
 
在Properties块中增加新的Properties:
[plain] view plaincopyprint?
Properties   
{  
    _MainTint("Global Color Tint", Color) = (1,1,1,1)  
}  
Properties 
{
_MainTint("Global Color Tint", Color) = (1,1,1,1)
}
接下来,通知Unity咱们将运用自己的极点函数:
[plain] view plaincopyprint?
CGPROGRAM  
#pragma surface surf Lambert vertex:vert  
CGPROGRAM
#pragma surface surf Lambert vertex:vert
为Properties中新增加的特点增加对应的引证:
[plain] view plaincopyprint?
float4 _MainTint;  
float4 _MainTint;
下面是很重要的Input结构。咱们增加了一个新的变量vertColor以便surf函数能够拜访vert函数中传递的数据:
[plain] view plaincopyprint?
struct Input   
{  
    float2 uv_MainTex;  
    float4 vertColor;  
};  
struct Input 
{
float2 uv_MainTex;
float4 vertColor;
};
下面是一个十分简略的vert函数。咱们拜访模型的极点色彩,再存储到Input结构体中:
[plain] view plaincopyprint?
void vert(inout appdata_full v, out Input o)  
{  
    o.vertColor = v.color;  
}  
void vert(inout appdata_full v, out Input o)
{
o.vertColor = v.color;
}
最终,咱们运用从Input中得到的数据填充SurfaceOutput结构体的Albedo参数:
[plain] view plaincopyprint?
void surf (Input IN, inout SurfaceOutput o)   
{  
    o.Albedo = IN.vertColor.rgb * _MainTint.rgb;  
}  
void surf (Input IN, inout SurfaceOutput o) 
{
o.Albedo = IN.vertColor.rgb * _MainTint.rgb;
}
完好代码如下:
 
[plain] view plaincopyprint?
Shader "Custom/SimpleVertexColor" {  
    Properties   
    {  
        _MainTint("Global Color Tint", Color) = (1,1,1,1)  
    }  
      
    SubShader   
    {  
        Tags { "RenderType"="Opaque" }  
        LOD 200  
          
        CGPROGRAM  
        #pragma surface surf Lambert vertex:vert  
  
        float4 _MainTint;  
  
        struct Input   
        {  
            float2 uv_MainTex;  
            float4 vertColor;  
        };  
          
        void vert(inout appdata_full v, out Input o)  
        {  
            o.vertColor = v.color;  
        }  
  
        void surf (Input IN, inout SurfaceOutput o)   
        {  
            o.Albedo = IN.vertColor.rgb * _MainTint.rgb;  
        }  
        ENDCG  
    }   
    FallBack "Diffuse"  
}  
Shader "Custom/SimpleVertexColor" {
Properties 
{
_MainTint("Global Color Tint", Color) = (1,1,1,1)
}
 
SubShader 
{
Tags { "RenderType"="Opaque" }
LOD 200
 
CGPROGRAM
#pragma surface surf Lambert vertex:vert
 
float4 _MainTint;
 
struct Input 
{
float2 uv_MainTex;
float4 vertColor;
};
 
void vert(inout appdata_full v, out Input o)
{
o.vertColor = v.color;
}
 
void surf (Input IN, inout SurfaceOutput o) 
{
o.Albedo = IN.vertColor.rgb * _MainTint.rgb;
}
ENDCG
FallBack "Diffuse"
}
效果如下:
 
解说
 
 
经过极点函数,咱们能够修改极点的方位、色彩、UV坐标等值。在本节中咱们运用了一个从Maya导入的已给极点上色的模型,但咱们能够发现,在运用默许材质的情况下这些色彩在Unity中是不显示的。咱们需求编写
Shader,提取这些色彩再在模型上显示出来。
 
咱们首要经过在#pragma声明中增加vertex:vert句子。这实际上通知Unity,嘿,不要用你自己内置的极点函数拜访模型极点信息啦,去我写的Shader里找一个名叫vert的家伙,用它去处理信息!如果Unity没有找到,它就
会报一个编译错误。
 
vert函数里,除了咱们了解的Input结构体,还有一个很特别的参数——appdata_full 。这个参数也是Unity内置的一个变量,它包含了模型极点的一切信息,包括方位、切线、法线、两个纹路坐标和色彩信息。其他的还有
appdata_base和appdata_tan,详细能够看见官网。
 
你还能够发现,vertColor是一个float4类型的变量,这意味着咱们还能够拜访它的通明通道。像下面这样:
[plain] view plaincopyprint?
void surf (Input IN, inout SurfaceOutput o)   
{  
    o.Albedo = IN.vertColor.rgb * _MainTint.rgb;  
    o.Alpha = IN.vertColor.a;  
}  
 

上篇:上一篇:常州手游设计-U3D模糊效果
下篇:下一篇:常州手游开发-u3d溶解shader