Shader2.0的顶点着色器和片段着色器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shader2.0的顶点着色器和片段着色器相关的知识,希望对你有一定的参考价值。

参考技术A 一·、顶点着色器

v2f vert(appdata v) //顶点着色器

               

                    v2f o;

                     o.vertex = UnityObjectToClipPos(v.vertex);

                    o.uv = v.uv;

                    return o;

               

o.vertex = UnityObjectToClipPos(v.vertex); // 一次MVP的过程

将3d坐标转化为2D坐标

MVP:M将本地坐标转化到世界坐标系下

V:将世界坐标转换到本地坐标

P:矩阵 透视矩阵和正交矩阵

二、片段着色器

fixed4 frag(v2f i) : SV_Target

               

                    fixed4 col = tex2D(_MainTex, i.uv);

                    return col;



片段着色器v2f就是顶点着色器计算出来的结果

tex2D就是 从_MainTex里面 用i.uv坐标 去一个像素 R G B A 正好对应Fixed4 用12位表示

所有的GPU里面只有浮点数

Float 占四个字节 占32位          次世代游戏的话 用Float更精细

Half 也是浮点数 两个字节 16位

Fixed 浮点数 1.5个字节   12位    如果对颜色的精准度没有太多要求 Fixed就足够了

Fixed4表示一个四维的 Fixed3表示一个三维的  即精确度跟上一个数值就表示几维

三、小知识

1.通过shader来完成矩阵的旋转,是因为其是在GUP里直接转的,省略了CPU-GPU这个过程 ,而矩阵的旋转 也是通过对顶点利用矩阵变换公式          的计算 

2.利用脚本修改shader里的公共成员:GetComponent<Renderer>().material.SetFloat(“参数名”)

3.图片的轮播(图片中的Warp Mode要为repate) 其实就是在片段着色器中利用法线 也可以用这个效果实现简单的流水线

                    fixed2 tmpUV = i.uv;

                   tmpUV.y += _Time.y;

                    fixed4 col = tex2D(_MainTex, tmpUV);

Unity中Shader的三种基本类型

一、固定功能着色器(Fixed Function Shader)

固定功能着色器为固定功能渲染管线的具体表现。功能较简单兼容比较老的机器

二、表面着色器

存在于Unity3D中由U3D发扬光大的一门技术。Untiy3D为我们把Shader的复杂性包装起来,降低shader的书写门槛,创建了表面着色器

三、顶点着色器和片段着色器

GPU上含有两个组件:可编程顶点处理器和可编程片段处理器,顶点和片段处理器被分离成可编程单元,可编程顶点处理器是一个硬件单元,可以运行顶点程序,而可编程片段处理器则是一个可以运行片段程序的单元。顶点着色器:顶点着色程序从GPU前端(寄存器)中提取图元信息(顶点位置、法向量、纹理坐标),并完成顶点坐标空间变换、法向量空间转换、光照计算等操作,最后将计算数据传送到指定寄存器中。片段着色器片段程序从上述寄存器中获取需要的数据:纹理坐标与光照信息等,并根据这些信息以及从应用程序传递的纹理信息进行每个片段的颜色计算(纹理查询),最后将处理后的数据传送光栅操作模块。

三种着色器的共同点:

都必须从唯一一个根Shader开始
Prooerties参数部分,作用以及语法完全相同。
具体功能都在SubShader里。
都可以打标签
都可以Fallback
都可以处理基本的功能,例如光照漫反射以及镜面反射。但如uv计算效果等高级功能,固定功能着色器无法完成。
三种着色器的不同点
表面着色器没有通道pass{},加了会报错,该着色器已经把具体内容打包在光照模型中了。
固定渲染管线每句代码之后都没有“;”
核心结构不同:

 

固定渲染管线的核心是:

Material{}以及SetTexture[_MainTex]{}

顶点与片段着色器的核心是:

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
ENDCG

表面着色器的核心是:

1.表面着色器使用Unity3D自带光照模型Lambert,也不做顶点处理,只需要一个表面处理函数surf即可。
CGPROGRAM
#Pragma surface surf Lambert
ENDCF
2.这套表示使用的是自己写的光照模型lsyLightModel,并且使用了顶点处理函数vert
CGPROGRAM
#pragma surface surf lsyLightModel vertex:vert
ENDCG

二、shader整体框架

 

 

1、从这幅图可以看到,Unity中的shader可以分为以下三个模块:
Properties一般定义中着色器的起始部分。属性模块可以定义一些属性,用来指定那个这段代码有哪些输入。在使用shader 的时候可以直接中材质面板里编辑这些属性。Properties块内的语法都是单行的。属性的定义格式如下所示:

属性可以划分为以下几类:

1)、数字与滑动条
name ("display name", Range (min, max)) = number //滑动条调节
name ("display name", Float) = number//数字调节
name ("display name", Int) = number//数字调节
颜色与向量(注意是四元数)
name ("display name", Color) = (number,number,number,number)
name ("display name", Vector) = (number,number,number,number)
2)、贴图
name ("display name", 2D) = "defaulttexture" {}
name ("display name", Cube) = "defaulttexture" {}//立方体贴图
name ("display name", 3D) = "defaulttexture" {}
3)、细节
Range与float的属性只能是单精度值。
在后面的着色器程序中,属性值通过[name]来访问。而display name将显示在材质检视器中。
可以使用在属性定义加上等号为每个属性提供缺省值。
对于纹理(2D, Rect, Cube) 缺省值既可以是一个空字符串也可以是某个内置的缺省纹理:"white", "black", "gray" or"bump"
使用示例
// properties for a water shader
Properties
{
_WaveScale ("Wave scale", Range (0.02,0.15)) = 0.07 // sliders
_ReflDistort ("Reflection distort", Range (0,1.5)) = 0.5
_RefrDistort ("Refraction distort", Range (0,1.5)) = 0.4
_RefrColor ("Refraction color", Color) = (.34, .85, .92, 1) // color
_ReflectionTex ("Environment Reflection", 2D) = "" {} // textures
_RefractionTex ("Environment Refraction", 2D) = "" {}
_Fresnel ("Fresnel (A) ", 2D) = "" {}
_BumpMap ("Bumpmap (RGB) ", 2D) = "" {}
}

 

2、子着色器SubShader

这个我会在下一篇文章中详细说明

3、回滚FallBack
Shader基本框架的最后是指定一个回滚函数Fallback,用来处理所有的子着色器都不能运行时的情况(当目标设备太老时,所有的设备都有其不支持的特性时使用了Fallback),可以认为是一种defult。

以上是关于Shader2.0的顶点着色器和片段着色器的主要内容,如果未能解决你的问题,请参考以下文章

顶点着色器和片断着色器

在顶点和片段着色器中访问同名统一失败

跨多个着色器的 OpenGL 统一

打开 gl 计算着色器和帧缓冲区

当有多个着色器程序时使用 glClear()

顶点着色器+片段着色器