Unity Shader学习笔记-1
本篇文章是对Unity Shader入门精要的学习笔记,插图大部分来自冯乐乐女神的github
如果有什么说的不正确的请批评指正
渲染流水线
流水线机制,拆分小段,前面的工序不用等后面的工序,流水线机制在计算机世界中经常使用,比如:TCP

流程图
渲染管线

应用阶段(开发者控制)、几何阶段(决定图元)、光栅化阶段(决定像素)
Shader作用
顶点着色器:实现顶点的空间变换,坐标变换(模型空间转换到齐次裁减空间)、逐顶点光照、计算顶点颜色
曲面细分着色器:细分图元,图元就是:点、线、面等渲染所需的几何信息
几何着色器:执行逐个图元的着色操作,或者用于产生更多的图元
片元着色器:逐片元的着色操作,修改颜色、深度缓冲、进行混合
屏幕映射

三角形遍历
三角形设置:由定点信息计算出边的信息
三角形遍历:计算是否在三角形内,使用与三条边叉乘的方法判断在边的左边或者右边,遍历3条边的方式按照顺时针或者逆时针,对应点在
计算三角形内的数据:

计算颜色:插值计算

两大渲染测试
决定是否丢弃片元
- 模板测试
- 通常用于限制渲染的区域
- 使用一个比较函数比较参考值和实际值
- 高级用法:渲染阴影、轮廓渲染
- 深度测试
- 与深度缓冲区的深度值进行比较大于时舍弃该片元
- 如果一个片元没有通过深度测试那么它就没权力修改深度缓冲区
- 两者的区别:除功能外,模板状态设置更新即使舍弃了该片元也会更新模板缓冲区的值
- early-z的方法:提前进行深度测试,可以帮助决定是否绘制片元,减少GPU开销
混合
合并颜色,颜色缓冲区,这次得到的结果和存储的结果进行合并

CPU、GPU、图形接口和驱动的关系
CPU和GPU之间的通信
数据加载到显存(显卡的内存,图像缓冲、深度缓冲)
设置渲染状态
调用DrawCall

CPU和GPU并行工作的秘密:命令缓冲区
一个命令队列,cpu给命令、gpu拿命令
drawcall就是一种命令,GPU的渲染速度很快,性能瓶颈主要是在CPU传递命令这方面
减少drawcall的方法有很多,其中Batching批处理是很常用的方法,思路就是把小的drawcall合并成大的drawcall,适用于静态的物体

显示流畅的方法
- Double Buffering:避免我们看到正在渲染的片元
- Front Buffer
- 实际显示的图像
- Back Buffer
- 在后面渲染的图像
- 后置缓冲区渲染完成后交换两缓冲区的值
- Front Buffer
着色器语言
用于编写着色器的语言,主要是顶点着色器和片元着色器需要编写
- HLSL DirectX
- 微软控制的着色器编译,各硬件编译的结果相同
- CG NVIDIA
- 和HLSL很像,根据平台的不同编译成相应的中间语言
- GLSL OpenGL
- 依赖硬件来编译,用显卡驱动来编译,各驱动的编译结果根据硬件变化
- 它们编译成中间语言IL给显卡驱动识别(这也是某种跨平台的意思吧-。-)
- ShaderLab unity的简化语言,少了很多的配置流程,大部分流程是unity自己做
ShaderLab
Shader选用
摘取乐乐女神的指导

一般用CG/HLSL代码写: CG代码和DX9的HLSL代码几乎一样,要在CGPROGRAM中写,CGPROGRAM要使用上面的Property的数据就要声明和上面Property一样名字一样类型的变量,如果不想在多个Pass里声明,则可以在Pass前的CGINCLUDE ... ENDCG之间声明变量,这样的Property是多Pass共用的
Properties{
_Color("Color Tint", Color) = (1, 1, 1, 1)
}
SubShader{
Pass{
...
fixed4 _Color;
...
}
}
顶点片元着色器 Unlit Shader
结构
命个名和shader在面板中的目录
Shader "Custom/MyShader" //名字
Properties
属性,会出现在材质面板中
Properties{
Name("display name",PropertyType) = DefaultValue
//.......
}
Name:属性的名字
display name:显示的名字
PropertyType:类型
ps:shader里改过了Property在C#脚本里并不能获得更改后的信息,只能获得预设的信息,GPU像CPU传数据使用Compute Shader
数据类型

2D、Cube、3D是三种纹理类型,默认值是一个字符串+{},字符串是内置的纹理名称
SubShader
unity扫描所有的SubShader块找到能够在目标平台上运行的SubShader,如果找不到就使用Fallback提供的Unity Shader
SubShader
{
[Tags]//标签
[RenderSetup]//状态
Pass{
}//完整的渲染流程
//Other Pass
}
显卡状态,在Pass里写的,剔除、深度、混合

怎么样以及何时渲染该对象,渲染队列最重要

Pass
表示渲染流程,一个Pass表示通过管线一次,可以写顶点着色器和片元着色器

UsePass可以使用其他Unity Shader的Pass,以提升复用性(用法:指明路径,并且Pass要有Name)

LightMode在有光照信息时读取光源的信息使用,主要是确定光源位置等
一个简单的Shader
Shader "Unlit/Chapter5SimpleShader"
{
SubShader
{
//选择不声明任何材质属性
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag//编译指令
//哪个函数包括了顶点着色器的代码
//哪个函数包括了片元着色器的代码
#include "UnityCG.cginc"//调库,你的unity目录\Editor\Data\CGIncludes
struct a2v {
float4 vertex :POSITION;
float3 normal:NORMAL;
float4 texcoord:TEXCOORD0;
};
float4 vert(a2v v) :SV_POSITION{
return UnityObjectToClipPos(v.vertex);
}//接受顶点坐标(POSITION)返回了顶点在裁剪坐标的位置(SV_POSITION)
float4 frag() : SV_Target{
return fixed4(1.0,1.0,0.0,1.0);
}//SV_Target告诉渲染器把用户的输出颜色存储到一个渲染目标中,这里是帧缓存
ENDCG
}
}
}
POSITION、NORMAL、TEXTCOORD0等都称为语义semantic,在结构体里的表示把提取到的信息当成一个什么对待,输出语义表示输出的结果是作为什么对待
POSITION顶点位置,在模型空间,NORMAL顶点法向量,也是模型空间,TEXTCOORD0表示纹理坐标,按理说纹理坐标只要uv,2维就可以了,但是有时比如天空盒的纹理需要用到3维的信息,一张纹理图有时前两维给一些信息,后两维又给一张图的uv信息

vert里的输出语义没有也可以,可以选择输出结构体
struct a2v {
float4 vertex : POSITION;
float2 texcoord0 : TEXCOORD0;
};
...
v2f vert(a2v i)
{
v2f o;
o.pos = UnityObjectToClipPos(i.vertex);
o.uv = i.texcoord0;
return o;
}
...
在frag里的SV_Target表示屏幕上的像素(帧缓冲),还可以输出SV_Depth来覆盖深度缓冲区,不过官方说吃性能
库文件



调试
1、假彩色图像,把数据作为颜色输出到屏幕上然后用取色器查看的数值调试法。
没办法,渲染管线里的数据不是想拿就拿的,让你随便拿了管线不相当于开了个洞,像素都漏了
2、帧缓冲区调试,Frame Debugger
3、VS插件ShaderLab补全,体验一般,甚至不想开
注意点
GPU结构决定它不擅长处理选择、循环等结构的程序,分支下的代码、分支的层数要尽可能少因为他会降低GPU的并行处理操作,条件变量最好是常数
3D数学
太多了,不好写,基础知识看看乐乐老师的书吧0.0
空间
各种空间关系一开始搞不太懂也没事,后面可以在实践中慢慢理解
这块乐乐老师的书上讲的牛的点变换推导很详细
模型空间:也叫对象空间、局部空间
世界空间:绝对位置,一个Transform没有父节点他的位置就是绝对位置
观察空间:摄像机空间,模型空间的特例
- 摄像机右手系

- 观察变换:投影变换
裁剪空间:clip space 裁剪矩阵,有一个视锥体决定摄像机可以看到的空间
- 投影矩阵的本质就是对xyz分量进行不同程度的缩放
屏幕空间
- 降维2d坐标
- 进行齐次除法
- 透视出发转化到NDC归一化的设备坐标

unity坐标旋向性

Unity Shader学习笔记-1的更多相关文章
- 【Unity Shader学习笔记】Unity基础纹理-单张纹理
1 单张纹理 1.1 纹理 使用纹理映射(Texture Mapping)技术,我们把一张图片逐纹素(Texel)地控制模型的颜色. 美术人员建模时,会在建模软件中利用纹理展开技术把纹理映射坐标(Te ...
- 【Unity Shader学习笔记】Unity基础纹理-渐变纹理
纹理可以用来存储任何表面属性. 可以通过使用渐变纹理来实现插画风格的渲染效果. 这项技术是由Valve公司提出的.Valve使用它来渲染游戏中具有插画风格的角色. 我们使用半兰伯特模型计算漫反射. 因 ...
- Unity Shader学习笔记 - 用UV动画实现沙滩上的泡沫
这个泡沫效果来自远古时代的Unity官方海岛Demo, 原效果直接复制3个材质球在js脚本中做UV动画偏移,这里尝试在shader中做动画并且一个pass中完成: // Upgrade NOTE: r ...
- 【Unity Shader学习笔记】Unity基础纹理-法线贴图
1 高度纹理 使用一张纹理改变物体表面法线,为模型提供更多细节. 有两种主要方法: 1.高度映射:使用一张高度纹理(height map)来模拟表面位移(displacement).得到一个修改后的法 ...
- 【Unity Shader学习笔记】Unity光照基础-高光反射
1.原理 1.1.Phong模型 计算高光反射需要表面法线.视角方向.光源方向.反射方向等. 在这四个矢量中,我们实际上只需要知道其中3个矢量即可,而第4个矢量(反射方向r)可以通过其他信息计算得到: ...
- 【Unity Shader学习笔记】Unity光照基础-半兰伯特光照
在光照无法达到的区域,模型的外观通常是全黑的,没有任何明暗变化,这会使模型的背光区域看起来就像一个平面. 使用半兰伯特光照可以解决这个问题. 逐顶点光照技术也被称为兰伯特光照模型.因为它符合兰伯特定律 ...
- 【Unity Shader学习笔记】Unity光照基础-漫反射光照
本代码只适用于平行光. 1.逐顶点漫反射光照 1.1漫反射光照原理 1.2代码实现 在Properties语义块中声明一个漫反射颜色属性 Properties { //漫反射参数,用于调整漫反射效果 ...
- Unity Shader 学习笔记(一)
_MainTex_ST (1)简单来说,TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)主要作用是拿顶点的uv去和材质球的t ...
- unity shader学习笔记(1) shader基础结构以及Properties面板
首先是shader的基础结构: Shader "Custom/Example { Properties//变量属性面板 { } SubShader { Tags { "Render ...
随机推荐
- 怎么下载chrome的扩展程序
很多时候我们是没办法访问谷歌扩展应用程序 chrome应用商店的,这时候我们最好能把对应扩展应用程序下载保存,以便提供给其他人员使用. 搜索得到知乎有很全的方法: 如何导出并打包第三方chrome扩展 ...
- .NET 数据库事务的各种玩法进化
事务是数据库系统中的重要概念,本文讲解作者从业 CRUD 十余载的事务多种使用方式总结. 以下所有内容都是针对单机事务而言,不涉及分布式事务相关的东西! 关于事务原理的讲解不针对具体的某个数据库实现, ...
- 运用sed命令高效地删除文件的特定行
运用 sed 命令高效地删除文件的特定行 正常来说,我们想要删除文件中的某些行内容,一般都是先打开这个文件,然后找到要删除的内容,再然后选中这些行并按删除键进行删除,这在数据量很少时是没有问题的.但是 ...
- 开始System.out.println();
第一篇博客 我在逛别人的博客的时候,发现他们有些内容是写他们自己的人生,有些是关于技术方面的个人观点分享探讨,每当看到好的文章的时候,我已经习惯的去点击收藏.有的时候我也在想,我为什么就不能做一个输出 ...
- Linux系统下部署项目流程
一.系统架构 linux系统 centOS 6.9 应用服务器:Tomcat /JDK 数据库服务器:MySQL 二.连接远程工具FinalShell 1.Centos 6: 启动服务:service ...
- 微信小程序入门教程
首先请看demo 很简单的静态js就可以实现一款小程序开发. js.json.html.css四个核心文件 序言 开始开发应用号之前,先看看官方公布的「小程序」教程吧!(以下内容来自微信官方公布的「小 ...
- android开发之 listview中的item去掉分割线 隐藏分割线
有三种方法: 1> 设置android:divider="@null" 2> android:divider="#00000000" #000000 ...
- Android开发之开源框架OKHTTP的Get请求代码,得到json字符串方法
<span style="white-space:pre"> </span><pre name="code" class=&q ...
- java 注解开发
目录 注解 JDK自带的注解三个 注解分类 按照运行机制 按照来源分类 自定义注解的语法要求 元注解 解析注解 获取注解的注解 Spring中的注解 组合注解 注解 JDK自带的注解三个 @Overr ...
- 利用ANSI转义序列在控制台输出彩色文字
说明:无论什么语言,只要你的终端能够解释ANSI转义序列(大多数的类unix终端仿真器都能够解释ANSI转义序列,win32控制台则不支持),就能够使用ANSI转义序列输出颜色.这个功能看似鸡肋,但只 ...


