TTY子系统初探

一、TTY子系统介绍

1、TTY介绍

TTY,一词源于Teleprinter,译为电传打印机,在早起用来表示电脑终端的设备。

现在我们通常使用TTY,是各种(物理/虚拟)终端的统称!

Linux系统的终端设备一般分为控制台终端伪终端串口终端其他类型四种。

下面我们来进一步了解这些Linux下常用的终端,为学习Linux TTY Framework打下基础!

cbe366c77f71c68a0664f1805e7e5856

2、控制台终端

控制台终端包括:系统控制台、当前控制台、虚拟控制台。

2.1 系统控制台

系统控制台,也就是我们Linux下面的/dev/console,是与操作系统交互的设备,系统所产生的信息会发送到该设备上。

目前只有在单用户模式下,才允许用户登录控制台/dev/console

console有缓冲的概念,为内核提供打印输出。内核把要打印的内容装入缓冲区__log_buff,然后由console指向某个激活的终端,来决定打印到哪里。console指向激活的终端

比如,我们在启动内核的时候,传入的参数console=ttyS1,将控制台终端指向ttyS1串口设备。

2.2 当前控制台

这是应用程序中的概念,如果当前进程有控制终端(Controlling Terminal),那么/dev/tty就是当前进程控制台的设备文件。

对于登录的Shell/dev/tty就是你正在使用的控制台,设备号(5,0),/dev/tty会映射到当前设备(使用命令tty可以查看它具体对应哪个实际物理控制台设备),输出到/dev/tty的内容只会显示在当前工作终端上。

你可以输入命令tty,显示当前映射的实际终端如:/dev/tty1或者/dev/pts/0等。

2.3 虚拟控制台

/dev/ttyn是进程虚拟控制台,他们共享同一个真实的物理控制台。

PC上,用户可以使用Ctrl + Alt + Fn切换,这种虚拟控制台对应tty1~n,其中:/dev/tty1代表第1个虚拟控制台;当使用Ctrl + ALT+F2进行切换时,系统的虚拟控制台为/dev/tty2 ,当前控制台(/dev/tty)则指向/dev/tty2

而比较特殊的是/dev/tty0,他代表当前虚拟控制台,其实就是当前所使用虚拟控制台的一个别名。因此不管当前正在使用哪个虚拟控制台(注意:这里是虚拟控制台,不包括伪终端),系统信息都会重定位到/dev/tty0上。

只有系统或超级用户root可以向/dev/tty0进行写操作。tty0是系统自动打开的,但不用于用户登录

3、伪终端

伪终端(Pseudo Terminal)是终端的发展,它多用于模拟终端程序,是远程登陆(telnet、ssh、xterm等)后创建的控制台设备。

它是成对出现的逻辑终端设备(即masterslave设备, 对master的操作会反映到slave上)。

简单说主终端和类似sshdtelnetd等用户空间的远程协议处理进程连接,而从终端则和shell之类的实际进程连接。

4、串口终端

串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。所以这些串行端口所对应的设备名称是/dev/ttyS0、/dev/ttyS1等,设备号分别是(4,0)、(4,1)等

若要向一个端口发送数据,可以在命令行上把标准输出重定向到这些特殊文件名上即可。 我们可以在命令行提示符下键入:echo "tekkaman" > /dev/ttyS1会把“tekkaman”发送到连接在ttyS1(COM2)端口的设备上。

在2.6以后的内核后,一些三星的芯片将串口终端设备节点命名为ttySACn

TI的Omap系列芯片从2.6.37开始,芯片自带的UART设备开始使用专有的的omap-uart驱动,故设备节点命名为ttyOn,以区别于使用8250驱动时的设备名“ttySn”。

img

5. 其它类型

还针对很多不同的字符设备存在有很多其它种类的终端设备特殊文件,例如针对ISDN设备的**/dev/ttyIn**终端设备等。

https://blog.csdn.net/liangzc1124/article/details/127469767

本文转载于网络 如有侵权请联系删除

相关文章

  • (二)深入浅出TCPIP之再识TCP,理解TCP三次握手(上)

    TCP作为一种可靠传输控制协议,其核心思想:既要保证数据可靠传输,又要提高传输的效率,而用三次握手恰恰可以满足以上两方面的需求!1.三次握手所谓的三次握手即TCP连接的建立。这个连接必须是一方主动打开,另一方被动打开的。TCP协议中,我们把主动发起请求的一端称为『客户端』,被动连接的一端称为『服务端』。不管是客户端还是服务端,TCP连接建立完后都能发送和接收数据。1.1三次握手过程握手之前主动打开连接的客户端结束CLOSED阶段,被动打开的服务器端也结束CLOSED阶段,并进入LISTEN阶段。随后开始“三次握手”:第一次握手 客户端向服务端发送连接请求报文段。该报文段的头部中SYN=1,ACK=0,seq=x。请求发送后,客户端便进入SYN-SENT状态。PS1:SYN=1,ACK=0表示该报文段为连接请求报文。PS2:x为本次TCP通信的字节流的初始序号。 TCP规定:SYN=1的报文段不能有数据部分,但要消耗掉一个序号。第二次握手 服务端收到连接请求报文段后,如果同意连接,则会发送一个应答:SYN=1,ACK=1,seq=y,ack=x+1。 该应答发送完成后便进入SYN-RCV

  • GIT学习----第十五节:Feature分支

    学习目的如何对未进行合并的分支进行强制删除?强制删除未合并分支建立并切换新功能分支feature-001$gitcheckout-bfeature-001 Switchedtoanewbranch'feature-001' Mreadme.txt复制查看工作区$gitstatus Onbranchfeature-001 Changesnotstagedforcommit: (use"gitadd<file>..."toupdatewhatwillbecommitted) (use"gitcheckout--<file>..."todiscardchangesinworkingdirectory) modified:readme.txt nochangesaddedtocommit(use"gitadd"and/or"gitcommit-a")复制提交$gitaddreadme.txt $gitcommit-m"测试新功能分支" [feat

  • 首屏渲染时间的计算

    背景图背景最近和团队中的小伙伴一起开发一个叫Aegis的前端监控系统(目前仅在腾讯内部开源)。既然是前端监控系统,除了要对各种异常进行监控,还需要收集前端的各项性能,其中就包括"首屏渲染时间"这个重要指标。由于React、Vue等框架的出现,DOMContentLoaded事件已经失去了原本的作用,现在"首屏渲染时间"的计算大多数时候是依靠人工打点,这与Aegis“业务零侵入”的设计理念不相符,为此,需要开发一套新的算法,尽可能准确的对“首屏渲染时间”进行估算。本文实现的算法主要依靠了浏览器提供的两个API:MutationObserver、performance。MutationObserver可能大家对这个API还比较陌生,不过目前浏览器对该API的支持情况已经非常好了。mutationObserverMutationObserver给我们提供了监听页面DOM树变化的能力,其用法非常简单://注册监听函数 constobserver=newMutationObserver((mutations)=>{ console.log('

  • 李宏毅深度学习之Deep Learning 计算图/反传播

    5.1计算图定义 所谓计算图,就是一种语言,这个语言是用来描述一个函数,我们知道neuralnetwork就是一个函数,所以我们需要描述函数的语言。其实graph有很多种定义方法,但是我们通常使用node来表示一个变量,他可以是一个scalar(标量),vector(向量)甚至是tensor(张量),这里的每一个edge代表了一个operation。y=f(g(h(x))),如何去画计算图,如上图所示,可以分布拆解。举个具体例子,计算e=(a+b)*(b+1),令c=a+b,d=b+1,则e=c*d,则可以得到如下图计算图。这个图的好处就是,我们在这个图上算变量的梯度是很容易的。根据这个图算变量的梯度之前,需要先了解一下链式法则。彪了我一口老血,幸亏我还能看懂。看来这下子接下去要愉快玩耍需要重新拾起数学来了。用上图加入链式法则。如果想同时计算和呢?这样做的好处就是,如果今天是computationalgraph,你最终的函数的输出只有一个值,你又需要算大量的不同值的偏微分的时候,用reversemode会比刚才的forwardmode还要更有效率,而在做neuralnetwork的时候

  • MySQL数据备份与恢复(二) -- xtrabackup工具

    上一篇介绍了逻辑备份工具mysqldump,本文将通过应用更为广泛的物理备份工具xtrabackup来演示数据备份及恢复的第二篇内容(本文篇幅较长,建议收藏后阅读)。01xtrabackup工具的安装1.1安装依赖包复制/*xtrabackup的使用需要安装相关的依赖包否则使用过程中会报相关错误*/ yuminstall-yrsyncperllperl-Digest-MD5perlperl-devellibaiolibaio-develperl-Time-HiResperl-DBD-MySQL复制1.2下载及安装 去percona官网下载对应版本的安装包https://www.percona.com/downloads,因为每个版本对应的数据库版本不同,因此需要根据数据库的版本选择对应的xtrabackup的安装包.当前测试使用的数据库为MySQL5.7因此下载2.4版本https://www.percona.com/downloads/Percona-XtraBackup-2.4/LATEST/另外,2.4.10及以后版本中,对libgcrypt进行了区分,因此也需要查询自己服务器的

  • Android Q和中端手机:这是我们在谷歌I/O 2019上看到的所有东西

    什么一个开端。谷歌I/O2019主题演讲结束了,但从头到尾感觉都像是一场力作。虽然我们的一些预测没有成真——我们将永远不会有像素手表吗?-最期待的谣言成真,这意味着我们遇到了一些理想的新硬件,包括中档像素3a和NestHubMax。不出所料,AndroidQ也参加了,这让我们对移动技术的未来更加兴奋。但有很多事情我们没有预见到,包括谷歌专注于创造人人都能参与的移动技术,以及缩小现有工具的规模,使它们更容易被所有人使用。这是我们在2019年谷歌I/O上看到的一切。PIXEL3A和3AXL:适合多数人,而非少数人手机越来越贵,谷歌对此并不满意。这就是为什么它推出了中端Pixel3a和3aXL-谷歌,这是自Nexus系列以来的首款中端手机,也是首款非旗舰像素手机。它配备了良好的中档配置,包括Snapdragon670,并配有4GB内存和64GB板载存储。按照传统,没有MicroSD卡,但用户可以在谷歌照片上获得免费的高分辨率存储。正如预期的那样,它运行的是纯像素版本的Android9.0Pie,并保证获得为期三年的主要Android更新和安全补丁。与全玻璃的Pixel3系列不同,Pixel3

  • 让失声群体重获“新声”,脑机接口领域现重大突破

    镁客网新增【科创板报】栏目实时速递科创板最新消息研究团队研发出一款解码器,能够利用人工智能基于大脑数据合成语音。策划&撰写:韩璐日前,学术期刊《自然》在线发表了一篇文章,其中涉及一种解码器,能够将大脑神经信号转化为语音,帮助无法说话的患者实现发声交流。据了解,该解码器由加州大学旧金山分校的神经外科学家EdwardChang教授与其同事一同开发。他们采用了一种叫做“高密度脑皮层电图”的技术,能够基于癫痫患者脑中被植入的电极(医疗监测需要)所传出的数据,直接记录下受试者大脑皮层的神经活动。过程中,受试者会被要求大声读出几百条句子,研究人员则会同步记录他们大脑腹侧感觉运动皮层区的神经活动,这里是大脑的语音产生中心。随后,研究人员将利用循环神经网络破译采集到的神经信号,其中涉及两个步骤:第一步,他们将神经信号转换为表征发音器动作的信号,包括下巴、喉、嘴唇和舌头动作相关的脑信号;第二步,他们则根据解码出来的发音器官动作,把信号转换为说出的语句。为了验证自己的成果,研究人员已经在亚马逊的众包任务平台MechanicalTurk上招募了听众,来辨认解码器合成的语音,测试内容包括325个单词和

  • 谷歌程序员辞职创业,赚钱还没原来多,码农工资有泡沫吗?

    晓查发自凹非寺 量子位报道|公众号QbitAI程序员是真正的高薪行业。近年来随着AI行业的兴起,工资更是高到吓人,有公司甚至愿意为AI工程师开出百万年薪。关于这个现象,不仅我国人民喜闻乐见,美国人民也争论不休。最近一位名叫JackWilson的程序员发文,丢出一个问题:程序员这个行业存在泡沫吗?引发了网友热烈讨论。让Jack开始怀疑人生的是他7年前做出的一个决定。Jack曾是一名谷歌工程师,2012年选择离职创业。和大多数“俗人”一样,他创业既是为了梦想,也是为了赚更多的钱,希望有朝一日能实现财务自由,不必再辛苦工作。然而他发现如果当初没有离职的话,现在可能赚的更多。打工比当老板赚的还多,这让开始反思程序员的高工资是否合理。程序员收入有多可怕Jack首先给谷歌的工程师算了一笔账:一位有5到10年经验的资深工程师,进入Google后可以获得约21.5万美元的年收入,其中包括15万美元基本工资、5%-10%的奖金以及其他股票期权。其中,股票期权的价值可能总共有20万美元,分4年行权,每年有5万美元的收入。这还仅仅是基于当前股价来估计。如果公司股价一路飙升,你会赚的更多。如果你在谷歌工作2~

  • android 调试工具之facebook stetho介绍

    概述Stetho是Facebook开源的一个Android调试工具。是一个ChromeDeveloperTools的扩展,可用来检测应用的网络、数据库、WebKit、SharePreference等方面的功能。开发者也可通过它的dumpapp工具提供强大的命令行接口来访问应用内部。推荐它的原因是不需要root,就可以实现上面的功能。配置好之后,在Chrome地址栏输入chrome://inspect既可。 查看网络请求(类似于fiddler或者charles):查看数据库等使用使用主要分为4部:1.项目添加依赖compile‘com.facebook.stetho:stetho:1.3.1‘复制2.初始化StethopublicclassMyApplicationextendsApplication{ publicvoidonCreate(){ super.onCreate(); Stetho.initializeWithDefaults(this); } }复制3.修改网络请求(可自行修改app的请求方式)对于请求的方式,可以根据自己项目实际网络的使用情况来选择,这里比如我使用的ok

  • SQL递归查询知多少

    最近工作中遇到了一个问题,需要根据保存的流程数据,构建流程图。数据库中保存的流程数据是树形结构的,表结构及数据如下图:仔细观察表结构,会发现其树形结构的特点:FFIRSTNODE:标记是否为根节点FSTABLENAME:标记来源单据名称FSID:标记来源单据分录IDFTTABLENAME:标记目标单据名称FTID:标记目标单据分录ID图中的流程为: 销售合同-->销售订单-->发货通知单-->销售出库单首先想到的办法就是把流程数据取回来,然后代码构造流程图。 第一个思路:根据根节点循环往下找,吭呲半天,发现没那么简单。 因为任何一个源头单据都可以多次下推目标单据: 第二个思路:先找到终极节点,在从终极节点往上找只至根节点为0。 这个思路实现起来也没有那么复杂,逻辑理清,循环遍历,最终也能实现结果。(但在大数据量情况下,易导致性能瓶颈。)这一次我们换一个思路,让SQL来替我们做这一复杂的递归查询。一、SqlServer递归查询1、基本概念公用表表达式(CTE)可以认为是在单个SELECT、INSERT、UPDATE、DELETE或CREATEVIEW语句的执行范围内定义

  • offer总包50w,写一篇测试面试实记

    大家好,我是CC,这是第103篇原创。这篇是朋友给我聊的最近面试的一些情况,我来做一个简单分析,这位朋友最终拿到的offer是50w,从面试题分析来看,客观题并不是很难,没什么八股文,基本是按照简历里面的内容做的提问,我认为这是一个比较务实的做法,听过一些朋友吐槽,一些企业面试官喜欢拿着自己的笔记本问,不会过多看你简历里面的技能,全程信息不对称很尴尬。这位朋友做过业务测试,自动化和性能都有不错的实践,所以市场对这样的同学还是蛮欢迎的。对于大家来说,很关心面试了什么类型的题目,我写了下客观题,必有读者问,能不能说下答案,我说下自己的思路,仅供参考,这位同学基于业务测试面试偏技术的多一点,非管理岗位。首先肯定会有一些通用类的,比如:描述你当前的工作职责?项目中遇到的问题,如何解决? 通过这两个题目基本都够看出来你在公司的一个段位和思考力,无论你在管理层和执行层面没有思考沉淀这样的同学价值不会很大,所以这两个问题其实非常有针对性,可以结合你现实的情况多思考,多沉淀话术。这样的问题在于数据和实例,不用流水账一样记录平时的工作内容。除了通用类,关于测试本身,往往业务的、性能的、自动化的都会问,尤

  • golang 复杂结构json转为map

    1、存在json文件:j.json,内容如下: { "aa":{"code":205,"hot":1}, "bb":{"code":206,"hot":1}, "cc":{"code":207,"hot":1}, "dd":{"code":208,"hot":1}, "ee":{"code":209,"hot":1}, "ff":{"code":210,"hot":1}, "gg":{"code":211,"hot":1}, "hh":{"code":212,"hot":1}, "ii":{"code":213,"hot":1} }复制 2、同目录下main.go,编写读取解析代码: packagemain import( "encoding/json" "fmt" "io/ioutil" ) funcreadFile(){ b,err:=ioutil.ReadFile("./j.json") iferr!=nil{ fmt.Println(err) } whitelist:=map[string]map[string]int{} err=json.Unm

  • PyTorch 60 分钟入门教程:数据并行处理

    可选择:数据并行处理(文末有完整代码下载) 作者:SungKim 和 JennyKang 在这个教程中,我们将学习如何用DataParallel来使用多GPU。 通过PyTorch使用多个GPU非常简单。你可以将模型放在一个GPU: device=torch.device("cuda:0") model.to(device) 然后,你可以复制所有的张量到GPU: mytensor=my_tensor.to(device) 请注意,只是调用my_tensor.to(device)返回一个my_tensor新的复制在GPU上,而不是重写my_tensor。你需要分配给他一个新的张量并且在GPU上使用这个张量。 在多GPU中执行前馈,后馈操作是非常自然的。尽管如此,PyTorch默认只会使用一个GPU。通过使用DataParallel让你的模型并行运行,你可以很容易的在多GPU上运行你的操作。 model=nn.DataParallel(model) 这是整个教程的核心,我们接下来将会详细讲解。 引用和参数 引入PyTorch模块和定义参数 importtorch imp

  • Git常用命令与入门

    Git仓库就是那个.git目录,其中存放的是我们所提交的文档索引内容,Git可基于文档索引内容对其所管理的文档进行内容追踪,从而实现文档的版本控制。.git目录位于工作目录内。对于任何一个文件,在Git内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。 Git的三种状态: Change(Unstaged):你改动了一个,没有调用任何git命令前,就是这种状态。 Staged暂存区:调用gitadd或者gitcommit-a之后,进入Staged状态,表示申明要变动了。 Committed:Commit,生成新的版本commit号,进入此状态。 常见状态提示: nothingtocommit(workingdirectoryclean):所有已跟踪文件在上次提交后都未被更改过 Untrackedfiles:未跟踪文件 Changestobecommitted:已跟踪文件(在添加add命令之后的文件与修改后又添加add命令之后的文件) Changesnotstagedforcommit:已跟踪文件的内容发生了变化,但还没有放到暂存区,

  • vue路由小节

    1、router-link跳转   <router-link:to="{name:'home'}"/> <router-link:to="{path:'/home'}"replace/>复制 注意: 如果希望跳转后,不保留上一个页面的历史记录,可以在router-lick上加入replace链接如果是'/'开始就是从根路由开始,如果开始不带'/',则从当前路由开始。 2、this.$router.push({}) methods:{ onchange(){ this.$router.push({//核心语句 path:"/home",//路径 query:{//路由传参时,push和query搭配使用,作用时传递参数 id:"123" } }) } } //home.vue文件接收时; exportdefault{ data(){ return{ id:'' } }, created(){//生命周期接收参数 this.id=this.$route.query.id,//接收参数关键字 console.log(this.id) } }复制

  • 【题解】The Magician HDU 6565 大模拟

    寒假大模拟加训。 直接贴代码。 一遍过样例,一遍AC,开心~ #include<bits/stdc++.h> usingnamespacestd; typedefpair<int,int>pii; int_w; enum{plain=0,swamp=1,mountain=2,island=3,forest=4}; queue<int>deck[2]; inthand[2][5],field[2][5],grave[2][5]; voiddraw_card(intp){ queue<int>&dck=deck[p]; int*hnd=hand[p]; if(!dck.empty()){ intx=dck.front(); dck.pop(); ++hnd[x]; } } booldraw(){ if(!deck[0].empty())returnfalse; if(!deck[1].empty())returnfalse; for(inti=0;i<2;++i) for(intj=0

  • App启动速度优化

    一、概述 要优化App的启动速度,首先需要了解App的启动流程。在Android系统中,系统会为每一个应用开辟一个Linux进程,默认情况下应用都运行在自己的进程中。 一个完整的App启动流程也包含进程的创建过程,关于进程(Application),Google在解释文档中描述为: Bydefault,everyapplicationrunsinitsownLinuxprocess.Androidstartstheprocesswhenanyoftheapplication’scomponentsneedtobeexecuted,thenshutsdowntheprocesswhenit’snolongerneededorwhenthesystemmustrecovermemoryforotherapplications. 也就是说: 当用户要启动App中任意一个组件时,系统都会首先启动这个应用的进程 在适当的时候,系统会关闭这个进程 那么,当用户点击桌面图标启动一个应用界面时,底层的完整流程如下: Click事件 Launcher调用startActivity() A

  • echarts 图表缩放 X轴Y轴数据缩放

    鼠标滚动缩放    Y轴与X轴数据缩放,在dataZoom中设置即可 varXdata=['63.27','27.90','33.52','17.98','42.25','24.54','33.96','11.73','72.58','45.36',]; varYdata=['西安市','铜川市','咸阳市','汉中市','商洛市','安康市','渭南市','宝鸡市','延安市','榆林市',]; option={ title:{ text:'', textStyle:{ fontSize:12, color:'#11DEF6',//标题颜色 }, subtext:'', subtextStyle:{ fontSize:12, color:'#E4765D',//副标题标题颜色 }, }, color:['#3398DB'], tooltip:{ trigger:'axis', axisPointer:{ //坐标轴指示器,坐标轴触发有效 type:'shadow',//默认为直线,可选为:'line'|'shadow' }, }, grid:{ left:'3

  • 《算法竞赛入门经典》5.32排序与检索-字母重排

      输入一个字典(用******结尾),然后再输入若干单词。每输入一个单词w,你都需要在字典中找出所有可以用w的字母重排后得到的单词,并按照字典序从小到大的顺序在一行中输出(如果不存在,输出:()。输入单词之间用空格或空行隔开,且所有输入单词都由不超过6个小写字母组成。注意,字典中的单词不一定按字典序排列。 1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4intn; 5charword[2000][10],sorted[2000][10]; 6//字符比较函数 7intcmp_char(constvoid*_a,constvoid*_b) 8{ 9char*a=(char*)_a; 10char*b=(char*)_b; 11return*a-*b; 12} 13 14//字符串比较函数 15intcmp_string(constvoid*_a,constvoid*_b) 16{ 17char*a=(char*)_a; 18char*b=(char*)_b; 19return

  • Spark读取json数据不匹配的情况

      今天晚上,我们老师给我们布置了一个任务,用spark读取一些json数据,然后做一些数据分析的任务       我以为重头戏是数据分析的部分,没想到自己被读取json数据拦了1个多小时,写篇博客记录下orz    常规的读取数据:  valuserInfo=spark.read.format("json").json("WebProjectTest/data/Users_Data.log")valuserLog=spark.read.format("json").json("WebProjectTest/data/Log_Data.log")复制     数据集1         数据集2         一开始我死抓数据集1,可是读取出来的数据并不是对应的,而是混乱的         想了半天没想明白,然后试了下数据集2,却发现没有毛病   这就奇了怪,难道是数据太大的原因,可是spark本来就是处理大数据的,没理由这100MB就给干趴了啊   我决定将数据集1中的数据截取一点出来,然后自己试验一下,终于让

  • Decal Buffer相关

    延迟渲染与前向渲染 前向渲染或叫正向渲染,每一个图元都经过顶点着色器,图元着色器,片段着色器,在片段着色器内连同光照一起计算,效率和图元数量有关。 延迟渲染会先计算出G-BUFFER,就是不含光照计算,但有光照需要的信息的BUFFER,最后在一个片段着色器内进行一次光照计算,效率和屏幕像素有关。 http://m.elecfans.com/article/651416.html比较概括 https://learnopengl-cn.github.io/05AdvancedLighting/08DeferredShading/比较详细 https://www.cnblogs.com/wangchengfeng/p/3440097.html https://blog.csdn.net/taotaoah/article/details/52633822 https://zhuanlan.zhihu.com/p/39464715 G-Buffer GeometryBuffer,亦即“几何缓冲”。区别于普通的仅将颜色渲染到纹理中,G-Buffer指包含颜色、法线、世界空间坐标的缓冲区,亦即指

相关推荐

推荐阅读