问题标签 [geometry-instancing]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
5025 浏览

opengl - OpenGL——一次渲染多个网格,带有单独的变换

我正在寻找一种同时渲染多个网格的方法,这样我就不必为每个网格发出绘制调用。我在这里处理的是 2D 渲染,一个典型的对象,比如一个正方形,里面可能只有两个三角形。但是,一个对象也可能非常复杂,并且有数千个三角形。

现在每个对象都可以自行移动。从概念上讲,为每个“对象”设置一个 VBO(或 VBO/IBO 对)是完全合理的:只要对象不变,我每帧都需要上传到 GPU 的只是变换信息:一个位置向量和一个方向值。或者,等效地,一个变换矩阵。

但是这种方法的问题在于,对于 1000 个方形对象的场景,我需要初始化 1000 个 VBO 和 1000 个 IBO,并且 1000 个绘制调用每帧设置 1000 套制服以渲染 2000 个三角形。

好的。如果所有这些对象都相同,我可以有一个 VBO/IBO 来描述它们,设置一个统一缓冲区对象(或者统一数组更合适——我仍然需要学习如何使用这些)和转换数据它们中的每一个,并发出一个实例化绘制调用,让顶点着色器通过使用它接收到的实例编号从 UBO 中提取转换数据。伟大的。

我只想更进一步。我想做相当于在不相同的网格上实例化的事情:我有 1000 个不同的对象,我很乐意在 1000 个单独的顶点/索引缓冲区对或一对巨大的顶点/索引缓冲区中描述它们。我想一次性将他们的转换数据发送到 GPU。只需让驱动程序/GPU 绑定或选择正确的顶点即可。

这可以做到吗?可以在不使用 SM4 几何着色器的情况下完成吗?

更新:我只是想到了一种潜在的方法来实现这一点。我使用顶点属性作为我的“实例化”值,用它来索引包含转换的 UBO。这是这样做的方法吗?

0 投票
1 回答
2425 浏览

directx-11 - 如何在 DirectX11 的几何着色器中实例化?

我知道在顶点着色器中你这样做:

在几何着色器中使用 instancedPosition 的等价物是什么?就像我想实例化一个由 1 个顶点组成的模型并为每个实例在几何着色器中制作一个四边形并将四边形的位置设置为对应的 instancePosition 的位置实例缓冲区中的实例。

0 投票
2 回答
1795 浏览

directx-9 - DirectX9 对具有多种材质的网格使用几何实例化

我正在尝试拥有一个灵活的几何实例化代码,能够处理具有多种材料的网格。对于具有一种材料的网格,一切都很好。我设法通过一次绘制调用渲染尽可能多的实例。

使用多种材料会使事情变得更加复杂。我的网格来自一个 .x 文件。它有一个顶点缓冲区、一个索引缓冲区和几种材质。为每个子集(材质)渲染的索引存储在属性数组中。

这是我使用的代码:

此代码仅适用于第一种材料。当我说第一个时,我的意思是索引为 0 的那个,因为如果我用第二种材料开始循环,它将不会被渲染。但是,通过调试 PIX 中的顶点缓冲区,我可以看到我的所有材质都被正确处理。所以在顶点着色器之后会发生一些事情。

另一个奇怪的问题,如果我将包含实例数据的流源设置为顶点大小为零,我的所有材质都将被渲染。

所以代替这个:

我将其替换为:

但是,当然,使用这段代码,我的所有实例都呈现在同一个位置,因为我一遍又一遍地重用相同的实例数据。

最后一点,如果我使用 D3DCREATE_SOFTWARE_VERTEXPROCESSING 创建设备,一切正常。只有硬件有问题,但不幸的是 DirectX 在调试模式下没有报告任何问题。

0 投票
2 回答
2768 浏览

c++ - 在 DirectX 10 中渲染精灵的最有效方法是什么?

我目前正在尝试在 DirectX 10 中显示 2D 精灵的各种方法。我首先使用该ID3DX10Sprite界面在一次调用中批量绘制我的精灵。然而,最终,我想要更多地控制我的精灵是如何渲染的,所以我决定研究基于四边形的精灵渲染(即每个精灵都由一个应用了纹理的四边形表示)。

我一开始很简单:我创建了一个由 4 个顶点组成的单个顶点缓冲区,在绘制精灵之前应用了一次。然后我循环遍历我的精灵,设置适当的属性以传递给着色器,并为每个精灵进行绘制调用,如下所示d3dDevice->Draw( 4, 0);:虽然它有效,但每个精灵的绘制调用都困扰着我,所以我寻找了一种更有效的方法。

在搜索之后,我了解了对象实例化,并决定尝试一下。一切都很顺利,直到我尝试实现精灵最重要的部分——纹理。简而言之,虽然我有一个纹理数组(在我的着色器顶部声明Texture2D textures[10];),可以使用文字/常量作为索引在我的像素着色器中成功采样,但我无法弄清楚如何控制哪些纹理应用于哪个通过纹理索引的实例。

我的想法是为每个实例传递一个纹理索引,然后可以使用该索引对像素着色器中数组中的适当纹理进行采样。但是,在进行了更多搜索之后,我找不到如何完成它的示例(并且发现很多事情表明如果不迁移到 DirectX 11 就无法完成)。

这是否是说在 DirectX 10 中通过对象实例化成功渲染精灵的唯一方法是基于纹理批量渲染它们?因此,例如,如果我的场景由 100 个具有 20 个不同纹理的精灵组成(每个纹理由 5 个精灵引用),那么将需要 20 次单独的绘制调用来显示场景,而我一次只发送 5 个精灵。

最后,我比较茫然。我做了很多搜索,似乎得到了相互矛盾的信息。例如,在这篇文章的第 6 段中,它指出:

使用 DirectX 10,可以将数组中的不同纹理应用于同一对象的不同实例,从而使它们看起来不同

此外,在白皮书的第 3 页,它提到了以下选项:

从纹理数组中读取每个实例的自定义纹理

但是,我似乎找不到一个具体的例子来说明如何设置着色器以使用每个实例的纹理索引来访问纹理数组。

最后,中心问题是:使用 DirectX 10 渲染精灵最有效的方法是什么?

如果答案是实例化,那么是否可以控制将哪个纹理应用于着色器中的每个特定实例 - 从而只需一个绘图调用就可以发送更大批量的精灵及其适当的纹理索引?还是我必须满足于一次只实例化具有相同纹理的精灵?

如果答案是返回到使用提供的 DX10 Sprite 界面,那么我有没有办法更好地控制它的渲染方式?

作为旁注,我还研究了使用几何着色器来创建实际的四边形,所以我只需要传递一系列点而不是管理顶点和实例缓冲区。尽管如此,除非有一种方法可以控制将哪些纹理应用于生成的四边形,否则我将回到仅通过纹理对精灵进行批处理。

0 投票
1 回答
513 浏览

c# - XNA 硬件实例化:网格未完全渲染

我按照这个简短的教程在 XNA 代码中实现了基本的硬件模型实例化方法:http: //www.float4x4.net/index.php/2011/07/hardware-instancing-for-pc-in-xna-4-with -纹理/

我已经创建了所需的着色器(虽然没有纹理图集,只有单个纹理),并且我正在尝试使用这种方法来绘制我使用 3DS Max 2013 生成并通过 FBX 格式导出的简单树。

我看到的结果让我不知道发生了什么。

出于某种原因,没有树干的树。

当我没有使用实例化方法,而只是在网格上调用 Draw 时(对于一个级别上的每棵树),整个树都显示出来了:

正确渲染,但没有实例化(每级数百个对象可能非常慢

我已经确定 Model只包含一个 Mesh 并且 Mesh 只包含一个 MeshPart

我正在使用顶点提取方法,通过使用模型的顶点和索引缓冲区“GetData<>()”方法,以及正确数量的顶点和索引,因此渲染了正确数量的图元。正确的纹理坐标和光照法线也被提取出来,正如正在渲染的树的一部分可见。

树的各个部分也位于正确的位置。

他们只是毫无理由地丢失了大约 1000 个左右的多边形。我在顶点提取和着色器参数生成的每一步都设置了断点,我终其一生都无法弄清楚我做错了什么。

我的 Shader 的顶点变换函数:

顶点绑定和索引缓冲区生成:

用于获取所有顶点信息的顶点提取方法(这部分我确信可以正常工作,因为我之前使用它来将测试几何形状加载到关卡中,如盒子、球体等,以测试各种着色器,并使用它们构建边界框提取的顶点数据,都是正确的):

这是对象批处理的渲染代码(在这种特殊情况下为树):

如果有人知道从哪里开始寻找错误,只需发布​​所有想到的想法,因为我完全不知道发生了什么。

这甚至抵消了我之前的所有经验,我在着色器代码或顶点生成中搞砸了一些东西,你会在屏幕上得到一些绝对的混乱 - 大量的图形伪影,例如源自网格应该在哪里的细长三角形,但一个提示向后伸展到(0,0,0),黑色纹理,不正确的定位(通常在天空盒之外或地形下方),不正确的缩放......

这是不同的东西,几乎就像它工作一样 - 树的可见部分在每个方面(位置,旋转,比例,纹理,阴影)都是正确的,除了缺少一部分。对我来说更奇怪的是,丢失的部分似乎在逻辑上被分割:只有树干的图元和树的最低分支的一些叶子丢失,所有其他图元正确渲染而没有伪影。基本上,他们......正确地失踪了

0 投票
1 回答
93 浏览

xna - XNA Hardware Instancing - faces drawn in wrong order around icosphere

I'm trying to implement the InstancedModelSample code into my game, and it's worked perfectly except for one problem - The edges on my icospheres are being drawn between the wrong vertices and it's just drawing a garbled mess.

When I used to draw the 300 or so models with individual Draw() calls, it renders fine, but not with this new code. I'm new to this stuff - how do I get the method to fill in the right gaps with faces when this seems to be a generic method useable with anything?

My code below is only slightly adjusted from the original sample, with parts that I can see aren't necessary to me (like bone transforms) excluded.



Thanks in advance to anyone who can help me out :)

0 投票
1 回答
819 浏览

opengl - 绘制选定的 VAO 实例 (glDrawArraysInstanced)

我正在使用 glDrawArraysInstanced 在不同位置绘制树的多个实例以生成森林。

有没有办法绘制选定的实例?例如:我得到了 100 棵不同属性的树。由于剔除,我只想绘制实例 3、65、89 和 95。

能够绘制单个实例就足够了。

0 投票
0 回答
231 浏览

ios - 如何在不使用 CAReplicatorLayer 的情况下绘制 UIView 的多个实例?

我有一个 UIView,我想制作它的多个副本,我可以将它们定位在屏幕的不同点上。我还希望能够对每个副本应用不同的掩码/变换,以便每个副本都可能显示原始的不同部分。

例如,假设我有一个视图 ,A并且我制作了它的两个副本B, 和C。然后我想应用一个蒙版B,使它只显示上半部分A,我想应用一个不同的蒙版C,使它只显示下半部分A

我该怎么做呢?

CAReplicatorLayer 并不能真正用于我在我的应用程序中尝试做的事情,因为副本需要位于视图层次结构的不同部分。此外,我不能使用任何利用快照的方法,因为原始视图可能包含动画内容或视频。我真正想要的是某种可以反映另一个视图内容的视图,这样我就有两个看起来完全相同的视图。

0 投票
1 回答
804 浏览

opengl - OpenGL 中基于实例的 VR 渲染

我正在尝试使用实例化在 OpenGL 中使用 1 个绘制调用、2 个实例(一个用于左眼,一个用于右眼)进行 VR 渲染。然后,顶点着色器将左侧的顶点转换为 instanceID 0,右侧的顶点转换为 instanceID 1。我唯一需要更多的是用于自动硬件剔除/裁剪的每个实例视口。这在 directX 中是可行的,但在 OpenGL 中是可行的吗?

0 投票
1 回答
323 浏览

c++ - Opengl - 实例化属性

我使用 oglplus - 它是 OpenGL 的 c++ 包装器。

我在为我的粒子渲染器定义实例数据时遇到问题 - 位置工作正常,但是当我想从同一个 VBO 实例化一堆整数时出现问题。

我将跳过一些实现细节,以免使这个问题变得更复杂。假设我在描述操作之前绑定了 VAO 和 VBO。

我有一个结构数组(称为“粒子”),我像这样上传:

结构的定义:

我使用辅助函数来定义 OpenGL 属性,如下所示:

我为位置和流体添加属性,如下所示:

顶点着色器代码:

整个代码会产生以下输出:

opengl问题

如您所见,粒子按照我想要的方式排列,这意味着“InstanceTranslation”属性设置正确。左侧的粒子组的 FluidID 值为 0,右侧的粒子组等于 1。第二组粒子具有正确的位置,但在 FluidColors 数组中的索引不正确。

我知道的:

  • 我设置 FluidColors 制服的方式没有问题。如果我像这样在着色器中硬编码颜色选择:

    sphereColor = FluidID == 0?FluidColors[0] : FluidColors 1 ;

我得到:

在此处输入图像描述

  • OpenGL 从 glGetError 返回 GL_NO_ERROR 所以我提供的枚举/值没有问题
  • offsetof 宏没有问题。我尝试使用硬编码值,但它们也不起作用。
  • 这不是 GLint 的兼容性问题,我使用简单的 32 位整数(使用 sizeof(int) 检查此问题)
  • 我需要使用 FluidID 作为索引颜色数组的实例属性,否则,如果我要将粒子组的颜色设置为简单的 vec3 制服,我必须批处理相同的粒子类型(具有相同的 FluidID ) 首先,这意味着对它们进行排序,并且操作成本太高。