gpt4 book ai didi

iphone - OpenGLES 2.0 : 3D Tile Visual Artifacts

转载 作者:行者123 更新时间:2023-12-03 19:44:43 25 4
gpt4 key购买 nike

我正在努力寻找一种方法来更好地处理游戏引擎中 3D 图 block 对象之间的接缝。只有当相机以足够远的角度向下倾斜时才能看到它们......我不相信这是纹理问题或纹理渲染问题(但我可能是错的)。

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

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 图 block 的侧面略有绘制,并且您会特别注意到由于从该角度应用的照明角度(方向)而产生的伪影。

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

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

Screenshot from engine demonstrating seams between tiles at low angles

UVs from Blender

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

目前,我使用 PowerVR 的 POD 格式来存储从 Blender 导出的模型数据(通过 PowerVR 的 Collada 和 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;
}

最佳答案

我不知道你的盒子是如何绘制的 - 但我相信这就是问题所在。当计算每个盒子的顶点时,我猜你会做这样的事情(伪代码)

int i,j,k;float widhtfor i,j,k in dims:   upper_left = (i,j,k)*width;  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);

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

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

for i,j,k:   upper_left = (i,j,k)*width;  upper_right = (i+1,j,k)*width;  lower_left = (i,j+1,k)*width;  lower_right = (i+1,j+1,k)*width;

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

编辑

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

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

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

要解决这个问题,您可以通过将每个实例的值保存在制服中并根据属性中给定的索引计算每个属性的值来进行“假”实例化(因为 ES 不支持实例化)。

编辑2:

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

关于iphone - OpenGLES 2.0 : 3D Tile Visual Artifacts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7236980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com