3

我很难找到一种方法来更好地处理我的游戏引擎中 3D 平铺对象之间的接缝。只有当相机像这样以足够远的角度向下倾斜时,您才能看到它们……我不认为这是纹理问题或纹理渲染问题(但我可能是错的)。

下面是两个屏幕截图 - 第一个演示了问题,而第二个是我在 Blender 中用于瓷砖的 UV 包裹。我在 UV 中为重叠提供了空间,这样如果纹理需要在较小的 mip-map 期间过度绘制,我应该仍然很好。我正在使用以下纹理参数加载纹理:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

在我看来,3D 瓷砖的侧面略微被绘制,并且您特别注意到由于从该角度应用的照明角度(定向)而产生的伪影。

我可以检查任何技巧或东西来消除这种影响吗?我在“图层”中渲染,但在这些图层中基于相机距离(最远的第一)。所有这些对象都在同一层中。任何想法将不胜感激!

如果有用,这是一个使用 OpenGLES2.0 的 iPhone/iPad 项目。我很乐意提供任何代码片段 - 让我知道可能是一个好的起点。

引擎的屏幕截图展示了低角度瓷砖之间的接缝

Blender 中的 UV

使用顶点/像素着色器和模型顶点进行更新

目前,我正在使用 PowerVR 的 POD 格式来存储从 Blender 导出的模型数据(通过 Collada,然后是 PowerVR 的 Collada2Pod 转换器)。这是 GL_SHORT 顶点坐标(模型空间):

64 -64 32
64 64 32
-64 64 32
-64 -64 32
64 -64 -32
-64 -64 -32
-64 64 -32
64 64 -32
64 -64 32
64 -64 -32
64 64 -32
64 64 32
64 64 32
64 64 -32
-64 64 -32
-64 64 32
-64 64 32
-64 64 -32
-64 -64 -32
-64 -64 32
64 -64 -32
64 -64 32
-64 -64 32
-64 -64 -32

所以一切都应该是完美的,我希望。这是着色器:

attribute highp vec3  inVertex; 
attribute highp vec3  inNormal;
attribute highp vec2  inTexCoord;

uniform highp mat4  ProjectionMatrix;
uniform highp mat4  ModelviewMatrix;
uniform highp mat3  ModelviewITMatrix;
uniform highp vec3  LightColor;
uniform highp vec3  LightPosition1;
uniform highp float LightStrength1;
uniform highp float LightStrength2;
uniform highp vec3  LightPosition2;
uniform highp float Shininess;

varying mediump vec2  TexCoord;
varying lowp    vec3  DiffuseLight;
varying lowp    vec3  SpecularLight;

void main()
{
    // transform normal to eye space
    highp vec3 normal = normalize(ModelviewITMatrix * inNormal);

    // transform vertex position to eye space
    highp vec3 ecPosition = vec3(ModelviewMatrix * vec4(inVertex, 1.0));

    // initalize light intensity varyings
    DiffuseLight = vec3(0.0);
    SpecularLight = vec3(0.0);

    // Run the directional light
    PointLight(true, normal, LightPosition1, ecPosition, LightStrength1);
    PointLight(true, normal, LightPosition2, ecPosition, LightStrength2);

    // Transform position
    gl_Position = ProjectionMatrix * ModelviewMatrix * vec4(inVertex, 1.0);

    // Pass through texcoords and filter
    TexCoord = inTexCoord;
}      
4

2 回答 2

2

我不知道你的盒子是怎么画的——但我相信这就是问题所在。在计算每个盒子的顶点时,我猜你会做这样的事情(伪代码)

整数 i,j,k;
浮动宽度

对于 i,j,k 以暗淡为单位:
  上左=(i,j,k)*宽度;
  upper_right = (upper_left.x+width,upper_left.y,upper_left.z);
  lower_left = (upper_left.x, upper_left.y+width,upper_left.z);
  lower_right = (upper_left.x+width,upper_left.y+width,upper_left.z);

这将失败,因为您在添加时会丢失精度,因此应该共享相同位置的角实际上不会。这就是造成差距的原因。

相反,你应该做这样的事情

对于 i,j,k:
  上左=(i,j,k)*宽度;
  upper_right = (i+1,j,k)*宽度;
  lower_left = (i,j+1,k)*宽度;
  lower_right = (i+1,j+1,k)*宽度;

这将确保角落将使用相同的坐标。

编辑

这仍然是一个精度问题。据我了解,您正在为每个块执行一次绘制调用,其中每个块唯一更改的是ModelviewMatrix. 这意味着您期望这条线

位置 = ProjectionMatrix * ModelviewMatrix * vec4(inVertex, 1.0);

会为 inVertex 和 ModelviewMatrix 的两个不同值给出相同的值,这是错误的。

为了解决这个问题,你可以做“假”实例化(因为 ES 不支持实例化),方法是将每个实例的值保存在制服中,并根据属性中给定的索引计算每个属性的值。

编辑2:

好的,请暂时不要考虑“假”实例。现在,请确保坐标相同。因此,不要只为一个块提供坐标,而是为所有块提供坐标,并且只使用一个 ModelViewMatrix。那可能也会更快。

于 2011-08-30T06:53:20.123 回答
1

试试这些

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
于 2011-08-31T15:06:41.473 回答