Shader之小白入门学习五

Shader之小白入门学习五

前言

上一篇学习了Properties,主要是为了在材质面板中去暴露一些参数给用户来调节。但是目前为止,虽然学会了暴露参数,但是调节起来还是没有任何效果,在这篇呢,就来学习一下如何让我们的参数来反馈表现,对于初学者来说,这篇内容至关重要,能否准确地理解直接影响是否能够买入Shader的大门。

先实现个小目标

先实现一个只有颜色属性可调节的简单材质效果,如下图所示:
在这里插入图片描述
模型可随便找一个,默认的几何体也可以,在材质面板中只有一个颜色属性,当我们点开拾色器时,对应的模型也会自动发生变化。我们就用之前的MyFirstShader来完善。

Pass

在一个Shader中,可以有多个SubShader以及一个SubShader中也可以有多个Pass。但是一个Shader中必须要至少有一个SubShader,并且这个SubShader中也必须至少有一个Pass。SubShader我们已经知道是什么了,接下来就来介绍一下Pass。
**Pass的意思就是渲染一次模型!**而具体要怎么渲染就需要我们在Pass中添加Cg/HLSL代码片段来实现了,这段代码片段是由CGPROGRAM开始,由ENDCG结束。u而就是说我们必须要添加CGPROGRAM和ENDCG,然后在他们中间去写实现效果的代码。好!那我们就按Unity规定的要求摆好姿势!

Shader "TA/MyFirstShader"
{
	Properties
	{
		_Color("Color",Color)=(1,1,1,1)
	}
	SubShader
	{
		Pass
		{
		CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

		ENDCG
		}
		
	}
	//FallBack "Diffuse"
	//CustomEditor "EditorName"
}

既然是经典片段着色器,那么就要先定义好顶点着色器与片段着色器,告诉Unity分别在哪里去执行他们。
:#pragma是Unity内置的编译指令用的命令,在Pas中我们就利用此命令来声明所需要的顶点着色器与片段着色器。
#pragma vertex name
定义顶点着色器为name,通常情况下会起名为vert。
#pragma fragment name
定义片断着色器为name,通常情况下会起名为frag。

顶点着色器

声明完后,就开始实现具体的内容吧
顾名思义,顶点着色器就是处理顶点的着色器,每个顶点都会执行一次顶点着色器。

在这里插入图片描述
解释一下顶点这个函数的结构。

  1. 顶点着色器函数的名称,在上面我们已经指定了顶点着色器的名称就是vert,所以这里我们必须要用vert作为名称。
  2. 其中float4 vertex是我们自己定义的一个四维向量,名字叫vertex(名字我们可以随便起),仅仅定义一个四维向量并不能使它拥有我们模型的顶点信息,所以这俩我们需要为它指定一个语义–POSITION,POSITION就是代表着模型的顶点位置信息。此时变量vertex就表示着我们模型的顶点位置。
  3. 在顶点着色器中最重要的事情就是将顶点从模型坐标转换到裁剪坐标(说白了就是将模型显示在二位显示器上时需要做的一些矩阵变换)。不会矩阵变换怎么办,没关系,Unity已经帮我们准备好现成的命令了,只需要调用UnityObjectToClipPos即可,后面括号中加上我们的顶点位置变量就可以了
  4. 然后呢,在后面的片段着色器中我们需要顶点着色器中的输出结果,所以3中需要加上return来转换后的顶点返回,float4就是用来定义我们返回的是四维向量。
  5. 经过变换后返回的顶点位置,我们也需要利用语义来标记一下,以便片段着色器可以知道哪个是从顶点着色器输出过来的顶点位置信息。所以我们在函数的后面加上:SV_POSITION。

:简单地说POSITION语义是用于顶点着色器,用来指定模型的顶点位置,是在变换前的顶点的本地空间坐标。SV_POSITION语义则用于像素着色器,用于标识经过顶点着色器变换之后的顶点坐标。在顶点着色器中处理顶点时,我们首先需要获取到模型的顶点数据(比如顶点位置,法线信息,顶点颜色等等),那么这些数据都是直接存储在模型中的,我们在Shader只需要通过标识语义就可以自动获得。
此时的Shader还无法正常编译,因为除了顶点着色器外,我们还需要一个片段着色器。

片段着色器

片段着色器也被称为像素着色器,主要是处理最终显示在屏幕上的像素结果。
经过顶点着色器的处理,我们已经得到了最终显示在屏幕上的定点矩阵,内部会自动进行插值计算,以获得当前模型的所有片段像素,然后每个像素都会执行一次片段着色器,得到每个像素的颜色值。
在这里插入图片描述

  1. 片段着色器的函数名,一种()是空的,因为在这个简单的示例中我们不需要额外的数据传过来,所以暂时为空。
  2. 在CG/HLSL中使用Properties中的变量前还需要在CG/HLSL中再重新声明一次。名称要求一致,这是死规则,我们只能按照要求来执行。float,half,fixed,这三个都是浮点数的表时,只是分别对应的精度不一样,主要用此可以进行更进一步的优化。
  3. 直接返回_Color,也就是直接返回我们在材质面板中定义的颜色,这也是我们这个小例子想要的效果。
  4. 同样,返回值是个四维向量,我们用float4来表示,如果想优化的话就用fixed4来表示,关于精度问题我们后面会说。
  5. SV_TARGET是系统值,表示该函数返回的适用于下一个阶段输出的颜色值,也就是我们最终输出到显示器的值。
    最终代码如下:
Shader "TA/MyFirstShader"
{
	Properties
	{
		_Color("Color",Color) = (1,1,1,1)
	}
		SubShader
	{
		Pass
		{
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag

		fixed4 _Color
		float4 vert(float vertex : POSITION) :sv_POSITION
	    {	
		    return UnityObjectToClipPos(vertex);
        }

		fixed4 frag() : SV_Target
		{
			return _Color
         }

		ENDCG
		}
		
	}
	//FallBack "Diffuse"
	//CustomEditor "EditorName"
}

此时我们已经可以正常编译并实时更换颜色得到反馈了。

总结

顶点着色器与片段着色器的执行并不是1:1的,举个例子,一个三角面片,只有三个顶点。顶点着色器只需执行3次,而片段着色器由最终的像素数来决定,执行几百上千都是很正常的,所以从性能的角度来考虑,我们要尽量把计算放在顶点着色器中去执行。其次在片段着色器中也要尽量的简化算法,节省开支。
原文链接: https://mp.weixin.qq.com/s/cWr148ZBZ2_IuWooakLJ6w.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值