【《Unity Shader入门精要》 提炼总结】(五)第五章·学习ShaderLab的数学基础&顶点/片元着色器的书写

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/iceSony/article/details/84309224

 

 

 

本文由@唐三十胖子出品,转载请注明出处。  
文章链接:https://blog.csdn.net/iceSony/article/details/84309224

 

 

 

这篇文章将总结和提炼《Unity Shader入门精要》的第五章“Unity Shader学习之旅”的内容。

通过这篇文章,你可以知道

1)Shader开发所需的数学基础

2)顶点/片元着色器的书写&语法介绍

一.学习ShaderLab的数学基础

矢量/标量:矢量是状态量,有方向大小;标量只有大小

小明向东10km/h开车

这里的向东10km/h就是矢量,10km/h就是标量

 

向量又称作矢量,一个三维向量(1,1,1)代表从原点到点(1,1,1)的射线

除了简单的加减,向量与标量的乘除

我们还要知道大学数学讲到的向量的内积与外积

向量内积:A·B (x1,y1)·(x2,y2)= x1x2+y1y2

实际意义:大于0 两者夹角<90 等于0 两者垂直 小于0 两者夹角>90

向量外积:AxB (x1,y1,z1)·(x2,y2,z2)= (y1z2-z1y2,z1x2-x1z2,x1y2-x2y1)

实际意义:AxB代表垂直于AB构成平面的法向量

 

最后还涉及了矩阵的乘法

你要知道的是为了区分点和向量在世界坐标中的区别,我们需要将xyz的坐标加上多一栏

(x,y,z,0/1) 0代表是向量 1代表点

比如一个矩阵乘法代表移动操作

其次在U3D中分为左右手坐标系

书中提到摄像头是右手坐标系,事实上windows下和mac是不同的

Mac下z越小离摄像头越远,而Mac下是z越大越远。这里特别说明这是由于OPENGL与DirectX的不同导致的。Windows下统一为左手坐标系。

(不清楚的可以看书,注意书中都是矩阵右乘,也就是从倒数第二个乘以倒数第一个开始)

二.接下来编写顶点/片元着色器

Shader "sony/Shader122"
{
    SubShader
    {
	Pass
        {
	    CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            struct a2v 
            {
		float4 position:POSITION;
		float3 normal:NORMAL;
		float4 texcoord:TEXCOORD0;
            };
	    struct v2f 
            {
		float4 pos : SV_POSITION;
		fixed3 color : COLOR0;
	    };
	    v2f vert(a2v v) 
            {
		v2f o;
		o.pos = UnityObjectToClipPos(v.position);
		o.color = v.normal*0.5 + fixed3(0.5,0.5,0.5);
		return o;
	    }
	    fixed4 frag(v2f o):SV_TARGET 
            {
		return fixed4(o.color,1.0);
	    }
            ENDCG
        }
    }
}

实现效果

介绍一下基本的语法

这就是第一个着色器,上一章说过顶点/片元着色器写在Pass中的CGPROGRAM-ENDCG中

这里不难看出两个申明

#pragma vertex vert

#pragma fragment frag

这里的vertex与fragment代表vert与frag函数分别作用在顶点、片元上

 

之后的函数编写和常见的c语法类似

但是有个符号      :

注意这里的     :  不是c++中的继承

这是告诉函数的最后的修改对象

比如float4 vert(float4 v : POSITION) :SV_POSITION

这里的v其实就是float4v = POSITION

SV_POSITION代表:最后return数据会作用在SV_POSITION裁剪坐标中(摄像机外不需要进行修改)

 

UnityObjectToClipPos:从世界坐标到裁剪坐标

 

结构体:用于顶点——>片元函数数据传递,如下在顶点函数中处理顶点颜色,传递给片元函数插值产生五彩的球体


Shader "sony/Shader122"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            struct a2v 
            {
                float4 position:POSITION;
                float3 normal:NORMAL;
                float4 texcoord:TEXCOORD0;
            };
            struct v2f 
            {
                float4 pos : SV_POSITION;
                fixed3 color : COLOR0;
            };
            v2f vert(a2v v) 
            {    
                v2f o;
                o.pos = UnityObjectToClipPos(v.position);
                o.color = v.normal + fixed3(0.5, 0.5, 0.5);
                return o;
            }
            fixed4 frag(v2f o):SV_TARGET 
            {
                return fixed4(o.color,1.0);
            }
            ENDCG
        }
    }
}

当我们需要参数的时候直接通过定义的结构体来获取就可以:)

和普通的定义不同的是我们修改结构体的内容不需要写输出内容,因为需要修改的内容写在开头了

比如:v2f vert(a2v v)

 

下一篇我们将介绍CG语法&变量与常见函数的使用

猜你喜欢

转载自blog.csdn.net/iceSony/article/details/84309224
今日推荐