c++ - 一个矩形(两个相连的四边形)有两个纹理 - 它们的公共(public)边界有错误

标签 c++ mapping directx textures blending

我有一个由两个四边形组成的矩形(8 个顶点,我使用索引三角形):

------+------
| \   | \   |
|  \  |  \  |
|   \ |   \ |
______+______

我也有两个纹理。我将它们都绑定(bind)到着色器。

我想用第一个纹理对矩形(左四边形)的一部分进行纹理处理,而用第二个纹理对另一部分进行纹理处理。

但是当我根据顶点在像素着色器中的位置选择纹理时,我遇到了标记为“+”的顶点的问题。有一次我正在分析第一个四边形的“+”顶点,但具有相同位置的顶点也在第二个四边形中(并且必须在其上具有第二个纹理)。所以按位置设置纹理会出错。

如何确定分配哪个纹理(在采样器中)?我不想进行第二次传递或向着色器添加其他信息(如果有任何选项可以在没有它的情况下执行此操作)。

基本上来说:我有模型和优势。该边缘告诉纹理变化的位置。但是如何实现这个目标呢?当我在该边的顶点上设置 texture1 或 texture2 时,会出现一些错误。

最佳答案

我认为你的做法是错误的。着色器中的条件分支会降低着色器的速度,应尽可能避免。这样做的原因是着色器经过优化,可以为每个像素并行执行相同的代码。如果根据图形卡实现将条件放入着色器中,将发生以下情况之一:着色器将执行条件的两个分支并在执行后为每个像素选择适当的路径,或者让所有像素等待最长路径在继续之前,条件已完成执行。

在您的情况下,您正在尝试绘制一个具有两个纹理的图元。以这种方式定义时,这实际上是不可能的。换个概念很容易达到你想要的效果:

我可以想到两种可能的方法(可能还有更多):

  1. 第一个也是最简单的方法是绘制两个四边形,每个四边形都有自己的纹理。的确,您会调用着色器两次,但我几乎看不到任何真正的减速,因为无论如何都会绘制确切数量的像素。
  2. 第二种方法稍微复杂一些,但可以让您只绘制一次。您需要做的是创建一个大纹理,其中包含两个并排的纹理,并将整个纹理映射到整个三角形 strip 。这样渲染器将确保每个四边形都有其“自己的”纹理。对于 OpenGl,这是使用 glTexSubimage2D 完成的。在 direct3d 9 中它更复杂,您使用以下顺序:
    A.使用 CreateTexture 创建纹理
    B.使用 IDirect3DTexture9::GetSurfaceLevel() 获取级别 0 的表面
    C.使用 D3DXLoadSurfaceFromMemory() 将图像加载到表面
    D.释放表面

因此,您将水平纹理坐标从 0 到 0.5 映射到第一个四边形的顶点,并将从 0.5 到 1 的坐标映射到第二个四边形的顶点。如果四边形大小不同或纹理大小不同,您只需相应地更改映射

如果您坚持在着色器中使用条件分支,您应该记住您是在谈论一列像素,而不仅仅是两个顶点(毕竟这是一个像素着色器),因此您应该检查所有像素。这可能是一个问题,因为除非没有变换,否则您无法知道每个像素的变换结果。最好不要在像素着色器中查询顶点值。

希望这能让你走上正轨

关于c++ - 一个矩形(两个相连的四边形)有两个纹理 - 它们的公共(public)边界有错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13507296/

相关文章:

c# - 数组是否对可编程图形管道的顶点元素数据有效?

C++ 内联函数和上下文特定优化

javascript - 如何从对象数组创建合并对象,该对象保留原始对象中的属性,而新传入的对象未更改

python - SWIG 生成的 C++ 包装器会导致许多编译错误

functional-programming - Erlang 映射中的模式匹配键

java - Java 中使用 Map 的 JSON 解析器

c++ - 如何防止 DirectX C++ 程序的拉伸(stretch)/缩放

c++ - FBX SDK 骨骼动画

使用 ostream 的 C++ 日志记录

C++ 工厂模式