为毛GPU Cache不能移动顶点?
这篇文章属于典型的剥洋葱文,由表及里,逐步引入新的知识点,挖掘最本质的原因。这篇文的逻辑是先假设再证明,按照这个思路去阅读会比较轻松。
Maya里的GPU Cache导入的几何体为什么不能编辑顶点?这可以算是一个高频问题了,这个问题可以转换为:GPU Cache导入的几何体为什么不能编辑Mesh(不仅不能编辑顶点,为它添加bevel一类的节点也不可以)?实际上这个问题在Maya的帮助文档中是有明确答案的。
我们来看看官方是如何解释的:
GPU caches are Alembic-based files that are optimized for fast playback performance in Maya. These performance gains come from the way GPU cache files are evaluated. The GPU cache node routes cached data directly to the system graphics card for processing, bypassing Maya dependency graph evaluation.
GPU cache是由Alembic文件派生出来的一种文件格式,为获取Maya中快速播放的性能专门做了优化。这些性能的提升来自于GPU cache文件求值的方式。GPU cache节点会避开Maya的dependency graph求值机制,把缓存数据直接发送到系统的图形卡接口进行处理。
现今的图形卡都有着比cpu夸张很多的线程数量,在并行计算的应用上有着极大优势,而图形处理的计算几乎都是线性计算,与图形卡的多线程简直是天作之合,GPU cache利用了图形卡的优势,把GPU cache文件中的缓存数据直接发送给图形卡进行计算,效率自然与基于传统计算框架cpu<-->memory的DG(dependency graph)机制不可同日而语。
但仔细一想,这段话有一个漏洞:虽然GPU cache导入的geometry无法编辑顶点,但整体移动还是可以的。这就与官方的解释相悖了,说好了会避开DG求值机制呢?
为了在这个问题上做更深层次的分析,我们插播一个DAG的小广告,快速的了解一下DAG的概念:
In Maya, a directed acyclic graph (DAG), defines elements such as the position, orientation, and scale of geometry. The DAG is composed of two types of DAG nodes, transforms and shapes. Maya's Directed Acyclic Graph (DAG) scene architecture, organized as a tree of transform nodes and shape nodes.
在Maya中,有向非循环图(Directed Acyclic Graph,DAG),定义了诸如几何体的位置、方向和大小等元素。有向非循环图由两种DAG节点构成,分别是Transform和Shape。Maya的有向非循环图(Directed Acyclic Graph,DAG)场景结构就是由transform和shape节点组成的一颗层级树。
A DAG node is simply an entity in the DAG. It may have and know about parents, siblings, and children, but it does not necessarily know about transformations or geometry. Transforms and Shapes are two types of nodes derived from a DAG node. A transform node is a type of DAG node which handles transformations (translate, rotate, and scale), while a shape node is a type of DAG node which handles geometry. A shape node does not maintain transformation information, and geometry cannot be hung below a transform node. This means that any piece of geometry requires two DAG nodes above it, a shape node immediately above it, and a transform node above the shape node.
DAG节点就是有向非循环图中的实体,该节点有且知道有哪些父节点、邻节点和子节点,但它并不必需要知道相关的transform信息和几何体信息。Transform和Shape是两种派生自DAG节点的节点,Transform节点是一种能处理transformation(译作变换,属于线性计算,包含translate、rotate、scale信息)信息的DAG节点,Shape节点是一种能处理geometry(几何体)信息的DAG节点。Shape节点不会维护transformation信息,geometry也不能放在Tranform节点下面。这意味着任意一片geometry都需要有两个DAG节点放在它的层级之上,Shape节点放置在geometry上面,transform放置在Shape节点上面,通过这种方式构造出一个层级关系树,供DAG使用。
Geometry层级示例:
Transform Node --> 处理transformation信息
|
Shape Node --> 处理下方Geometry信息
|
Geometry Data --> 可能存放在内存中,也可能存放在GPU显存中
根据DAG的概念,我们可以推论:对于GPU cache导入进来的geometry来说,必然会为它创建两个DAG节点,一个是Transform Node,一个是Shape Node。其中Tramsform节点中的tramsformation信息是可以编辑的,可以接受外部的位移操作,而Shape节点持有的geometry信息是不可编辑的。
但现在这个推论还是不够深入,为什么Alembic Cache既能编辑transformation又能编辑geometry信息,唯独GPU cache只能编辑transformation?
下面我们再引入DG(dependency graph)的概念,更进一步的,去Maya的底层找答案。
The dependency graph lies at the heart of Maya. It maintains the construction history of the scene: a record of what operations you have applied in what order. The graph is made up of a series of interconnected nodes, each of which encapsulates a single operation or a single set of calculations. Each node accepts a limited set of well-defined input data, performs its calculations based on that data, and produces one or more output values.
Dependency graph(依赖图)位于Maya核心,它维护着场景的构造历史,在这里,构造历史指的是你以某种顺序应用的操作记录。该图由一系列相互连接的节点组成,每一个节点封装一个操作或一组计算。每个节点接受有限的一组定义好的输入数据,再根据该数据执行计算,并生成一个或多个输出值。
Most objects in Maya are dependency graph nodes, or networks of nodes (several nodes connected together). For example, DAG nodes are dependency graph nodes, and shaders are networks of nodes.
Maya中的大多数对象都是依赖图节点或是由多个节点连接到一起构成的子网络。例如,DAG节点是依赖图节点,着色器是节点网络。
Certain events cause the dependency graph to re-evaluate itself, examples being screen refresh, and animation playback. During a refresh for example, the system will walk down the DAG and for each DAG node check to see whether it needs to be re-evaluated.
某些事件会触发依赖图重新对自己求值,例如屏幕刷新和动画回放。在屏幕刷新期间,Maya底层将遍历DAG层级结构,并检查每一个经过的DAG节点是否需要重新求值。
由上可知,Transform和Shape节点实际上就是DG节点的一种,我们可以猜测,“The GPU cache node routes cached data directly to the system graphics card for processing, bypassing Maya dependency graph evaluation. ”这句话指的是,在viewport显示geometry的时候,GPU cache构造的Shape node所持有的geometry数据会直接发送到系统的图形卡接口进行直接处理,避开DG的求值;而GPU cache构造的Transform node则依然会进入DG的求值机制,用户可以像使用Polygon一样,在Transform node上添加历史节点,比如Time node来key关键帧。
实际上,在GPU cache的开发文档中还提到了这样一句:
The gpuCache node is a Shape node that holds baked animated geometry in memory.The node can stream the animated geometry to the viewport without triggering any DG evaluation of geometry attributes (mesh, nurbs or subd surface data).
gpuCache 节点是一个在内存中持有几何体数据的Shape节点,当然这个几何体数据是烘焙后的、有动画的几何体数据。gpuCahe节点可以把几何体数据传递给viewport(就是hardware renderer或者viewport2.0),而不会触发任何几何体属性的DG求值行为。
这条说明就充分佐证了我们的猜测,这个解释无疑比文章最开始的答案要更深入。但我们依然还有一个疑惑,这种特性是如何实现的呢?为什么Alembic Cache导入abc文件可以编辑顶点,GPU Cache就不行?下面我们打破砂锅问到底,去GPU Cache的源码里寻找答案。
GPU cache的源码是公开的,你可以通过下载对应Maya版本的devkit来获取,附个链接:Maya2017 devkit下载地址。现在我们阅读GPU cache的源码来验证这个猜测是否为真。
首先,在doGpuCacheExportArgList.mel中有这样一段代码可以展示GPU cache创建DAG节点的过程:
string $xformNode = `createNode transform -name $nodeName`;
createNode gpuCache -name ($nodeName + "Shape") -parent $xformNode;
setAttr ".cacheFileName" -type "string" $fileFullPath;
其中第一行创建transform节点;第二行创建gpuCache节点,gpuCache节点就是shape节点,下面会讲到;第三行为gpuCache节点制定abc文件路径。这就印证了我们在DAG环节的推论,GPU cache导入abc数据时会分别创建一个transform节点,一个shape节点。而transform节点就是Maya内置的transform节点,所以当然可以提供位移、旋转、缩放等操作。
我们再看下一段代码,在gpuCacheShapeNode.cpp中有如下定义:
///////////////////////////////////////////////////////////////////////////////
//
// ShapeNode
//
// Keeps track of animated shapes held in a memory cache.
//
////////////////////////////////////////////////////////////////////////////////
class ShapeNode : public MPxSurfaceShape
const char* ShapeNode::nodeTypeName = "gpuCache";
这段代码这足以证明gpuCache是一个标准的Shape node。倒数第一行意为ShapeNode的类型名是“gpuCache”,倒数第二行意为ShapeNode继承自MPxSurfaceShape。这这里简单介绍一下MPxSurfaceShape,该类主要用于实现新的shape,并且有可选、可操作的组件,还有与Maya中默认shape相似的行为。也就是说,ShapeNode是可以提供与默认Shape相似功能的,比如,在viewport2.0中能显示并编辑点线面,能添加bevel一类的历史节点。
但显然gpuCache并没有显示顶点,在被选中时,显示的边缘也是dashed line,不是正常的实线。在这里我们应该去查看MPxSurfaceShapeUI类,MPxSurfaceShape和MPxSurfaceShapeUI是需要一并实现的,MPxSurfaceShape主要用于操作几何体数据,MPxSurfaceShapeUI则用于显示几何体。在gpuCache中这两个类分别由ShapeNode、ShapeUI实现。
在ShapeNode中没有实现setInternalValue()方法,而MPxSurfaceShape类中对顶点的编辑都是通过setInternalValue()来处理的,显然ShapeNode不具备编辑顶点的接口,自然gpuCache也就无法编辑顶点了;
在ShapeUI只有drawBoundingBox()、drawWireframe()、drawShaded()三个绘制函数,分别绘制boundingbox、模型线框及表面。在这个类里并没有找到绘制顶点的函数,这就是你在Viewport 2.0中无法看到gpuCache顶点的原因,无法看到顶点,自然也无法操作顶点。另外drawWireframe()函数中也指定了线框的绘制方式:kLineStippleShortDashed,强制Maya以虚线的方式绘制线框。
可以断定,gpuCache的源码中一定重写相关方法。继续阅读源码能够看到在gpuCacheSubSceneOverrride.h文件中有如下声明:
class SubSceneOverride : public MHWRender::MPxSubSceneOverride
MPxSubSceneOverride是Viewport 2.0的绘图基类,该类允许用户完整的定义渲染单元(MRenderItem),通过update()方法将计算后的geometry数据添加到MRenderItem,再通过绘图函数进行绘制。该类主要用于在使用Viewport 2.0时绘制sub-scene类型的DAG节点。SubSceneOverride子类在gpuCachePluginMain.cpp中通过MHWRender::MDrawRegistry::registerSubSceneOverrideCreator()方法注册到了Maya中,并与ShapeNode建立关系。这就意味着一旦创建了gpuCache的DAG Shape Node实例,就会有SubSceneOverride负责它在Viewport 2.0中的绘制工作。当然具体的点线面绘制工作由Viewport 2.0来执行,SubSceneOverride主要负责获取renderitem,并将处理过的renderitem推送至Viewport 2.0。
而几何体数据就是在MPxSubSceneOverride中发送到GPU memory中的。这个过程会涉及到更多的开发细节,以后有时间再做分享吧。
另外,为什么不能在gpuCache上添加诸如bevel之类的历史节点呢?答案很简单,因为gpuCache节点没有outmesh属性,bevel这类节点是无法连上去的。
以上,就是gpuCache不能编辑顶点的真相。
为毛GPU Cache不能移动顶点?的更多相关文章
- GPU
GPU主要是进行计算机图形这种大运算量的图形处理器,包括顶点设置.光影.像素操作.对CPU发出的数据和指令,进行着色,材质填充,渲染. 在没有GPU的系统中,3D游戏中物体移动时的坐标转换与光源处理, ...
- Point : GPU编程的艺术!一切的历史!
Point: 渲染渲染,神奇的渲染!! ———————————————— 只要你走的足够远,你肯定能到达某个地方. 1"GPU编程" History ————————— //由于笔 ...
- (转)GPU图形绘制管线
摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文名“GPU编程与CG语言之阳春白雪下里巴人”第二章. 图形绘制管线描述GPU渲染流程, ...
- 翻译:GLSL的顶点位移贴图
翻译:GLSL的顶点位移贴图 翻译自: Vertex Displacement Mapping using GLSL 译者: FreeBlues 说明: 之所以选择这篇文档, 是因为现在但凡提到位移贴 ...
- Multi-core compute cache coherency with a release consistency memory ordering model
A method includes storing, with a first programmable processor, shared variable data to cache lines ...
- GPU虚拟化技术详解
GPU虚拟化技术详解 GPU英文名称为Graphic Processing Unit,GPU中文全称为计算机图形处理器,1999年由NVIDIA公司提出. 一.GPU概述 GPU这一概念也是相对于计算 ...
- Instruments 使用指南
Instruments 用户指南 http://cdn.cocimg.com/bbs/attachment/Fid_6/6_24457_90eabb4ed5b3863.pdf 原著:Apple Inc ...
- UE4命令行使用,解释
命令行在外部 从命令行运行编辑项目 1 导航到您的[LauncherInstall][VersionNumber]\Engine\Binaries\Win64 目录中. 2 右键单击上 UE4Edit ...
- 【原创】Linux环境下的图形系统和AMD R600显卡编程(9)——R600显卡的3D引擎和图形流水线
1. R600 3D引擎 R600核心是AMD一款非常重要的GPU核心,这个核心引入了统一处理器架构,其寄存器和指令集同以前的GPU 都完全不同,对其编程也有比较大的区别. 图1显示了R600 GPU ...
随机推荐
- WPF popup自动关闭
var tileMore = new Tile { Height = , Width = , Background = , , )), Title = "更多...", }; ti ...
- github仓库主页介绍、用git管理本地仓库和github仓库、搭建网站
github仓库主页介绍 名词解释: 工作区: 添加.编辑.修改文件等动作 暂存区: 暂存已经修改的文件,最后统一提交到git中 git(仓库): 最终确定的文件保存到仓库,成为一个新的版本,并且对他 ...
- 2186 Popular Cows
Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 41771 Accepted: 16955 De ...
- echarts 折线图点击高亮
echarts中注册事件很多 ,记录下今天做的折线图点击高亮: 查了api,看了半天,发现折线图点击时只能做到圆点变大,并不能实现点击线条,整条线条高亮,也真是醉了. 上图: 如图所示,只能圆点变大. ...
- ppt图片在word中不能正常显示,只显示为矩形框的解决方法
word中插入的其他图片是好的,但是从ppt复制粘贴过来的图片只显示个框. 解决方法:以下红框中内容去选中.
- storm入门基础实例(无可靠性保证实例)
本实例为入门篇无可靠性保证实例,关于storm的介绍,以及一些术语名词等,可以参考Storm介绍(一).Storm介绍(二). 本案例是基于storm0.9.3版本 1.案例结构 案例:Word Co ...
- s21day23 python笔记
s21day23 python笔记 一.内容回顾及补充 字符串格式化 %s # 示例一:特别注意:最后的右括号前面必须有逗号(,) msg = '我是%s,年龄%s'%('alex',19,) # 元 ...
- go chan 入门代码
package main import ( "fmt" "sync" "time" ) // 生产数据 func producer(num ...
- JavaScript新手入门 贪吃蛇
从小就在玩贪吃蛇,但是知道今天自己做了一遍才知道原理的具体的实现步骤. 刚进入界面时显示开始游戏(不重要,本人比较喜欢吹毛求疵) 中间黑色部分为游戏的主要展示部分 主要步骤及源码: body中代码,红 ...
- 输入框VS软键盘
最近在做一个h5的时候遇到的问题 我们都知道当页面上的有输入框被选中了,这个时候就回调出键盘用户可以输入.但是安卓手机在弹出键盘时页面的输入框也会被覆盖住: 以下为暂时的解决办法:(以下方法同时解决了 ...