从头开始学shader(二) SimpleShader2

在上一个Shader中我们只使用了最基本的参数,这次我们将从系统中获取更多的参数来进行说明.

Shader "Unlit/SimpleShader2"
{
	SubShader
	{
		Pass
		{
		CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			struct a2v{
				float4 vertexs : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
			};

			struct v2f{
				float4 pos : SV_POSITION;
				fixed3 color : COLOR0;
			};

			v2f vert (a2v i)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(i.vertexs);
				o.color = i.normal;
				return o;
			}

			fixed4 frag (v2f i) : SV_Target
			{
				return fixed4(i.color, 1.0);
			}
			ENDCG
		}
	}
}

这个shader与上次不同的是定义了两个结构.

struct a2v{
	float4 vertexs : POSITION;
	float3 normal : NORMAL;
	float4 texcoord : TEXCOORD0;
};

a2v的结构定义了哪些数据会传递给顶点着色器.这个结构必须定义好语义,Unity才会知道需要把哪些数据传递给顶点着色器.这个阶段的语义有

POSITION   模型空间中的顶点位置, float4

NORMAL     顶点法线,float3 

TANGENT   顶点切线,float4

TEXCOORDn(TEXCOORD0, TEXCOORD1)    顶点坐标纹理,如uv1,uv2等.通常是float2或float4

COLOR       顶点颜色,通常是fixed4或float4

所以我们在例子中传入了顶点的位置POSITION,顶点的法线NORMAL和一套模型的uv.

struct v2f{
	float4 pos : SV_POSITION;
	fixed3 color : COLOR0;
};

v2f结构则定义了从顶点着色器传递到片元着色器的数据.在传递到片元着色器的数据中,SV_POSITION参数是必须的,否则渲染器将无法得到裁剪空间中的顶点坐标,也就无法把顶点渲染到屏幕上.

这个阶段的语义通常有:

SV_POSITION   裁剪空间中的顶点坐标,必须包含的语义

COLOR0           通常用于第一组颜色输出

COLOR1           通常用于第二组颜色输出

TEXCOORD0~TEXCOORD7   通常用于输出纹理坐标uv

所以本例中我们从顶点着色器传递到片元着色器的参数有裁剪空间下的顶点坐标和一组color数据.

需要注意的是顶点着色器是逐顶点调用的,而片元着色器是逐片元调用的.片元着色器的输入是顶点着色器的输出经过插值的结果.

v2f vert (a2v i) 
{
	v2f o;
	o.pos = UnityObjectToClipPos(i.vertexs);
	o.color = i.normal;
	return o;
}

在这个例子中,顶点着色器的输出是我们自定义的结构数据v2f,输入是我们定义的结构数据a2v.

在函数中我们首先定义了需要输出的结构v2f o.接着我们给o.pos赋值,把模型空间中的坐标转换到裁剪空间中.然后我们把顶点的法线传给了o.color.然后把填充了数据的v2f传递给片元着色器.

fixed4 frag (v2f i) : SV_Target
{
	return fixed4(i.color, 1.0);
}

在片元着色器中,我们直接把传来的经过插值的color直接输出,即直接把顶点的法线数据作为颜色进行输出.

下面是在unity中的效果:

在cube中,在同一个面上的顶点法线都是同一个方向,所以cube的每一个面都是一个颜色.模型的forward的法线是(0,0,1),所以他的前面输出了蓝色,对应的右面(1,0,0)红色,上面(0,1,0)绿色.

而sphere中,每个面的法线都朝着不同的方向,而顶点着色器的输出经过插值传递给片元着色器,所以球体的颜色被均匀的插值输出,出现了连续的颜色效果.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值