Unity的shader学习1
先来看一段我们项目常见的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的更多相关文章
- Unity的shader学习2
下面继续看基于surface的shader代码,基本与Vertex&Fragment shader差不多,只是不能写pass,然后只需要声明surface函数,就能处理所有的事情. Shade ...
- 【Unity Shaders】Shader学习资源和Surface Shader概述
写在前面 写这篇文章的时候,我断断续续学习Unity Shader半年了,其实还是个门外汉.我也能体会很多童鞋那种想要学好Shader却无从下手的感觉.在这个期间,我找到一些学习Shader的教程以及 ...
- Unity Shader 学习之旅
Unity Shader 学习之旅 unityshader图形图像 纸上学来终觉浅,绝知此事要躬行 美丽的梦和美丽的诗一样 都是可遇而不可求的——席慕蓉 一.渲染流水线 示例图 Tips:什么是 GP ...
- Unity Shader 学习之旅之SurfaceShader
Unity Shader 学习之旅之SurfaceShader unity shader 图形图像 如果大地的每个角落都充满了光明 谁还需要星星,谁还会 在夜里凝望 寻找遥远的安慰——江河 官方文档 ...
- 第四章 开始Unity Shader学习之旅(2)
目录 1. 强大的援手:Unity提供的内置文件和变量 1.1 内置的包含文件 1.2 内置的变量 2. Unity提供的Cg/HLSL语义 2.1 什么是语义 2.2 Unity支持的语义 2.3 ...
- [转]Unity Shader 学习总结
1.先来一段单张纹理贴图的shader示例代码: // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClip ...
- 【Unity Shaders】学习笔记——SurfaceShader(十一)光照模型
[Unity Shaders]学习笔记——SurfaceShader(十一)光照模型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5664792.html ...
- 【Unity Shaders】学习笔记——SurfaceShader(十)镜面反射
[Unity Shaders]学习笔记——SurfaceShader(十)镜面反射 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以. 水 ...
- 【Unity Shaders】学习笔记——SurfaceShader(九)Cubemap
[Unity Shaders]学习笔记——SurfaceShader(九)Cubemap 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以 ...
随机推荐
- s12-day03-work01 python修改haproxy配置文件(初级版本)
#!/usr/local/env python3 ''' Author:@南非波波 Blog:http://www.cnblogs.com/songqingbo/ E-mail:qingbo.song ...
- Validating a Model
- 【LOJ】#2174. 「FJOI2016」神秘数
题解 这道题的结论很显然= = 就是暴力求的话,把一个区间的数排一下序,如果当前这个数大于前面所有数的前缀和+1,那么前缀和+1即我们所求的答案 那么我们设置一个当前答案(初始为1),在主席树上求出来 ...
- js获取或设置当前窗口url参数
直接上代码 // 获取当前窗口url中param参数的值 function get_param(param){ var query = location.search.substring(1).spl ...
- Scrollify – jQuery全屏滚动插件
和 fullPage.js 一样,Scrollify 也是一款基于 jQuery 的全屏滚动插件.跟 fullPage.js 相比,Scrollify 更加小巧,压缩后不足 4KB.但功能上不如 fu ...
- 《java虚拟机》----java内存模型与线程
No1. No2. java内存模型规定了所有的变量都存储在主内存中(Main Memory)中 每条线程还有自己的工作内存(Working Memory) 线程的工作内存中保存了被该线程使用到的变量 ...
- HDU 6183 Color it
线段树. 假设只有一种颜色,因为每次询问有一个$x$一定是$1$,那么我可以想办法找出每一个$y$最小的$x$是多少,如果最小的都不符合,那么一定不符合,因为更新变成了单点更新,询问是区间询问最小值, ...
- CodeForces 803D Magazine Ad
二分. 首先把字符串处理成一个数组,二分答案,判断一下即可. #include <cstdio> #include <cmath> #include <set> # ...
- Android之 ListView(1)
ListView是Android中最常用的控件之一. 当有太多数据需要显示的时候,ListView就派上用场了.它允许用户通过滑动手指的方式,将数据滑入滑出界面. 一.最简单的ListView实现 1 ...
- 【3.16高一(第二学期)模拟测试】 T3,T4题解
看到这个标题我想你一定会想为什么小编只发T3,T4的题解,原因有很多:1)小编也不怎么会讲:2)小编搜遍各大OJ,都没有找到可以提交的地方:3)虽然给了测试数据,小编懒得一个一个试.如果你找到了测评网 ...