先来看一段我们项目常见的Shader代码,这个是Vertex&Fragment shader,目前已经不常用了,不过还是适合我们理解一些基础知识和理解一些比较老的shader 代码。下次我们再讲unity主推的surface shader

 Shader "Custom/test"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
} SubShader
{
Pass
{
Tags { "RenderType"="Opaque" } CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex; struct VertexOutput
{
float4 pos:SV_POSITION;
float2 uv_MainTex:TEXCOORD0;
}; VertexOutput vert(appdata_base input)
{
VertexOutput o;
o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
o.uv_MainTex = input.texcoord.xy;
return o;
} float4 frag(VertexOutput i):COLOR
{
float4 col = tex2D(_MainTex,i.uv_MainTex);
return col;
} ENDCG
}
}
FallBack "Diffuse"
}

第1行代码的 Shader "Custom/test" 声明了目录结构,test是这个shader的名字。之后就可以在材质上中找到对应的shader

第3-6行声明了shader的可以调节参数的地方。设置了之后,就可以在Inspector面板中找到对应的变量。具体内容查看这里.

第8行的SubShader比较重要。一个Shader中可以包含任意多个SubShader,但是只有一个SubShader被显卡选中并最终执行。显卡会自动选择一个最适合它自身性能的SubShader去执行。如果我们写的SubShader最后都没有被选中,那么就执行第25行的fallback 指定的shader。

第10行的Pass也很重要,在一个SubShader中我们可以定义多个Pass,而Pass与SubShader不同,你写的每一个Pass都会按照顺序全部执行一遍.我们要在Pass中写具体的着色器代码,还有一点要提一下,在Unity主推的Surface Shader中是不能写Pass的,因为在Unity的光照模型中他会自动定义一些Pass,所以也就不再允许你额外写了。

第12行的 Tags { "RenderType"="Opaque" } 他是一种ShaderLab(UnityShader中除了CG以外的语法),给我们提供好的可配置的一些选项,这些选项你可以每个Pass都写一个,也可以直接写在SubShader下面让所有Pass公共用一个配置。这里面的RenderType = "Opaque"是告诉渲染设备,这个使用这个Shader的材质是一个不透明的物体,对应的还有Transparent透明物体等,这个标签的功能需要跟ztest配合使用。比较重要的还有Queue标签,它会改变物体被渲染的顺序。具体看这里,常用标签的顺序为 Background is 1000, Geometry is 2000, AlphaTest is 2450,Transparent is 3000 and Overlay is 4000.

第14~40行被CGPROGRAM 和 ENDCG包含的部分才是真正的CG代码

第15~16行的两句话是告诉渲染设备顶点着色器(vertex)和片段着色器(fragment)的名字是什么,这是为了让显卡在渲染的时候能够准确找到他们而必须声明的.而我们后面具体些着色器的时候也要用这个名字

第17行#include "UnityCG.cginc"是因为Unity为我们提供大量的可用变量和常量,比如说一些空间变换矩阵,这样子可以提高我们的开发效率,为了使用他们你需要把这句话加上。在Unity4.0之后你可以省略这句话了,他会被默认包含进来,不过为了向下兼容还是建议加上。

第18行的uniform sampler2D _MainTex;我们声明了一个叫_MainTex变量,他的类型是sampler2D(也就是指可采样的2D贴图),前面的uniform意思是说这个变量是由外部赋值进来的,你会发现这里的_MainTex和我们的Properties中的_MainTex名字一致,前面说过了,通过这种方式我们就可以在着色器中使用在Properties中声明的变量了。

第20行~24行是声明一个顶点着色器的输出结构,它同时也是片段着色器的输入结构.每个变量声明最后都跟了一个像:SV_POSITION这样的语法,这在CG中称为语义(semantic),简单的理解就是显卡设定了一些特定的寄存器,用来存放一些指定的特殊变量,在渲染时候如果需要用到的话就直接来取,这样子可能处理起来更快。其中SV_POSITION是专门用来存放模型顶点在投影空间的坐标的。TEXCOORD0可以用来存放任何你想存放的变量,在光栅化的时候这个变量会被插值 。类似于TEXCOORD0还有TEXCOORD1,TEXCOORD2等,具体个数看显卡的性能.我们在这个结构里添加了两个变量一个是顶点投影坐标,这个是必须有的,另外一个是顶点的纹理坐标,用来贴图用的。

第26~32行 是顶点着色器的代码部分,着色器(理解成函数就行了)的返回类型为我们刚才声明的返回结构,着色器名字就用我们在CG代码一开始通过#pragma 关联的名字。

而参数这里要注意一下了,顶点着色器接受的参数都是模型最原始的参数,也就是美术同学指定的模型本身的一些参数,包括顶点的位置,法线,纹理坐标,颜色等等.unity通过MeshRenderer等render组件把顶点信息传递给了Shader,但是在Shader中是通过语义(semantic)来关联这些参数.

这个appdata_base是一个Unity为我们定义好的结构,就在我们上面写过的#include"UnityCG.cginc"包含进来.你可以在Unity安装目录的/Editor/Data/CGIncludes文件夹里面找打他看一看源代码。

所以在顶点着色其中我们可以通过appdata_base.XXX这种方式来直接获取模型的顶点信息了。具体官方解释查看这里。Unity_Matrix_MVP是unity提供好的模型空间转投影空间的矩阵,mul(UNITY_MATRIX_MVP,input.vertex)就能取到投影空间的坐标。

o.uv_MainTex = input.texcoord.xy;就是将uv信息传递进去。texcoord.xy就是uv信息。

第34~38行是片段着色器的代码,由于片段着色器的任务就是最后计算出一个颜色提供给渲染设备进行最后的处理,所以它的返回值为float4(存的是rgba).

函数的名字与前面#pragma约定好的一致.参数的话就是刚刚顶点着色器输出结构.

而最后面还跟了个:COLOR,这是为了把返回结果提供给:COLOR语义关联的寄存器,到时候渲染设备最后进行处理的时候去这里取片段着色器计算出来的结果就可以了.

tex2D函数,这是一个根据纹理坐标查询2D贴图颜色的函数,第一个参数是贴图,就是我们在上面声明的_MainTex,而后面是我们要查询的坐标,纹理坐标填上去就可以了,最终将为我们返回一个贴图上的颜色。

Unity的shader学习1的更多相关文章

  1. Unity的shader学习2

    下面继续看基于surface的shader代码,基本与Vertex&Fragment shader差不多,只是不能写pass,然后只需要声明surface函数,就能处理所有的事情. Shade ...

  2. 【Unity Shaders】Shader学习资源和Surface Shader概述

    写在前面 写这篇文章的时候,我断断续续学习Unity Shader半年了,其实还是个门外汉.我也能体会很多童鞋那种想要学好Shader却无从下手的感觉.在这个期间,我找到一些学习Shader的教程以及 ...

  3. Unity Shader 学习之旅

    Unity Shader 学习之旅 unityshader图形图像 纸上学来终觉浅,绝知此事要躬行 美丽的梦和美丽的诗一样 都是可遇而不可求的——席慕蓉 一.渲染流水线 示例图 Tips:什么是 GP ...

  4. Unity Shader 学习之旅之SurfaceShader

    Unity Shader 学习之旅之SurfaceShader unity shader 图形图像  如果大地的每个角落都充满了光明 谁还需要星星,谁还会 在夜里凝望 寻找遥远的安慰——江河 官方文档 ...

  5. 第四章 开始Unity Shader学习之旅(2)

    目录 1. 强大的援手:Unity提供的内置文件和变量 1.1 内置的包含文件 1.2 内置的变量 2. Unity提供的Cg/HLSL语义 2.1 什么是语义 2.2 Unity支持的语义 2.3 ...

  6. [转]Unity Shader 学习总结

    1.先来一段单张纹理贴图的shader示例代码: // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClip ...

  7. 【Unity Shaders】学习笔记——SurfaceShader(十一)光照模型

    [Unity Shaders]学习笔记——SurfaceShader(十一)光照模型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5664792.html ...

  8. 【Unity Shaders】学习笔记——SurfaceShader(十)镜面反射

    [Unity Shaders]学习笔记——SurfaceShader(十)镜面反射 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以. 水 ...

  9. 【Unity Shaders】学习笔记——SurfaceShader(九)Cubemap

    [Unity Shaders]学习笔记——SurfaceShader(九)Cubemap 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以 ...

随机推荐

  1. 一个简单的AboutMe页面

    Web2.0程序设计的小练习. Firefox下的效果 Chrome下的效果,套上了Helvetica,不知道为什么FF没有 (其实好像应该再优先加个Helvetica Neue的……呃……) 代码和 ...

  2. jquery validate表单验证插件的基本使用方法及功能拓展

    1 表单验证的准备工作 在开启长篇大论之前,首先将表单验证的效果展示给大家.    1.点击表单项,显示帮助提示 2.鼠标离开表单项时,开始校验元素 3.鼠标离开后的正确.错误提示及鼠标移入时的帮助提 ...

  3. python元类:type和metaclass

    python元类:type和metaclass python中一切皆对象,所以类本身也是对象.类有创建对象的能力,那谁来创建类的呢?答案是type. 1.用tpye函数创建一个类 class A(ob ...

  4. ES6 简介

    1.全称: ECMA 标准,又称ES2015 JavaScript 是大家所了解的语言名称,但是这个语言名称是商标( Oracle 公司注册的商标).因此,JavaScript 的正式名称是 ECMA ...

  5. python动态获取对象的属性和方法 (转)

    转自未知,纯个人笔记使用 首先通过一个例子来看一下本文中可能用到的对象和相关概念. #coding:utf-8 import sys def foo():pass class Cat(object): ...

  6. 【记录】Mysql 5.7 解压版的安装

    1.解压 2.打开my_default.ini 将basedir修改为MySQL的解压目录 将datadir修改为MySQL的解压目录\data 3.更改环境变量 系统变量里面添加MYSQL_HOME ...

  7. Blob和Clob在JDBC中的简介

    数据库在当今的应用越来越广泛了,同样伴随着领域的广泛,存储的内容也不在是只有数值.字符.boolean几种类型,而是越来越多样化.在这样的前提下就出现了Blob和Clob两个类型.下面我将对这个两个类 ...

  8. 力扣:丑数II和数组中前K大的元素

    数组中的第K个元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k ...

  9. Python开发基础-Day32 进程间通信、进程池、协程

    进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...

  10. 利用yii2分页插件,成对取出数组数据

    数组太大不好处理,切割出来处理 $ids = [1, 2, 3, 4, 5, 6, 7, 8, 9]; $count = count($ids);$size = 2; $pages = new Pag ...