我在OpenGL中遇到了3D纹理问题.
我通过设置纹理
glTexImage3D(GL_TEXTURE_3D, 0, GL_LUMINANCE, 640, 480, 8, 0, GL_RED, GL_UNSIGNED_BYTE, tex3Ddata);
Run Code Online (Sandbox Code Playgroud)
tex3Ddata共有8片640x480位图.现在当我尝试使用纹理坐标访问不同的切片时,由于某种原因图像会相互融合,因此我没有正确设置坐标,但我不知道为什么.纹理切片本身是8位单色.
显示代码:
for(unsigned int i = 0; i < g_numCameras; i++) {
float tx = ((float)i) / ((float)g_numCameras - 1);
//tx = 0.5f; //this is for testing only
float fI = ((float)i) / ((float)g_numCameras);
if( i < (g_numCameras >> 1)) {
glTexCoord3f(0.0f, 1.0f, tx);
glVertex3f( -1.0f + fI * 4.0f, 0.0f, 0.5f);
glTexCoord3f(1.0f, 1.0f, tx);
glVertex3f( -1.0f + (fI + 1.0f / ((float)g_numCameras)) * 4.0f, 0.0f, 0.5f);
glTexCoord3f(1.0f, …Run Code Online (Sandbox Code Playgroud) 我的问题是关于texturecoordinate如何精确地映射到纹理中的纹素(不考虑过滤).
(0,0)例如是参考左上角像素的左上角还是参考左上角像素的中心?
如果使用近滤波,在纹理坐标(0.5,0.5)处获取什么像素?
怎么样(1.0,1.0),它是指右下角像素的右下角还是右下角像素的左上角?(我记得几年前,一些ATI和NVIDIA卡之间存在差异.它现在是标准化的吗?)
如果使用texelFetch()而不是textureLod(),访问像素的正确方法是什么?
是吗
ivec2 size = textureSize(sampler,0);
ivec2 iCoords = ivec2(int(uv.x*size.x),int(uv.y*size.y));
vec4 col = texelFetch(sampler,iCoords);
Run Code Online (Sandbox Code Playgroud)
或者可能
ivec2 iCoords = ivec2(int(uv.x*size.x+0.5f),int(uv.y*size.y+0.5f));
Run Code Online (Sandbox Code Playgroud)
正确?
甚至
ivec2 iCoords = ivec2(int(uv.x*(size.x+1)),int(uv.y*(size.y+1)));
Run Code Online (Sandbox Code Playgroud)
?
也许有人可以澄清映射究竟是如何工作的?
我在我的球体上有错误的纹理贴图.这个问题众所周知,但解决方案很少见.
这是我为球体生成UV的代码.
T =三角形,Nv =顶点法线.
for (int i=0; i<nbF; i++)
{
float tx1 = atan2(Nv[T[i].v1].x, Nv[T[i].v1].z) / (2.0f*M_PI) + 0.5f;
float ty1 = asinf(Nv[T[i].v1].y) / M_PI + 0.5f;
float tx2 = atan2(Nv[T[i].v2].x, Nv[T[i].v2].z) / (2.0f*M_PI) + 0.5f;
float ty2 = asinf(Nv[T[i].v2].y) / M_PI + 0.5f;
float tx3 = atan2(Nv[T[i].v3].x, Nv[T[i].v3].z) / (2.0f*M_PI) + 0.5f;
float ty3 = asinf(Nv[T[i].v3].y) / M_PI + 0.5f;
float n = 0.75f;
if(tx2 < n && tx1 > n)
tx2 += 1.0;
else if(tx2 > n …Run Code Online (Sandbox Code Playgroud) 我使用D3DXCreateSphere方法来创建球体网格.我想在它上面应用地球纹理.我使用以下代码计算像素着色器中的纹理坐标:
sampler ShadeSampler = sampler_state
{
Texture = (ShadeTex);
AddressU = Mirror;
AddressV = Mirror;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
};
PS_OUTPUT PSMain(VS_OUTPUT input){
PS_OUTPUT output = (PS_OUTPUT)0;
vector uv;
uv.x = 0.5 + atan2(input.normal.z, input.normal.x) / piMul2;
uv.y = 0.5f - asin(input.normal.y) / pi;
vector b = tex2D(ShadeSampler, uv.xy);
output.diffuse = b * input.diffuse;
return output;
}
Run Code Online (Sandbox Code Playgroud)
我使用D3DXCreateTextureFromFileEx方法来创建IDirect3DTexture9,但是当我通过使用参数的D3DX_DEFAULT值启用mipmap功能时MipLevels,渲染结果有点错误,在接缝处总是有一个像素线.下图显示了问题,但是当我通过使用参数D3DX_FROM_FILE值禁用mipmap功能时MipLevels,该行消失.我不知道为什么会这样,有什么建议吗?

假设您有一个简单的Tileset用于游戏,如下所示:

现在,当处理简单的GUI框架(如.NET)时,加载该图像,选择其一部分然后逐块绘制将非常容易。但是,当使用OpenGL时,此过程似乎更多……唯一,独特。我可以轻松地将该图像加载到OpenGL中并将其绑定到某些几何形状,但是,当涉及到“选择”某些图块(不取消绑定所述纹理)时,它似乎需要的数学运算与传统的x,y,width不同,高度方法。
如果要为当前图块选择64,128(像素空间中的坐标)的图块,我将使用反映该理想的纹理坐标,而不是我在其他网站上看到的那些奇怪的分数。
似乎在绑定纹理时OpenGL根本不使用像素空间,或者我可能在这里误解了一些基本概念。我不确定。
这是在某些任意位置渲染32 x 32瓦片的简单方法(在此示例中,将保持为0,0):
int spriteX = 0;
int spriteY = 0;
int spriteWidth = 32;
int spriteHeight = 32;
GL.BindTexture( TextureTarget.Texture2D , texture );
GL.Begin( PrimitiveType.Quads );
{
GL.TexCoord2( 0 , 1 );
GL.Vertex2( spriteX , spriteY );
GL.TexCoord2( 1 , 1 );
GL.Vertex2( spriteX + spriteWidth , spriteY );
GL.TexCoord2( 1 , 0 );
GL.Vertex2( spriteX + spriteWidth , spriteY + spriteHeight );
GL.TexCoord2( 0 , 0 );
GL.Vertex2( spriteX , spriteY + spriteHeight ); …Run Code Online (Sandbox Code Playgroud) 我现在的情况是想使用VAO/VBO来回收相同的顶点并使用索引来加速渲染。
一切都很好,除了我的纹理模型使用 UV 坐标,并且对于相同的顶点(大约 >80%),我最终可能会根据我期望渲染的三角形获得不同的 UV 坐标(事实上,我正在使用md2 模型和纹理)。
对于老式的即时模式来说,这种渲染方式非常不错。现在,解决这个问题并通过 VAO/VBO 渲染的最佳方法是什么?
我想到的是分解三角形并创建具有重复顶点的非常大的 VBO,以便我可以将正确的 UV 坐标链接到每个“相同”。
我不得不说我不喜欢这个...有什么想法吗?
诗。对于不了解格式的人:如果您想使用纹理映射,我相信您必须使用基于要渲染的三角形的自定义 UV 坐标。否则纹理颜色都乱了!
我有一个高分辨率的房间多边形网格,我想提取顶点颜色信息并将它们映射为 UV 贴图,这样我就可以生成房间的纹理图集。
之后,我想重新划分模型的网格,以减少多边形的数量,并将高分辨率纹理以较低的分辨率映射到新的网格上。
到目前为止,我已经找到了在 Blender 中执行此操作的链接,但我想以编程方式执行此操作。您知道有什么库/代码可以帮助我完成任务吗?
我想首先我必须对模型进行分段(法线标准可能会有所帮助),然后切割每个网格段,这样我才能对其进行参数化。关于参数化,LSCM似乎为简单模型提供了良好的结果。一旦获得了纹理图集,我认为问题就变成了纹理映射的简单任务。
我的主要问题是分割和网格切割。我正在使用CGAL 库来实现此目的,但该算法太简单,无法切割复杂的形状。关于对房间大小的模型表现良好的更好的分割/切割算法有什么提示吗?
编辑:
该网格由 RGB-D 相机重建的房间组成,有 250 万个顶点和 470 万个面。重点是提取高分辨率纹理,重新网格化模型以减少多边形数量,然后将纹理重新映射到其上。它不是一个封闭的网格,并且由于重建而存在漏洞,所以我猜测我的任务是否根本无法完成。
我附上网格的捕获。
我正在创建一个带有圆角的平面几何形状。这是我的代码的一部分。
var geometry = new THREE.ShapeGeometry(shape);
var front_material = new THREE.MeshPhongMaterial({ map: frontTexture, side: THREE.FrontSide });
var back_material = new THREE.MeshPhongMaterial({ map: backTexture, side: THREE.BackSide });
var materials = [front_material, back_material];
mesh = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
Run Code Online (Sandbox Code Playgroud)
此代码仅加载正面并在背面呈现不可见。经过几个小时的谷歌搜索后,我找不到如何在当前 Three.js 版本 r78 上添加materialIndex。
我怀疑我只需要在这个问题上添加材料索引。
我有这个网格,基本上是从地图集中采样其纹理。当纹理被放大时,它会按预期工作。

然而,每当我从远处看它时,我开始看到纹理上的线条和蓝色色调,就好像它们在闪闪发光......

这是用于指定图像属性的代码:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
Run Code Online (Sandbox Code Playgroud)
count 5
name grass_top
uv 0.750 0.750 0.81250 0.81250
name grass_side
uv 0.18750 0 0.250 0.06250
name grass_bottom
uv 0.1250 0 0.18750 0.06250
name dirt
uv 0.1250 0 0.18750 0.06250
name stone
uv 0.0625 0 0.125 0.0625A
Run Code Online (Sandbox Code Playgroud)
这里可能有什么问题,我完全被难住了......