UnityShader学习笔记1 — — 入门知识整理
注:资料整理自《Unity Shader入门精要》一书
一、渲染流程概念阶段:

应用阶段:(1)准备好场景数据:(如摄像机位置,物体以及光源等)
(2)粗粒度剔除(Culling):(把不可见物体剔除,不导入下一阶段)
(3)设置每个模型的渲染状态:(如材质、纹理、shader等),输出渲染图元(rendering primitives)(如点、线、三角面等几何信息)并传递至下一阶段
几何阶段:(1)在GPU上处理绘制几何所需要的相关操作(具体操作细分在随后的GPU流水线中介绍)
(2)重要操作:把顶点坐标变换到屏幕空间中,再交给光栅器处理
(3)随后输出屏幕空间的二维顶点坐标,每个顶点的深度值、着色信息等至下一阶段
光栅化阶段:(1)利用上一阶段的数据在屏幕上产生像素,并渲染出最终图像(由逐顶点数据 -> 到逐像素数据)
注:这只是概念化的渲染阶段,具体硬件上的流程请参考下面的GPU流水线
二、GPU流水线:

几何阶段
顶点着色器(Vertex Shader):完成的主要工作有:坐标变换和逐顶点光照


裁剪(Clipping):将不在摄像机范围内的物体剔除掉

屏幕映射(Screen Mapping):
输入:上一阶段的单位立方体内的三维坐标
输出:二维屏幕坐标系(Screen Coordinates),与分辨率有关
保留Z轴坐标(深度值),与屏幕坐标系构成窗口坐标系(Window Coordinates)


光栅化阶段
光栅化阶段有两个重要目标:
计算每个图元覆盖哪些像素
替这些像素计算颜色
百科:光栅化(Rasterization)是把顶点数据转换为片元的过程,具有将图转化为一个个栅格组成的图象的作用
三角形设置(Triangle Setup):
计算光栅化一个三角网格所需的信息(如坐标信息等)
三角形遍历(Triangle Traversal):
检查每个像素是否被三角形网格所覆盖,如果是,则生成一个片元(Fragment)
通过三角网格来判断覆盖了哪些像素,并用3个顶点的顶点信息对这些像素插值
注:片元并不相当于像素,相比于像素还多了很多信息(如坐标,深度值、法线、纹理坐标等)

片元着色器(Fragment Shader):
输入:上一阶段的插值数据
输出:颜色值(一个或多个)

逐片元操作(Per-Fragment Operations(OpenGL)):
(Output-Merger(DirectX))
主要任务:(1)决定每个片元的可见性
(2)如果一个片元通过所有测试,则把这个片元的颜色值和已储存在颜色缓冲区中的颜色合并
模范测试和深度测试是可配置的,通常将片元的模板值/深度值与开发者给定的值进行比较,然后决定是否舍弃该片元
混合也是可配置的,决定是覆盖上一次颜色缓冲区中值还是进行合并(如透明效果)



三、其余补充

关于Draw Call
首先DrawCall通俗讲就是CPU对GPU发出的一个命令(CPU调用图像编程的API(如OpenGL和DirectX)以命令GPU开始渲染)
大致上的渲染阶段:CPU阶段:CPU从硬盘中加载数据到显存中 -> 设置好渲染状态 -> DrawCall
GPU阶段:参考上文第二部分GPU流水线

众所周知,DrawCall会影响游戏的帧数,而帧数则是由CPU和GPU两者中较差的那个决定了瓶颈上限,因此当DrawCall多了以后,如上图2.19所示,CPU需要一条条发布命令,而GPU由于对图像的渲染能力很强,可以一次渲染多个三角网格,此时往往就会导致CPU处理速度跟不上无法及时给出命令,而GPU则会处于空闲状态。
那如何减少DrawCall?
(1)避免使用大量很小的网格,如果必须使用时可以考虑把他们合并成一张大网格,减少节点数
(2)避免使用过多的材质

UnityShader学习笔记1 — — 入门知识整理的更多相关文章
- AngularJs学习笔记1——入门知识
1.什么是AngularJs AngularJs 诞生于2009年,由Misko Hevery 等人创建,后被Google收购,是一个优秀的Js框架,用于SPA(single pag ...
- python学习笔记--Django入门四 管理站点--二
接上一节 python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...
- WebSocket学习笔记——无痛入门
WebSocket学习笔记——无痛入门 标签: websocket 2014-04-09 22:05 4987人阅读 评论(1) 收藏 举报 分类: 物联网学习笔记(37) 版权声明:本文为博主原 ...
- MyBatis:学习笔记(1)——基础知识
MyBatis:学习笔记(1)--基础知识 引入MyBatis JDBC编程的问题及解决设想 ☐ 数据库连接使用时创建,不使用时就释放,频繁开启和关闭,造成数据库资源浪费,影响数据库性能. ☐ 使用数 ...
- golang学习笔记13 Golang 类型转换整理 go语言string、int、int64、float64、complex 互相转换
golang学习笔记13 Golang 类型转换整理 go语言string.int.int64.float64.complex 互相转换 #string到intint,err:=strconv.Ato ...
- canvas学习笔记、小函数整理
http://bbs.csdn.net/topics/391493648 canvas实例分享 2016-3-16 http://bbs.csdn.net/topics/390582151 html5 ...
- C#学习笔记(基础知识回顾)之值类型与引用类型转换(装箱和拆箱)
一:值类型和引用类型的含义参考前一篇文章 C#学习笔记(基础知识回顾)之值类型和引用类型 1.1,C#数据类型分为在栈上分配内存的值类型和在托管堆上分配内存的引用类型.如果int只不过是栈上的一个4字 ...
- C#学习笔记(基础知识回顾)之值传递和引用传递
一:要了解值传递和引用传递,先要知道这两种类型含义,可以参考上一篇 C#学习笔记(基础知识回顾)之值类型和引用类型 二:给方法传递参数分为值传递和引用传递. 2.1在变量通过引用传递给方法时,被调用的 ...
- C#学习笔记(基础知识回顾)之值类型和引用类型
一:C#把数据类型分为值类型和引用类型 1.1:从概念上来看,其区别是值类型直接存储值,而引用类型存储对值的引用. 1.2:这两种类型在内存的不同地方,值类型存储在堆栈中,而引用类型存储在托管对上.存 ...
随机推荐
- 浅析JS中的堆内存与栈内存
最近跟着组里的大佬面试碰到这么一个问题, Q:说说var.let.const的区别 A:balabalabalabla... Q:const定义的值能改么? A:你逗我?不能吧 不知道各位看官怎么想? ...
- redis key全量导出与导出指定前缀的key
redis命令列表中有两种方法可以全量导出所有的key: (1)keys 由于redis是单线程的,使用keys会导致redis服务阻塞,不建议线上服务采用这种方式. (2)scan 命令,下面是使用 ...
- 20145203盖泽双java实验三 敏捷开发与XP实践
java实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> ...
- Python之Web2py框架使用
本文主要是对Web2py框架的介绍和安装使用. 一. 介绍 全栈式Web框架:Web2py是 Google 在 web.py 基础上二次开发而来的,兼容 Google App Engine .是一个为 ...
- PAT乙级1033
1033 旧键盘打字 (20 分) 旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及坏掉的那些键,打出的结果文字会是怎样? 输入格式: 输入在 2 ...
- MapReduce -- 统计天气信息
示例 数据: -- :: 34c -- :: 36c -- :: 32c -- :: 37c -- :: 23c -- :: 45c -- :: 50c -- :: 33c -- :: 41c -- ...
- Spring Cloud 微服务项目实现总架构一
Spring Cloud 服务是一种分布式服务,包括配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,主节点选举, 分布式session, 集群状态等公共组件. 一 注册机 ...
- [iOS]异常捕捉
UncaughtExceptionHandler.h #import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interfac ...
- 实现点击到底部、顶部、指定div功能
顶部: $(".back_top").click(function () { scrollTo(0, 0); }); function goTop() { $('html, bod ...
- C语言学习记录_2019.02.23
char类型的输出: scanf("%d",&i);//i=49; char x=i; printf("x=%d\n",x); printf(" ...