Unity shader学习笔记(二)—— 着色器

概述

在学习笔记(一)中,说明了GPU渲染流水线中有三个可编程的部分,亦即四个着色器。分别是顶点着色器曲面细分着色器几何着色器片元着色器。但是在Unity shader的教程中,我只看到了关于顶点着色器和片元着色器的编程,所以本文只记录关于顶点着色器和片元着色器的学习笔记。另外还有一个着色器需要提及,就是表面着色器(Surface Shader)。这是Unity自己创造的一种着色器类型,但实际上底层实现仍然是使用顶点/片元着色器。

Unity的着色器类型

在Project视图中创建一个Shader,会出现几种可选的类型:
Alt

  • Standard Surface Shader:标准的表面着色器模板,包含一个标准光照模型
  • Unlit Shader:不包含光照(但包含雾效)的基本的顶点/片元着色器
  • Image Effect Shader:各种屏幕后处理模板
  • Compute Shader:会产生一种特殊的Shader文件,这类Shader文件旨在利用GPU的并行性来进行一些与常规渲染流水线无关的计算

顶点着色器

在Unity Shader中,指定渲染流水中使用的顶点着色器代码如下:

Shader "Assets/Shaders/SimpleColorShader" {
	SubShader{
		Pass{
			CGPROGRAM
			#pragma vertex vert

			float4 vert(float4 v : POSITION) : SV_POSITION {
				return UnityObjectToClipPos(v);
			}
			ENDCG
		}
		
	}
}

其中,#pragma vertex表示指定一个顶点着色器,而vert就是实现的顶点着色器名称,亦即一个函数。函数的具体含义以后再做学习笔记。
一个顶点着色器接收一组模型顶点坐标输入,同时必须输出齐次裁剪空间的有颜色的顶点。从模型顶点坐标到齐次裁剪空间坐标的变换总共经历三个子变换,分别是世界变换(World Transformation),视图变换(View Transformation)和投影变换(Projection Transformation),每个变换都由一个矩阵完成,这三个矩阵统称:MVP变换矩阵。
注意上述代码中,有这么一行return UnityOjectToClipPos(v);。从函数的名称上看,意思是将Unity游戏物体(Object)变换到裁剪(Clip)坐标。实际上,这段代码原本是return mul(UNITY_MATRIX_MVP, v);。即将原输入顶点v乘以MVP矩阵,变换到齐次裁剪空间坐标。Unity自动将这行代码替换成了UnityOjectToClipPos(v);。可见,这两个代码实际上等效的,就是一个坐标变换。

片元着色器

这里的片元可以理解为像素,但并不是一个真正的像素,它包含了比像素更多的信息。关于片元着色器(Fragment Shader)在维基百科上有这么一段话:

Pixel shaders, also known as fragment shaders, compute color and other attributes of each "fragment" - a unit of rendering work affecting at most a single output pixel. 

它表示,一个片元着色器计算每个片元的颜色和其他属性。一个片元着色器一次只处理一个片元,一次只输出一个片元的颜色值(affecting at most a single output pixel)。
一个完整的Unity Shader还需要包含片元着色器的代码,我们将片元着色器的代码加到上面Unity Shader代码中,变成:

Shader "Assets/Shaders/SimpleColorShader" {
	SubShader{
		Pass{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			float4 vert(float4 v : POSITION) : SV_POSITION {
				return UnityObjectToClipPos(v);
			}
			float4 frag() : SV_Target {
				return fixed4(1.0, 1.0, 1.0, 1.0);
			}

			ENDCG
		}
		
	}
}

第二个#pragma指定片元着色器为frag()函数。顶点着色器将坐标变换到齐次裁剪空间坐标系上,使得模型能够显示在屏幕上,然后片元着色器为模型显示在屏幕上的每个像素指定了一个颜色(1.0,1.0,1.0,1.0)。这很明显是一个RGBA值,全是 1 ,代表白色。
新建一个物体,新建一个材质,然后指定将这个Shader脚本拖到该材质下,最后将该材质赋予新建的物体。
我们会看到场景的物体就是纯白色。
在这里插入图片描述
注意,左边的球采用的是上述的shader,右边的球是使用默认的材质,默认的shader。为了放大区别,环境光强度我调高到了10,颜色调成了暗红色。显然,左边的球并不受环境光的影响,因为Shader代码中,压根儿没有对环境光因素做处理,仅仅就是输出了一个固定的颜色。
我们把片元着色器的返回的颜色值改成(0,0,1.0,1.0)。会发现球的颜色变了。
在这里插入图片描述

总结

在Unity Shader中编写顶点着色器和片元着色器的代码被包含在#CGPROGRAM中,它指明下述代码实际上就是CG(C for graphics)的语法。但是CG的特性又不是全部都能在Unity中使用。不过仍然建议优先熟悉CG,这样编写Unity shader不至于一头雾水。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值