【问题标题】:Texture painting on a 3D model在 3D 模型上绘制纹理
【发布时间】:2016-05-10 23:35:24
【问题描述】:

我知道这里已经有几个类似的问题,但答案对我想要实现的目标并没有真正的帮助。正如标题所示,我希望在 OpenGL 中将纹理投影到 3D 模型(准确地说是其 UV 映射纹理)上。这个视频中展示了最好的例子 - https://www.youtube.com/watch?v=pT4bx4J4NQQ

在 cmets 中,作者提到他“将画笔所在的枪的每个像素投影回 UV 空间并更新原始纹理”。我假设他是通过渲染一个额外的 UV 通道来做到这一点的,该通道允许他用画笔纹理中的像素替换可见像素。像往常一样,说起来容易做起来难:主要问题是当我们缩小模型并开始投影时,并非所有模型的 UV 都会在屏幕空间中看到,因此重新放大应该会显示“洞”(模型的UV 太小,无法在屏幕空间中渲染)。

所以我的问题是 - 从远处绘画时如何避免这些孔?投影映射不是这里的答案,因为它会影响画笔结束的所有面,甚至是可见表面后面的面。超级采样也无法处理极端情况,而且会非常缓慢。

我也怀疑他是否会检查模型的所有纹理像素以确定它们是否位于画笔下方,因为增加其大小或创建画笔会显着减慢速度。

【问题讨论】:

  • 你有没有在这方面取得任何进展?我一开始就卡住了。

标签: opengl textures paint projection brush


【解决方案1】:

视频中显示的程序的实现者所做的可能是在一个额外的离屏通道中绘制模型,并在一个离屏通道中使用纹理 ST 坐标。现在几年前有一种方法可以通过使用特殊的渲染模式(选择模式)来“挑选”对象——不要使用它,它超级慢而且效率低下。但是选择模式选择的基本步骤之一是,在投影和模型视图矩阵的顶部乘以一个特殊的“选择”矩阵,这会将转换体积“缩放”到选择矩形下方的内容。如果您将该附加转换与 ST 坐标渲染传递组合到足够高分辨率的缓冲区(称为纹理几何缓冲区)中。

现在是棘手的部分:请记住,纹理实际上是从 ST 空间到 proj(modelview(XYZW)) 的映射(因此称为纹理映射)。您实际上想要的是逆映射。如果您不关心局部曲率,您可以通过简单地交换传递到“映射”机器的坐标来做到这一点。因此,如果您将 proj(modelview(XYZW)) 放入 ST 将去的地方,反之亦然,它会给您一个逆映射。使用贴花作为纹理和纹理几何缓冲区执行此操作,您已反转纹理映射并将贴花绘制到模型的纹理空间中。因此,将您的模型纹理设置为 FBO 的颜色附件,您可以在其中进行反向绘制,并使用贴花作为纹理进行绘制,然后就可以了。

所以我的问题是 - 从远处绘画时如何避免这些孔?

通过对其进行插值。如果您的中间缓冲区具有足够高的分辨率,这将免费发生。请注意,我不是您链接的视频中显示的程序的作者。但是我曾经确实写过这样一个程序,虽然我放错了它的来源。做起来并不难,你通常可以在每个主要的 3D 建模包中找到这样的功能。如果周围有适当的工具,那么使用粗略的技术演示几乎没有用处。

【讨论】: