使用 XNA 创建游戏/2D 开发/纹理
纹理有许多格式,一些众所周知,如 bmp、gif、jpg 或 png,一些鲜为人知,如 dds、dib 或 hdr 格式。你需要了解 UV 坐标以及它们是如何映射的。此外,还应该讨论纹理贴图、透明纹理以及在着色器中访问和使用纹理等主题。
在 3D 建模的背景下,纹理贴图是一个应用于模型表面的位图。结合着色器,可以显示几乎任何材料的几乎所有可能的表面和属性。纹理化过程类似于将图案纸应用于盒子。多纹理化是在一个模型上同时使用多个纹理。
每个顶点都有一个 xyz 位置,此外还有一个 uvw 空间中的纹理坐标(也称为 uvw 坐标)。
uvw 坐标用于如何将纹理投影到多边形上。对于像计算机游戏中通常使用的二维位图纹理,只需要 u 和 v 坐标。
对于数学纹理(例如 3D 噪声),通常需要 uwv 坐标。
- uv 坐标 (0,0) 是位图的左下角
- uv 坐标 (1,1) 是位图的右上角
- 如果 uv 坐标 <0 或 >1:纹理的贴图
一个顶点可以有多个纹理坐标:因此,使用多个映射通道来显示重叠的纹理,以表示更复杂的结构。
贴图是指纹理的重复和排列,以及纹理彼此相邻的重复,没有重叠。如果 uv 坐标 <0,则纹理将缩小并重复。如果 uv 坐标 >1,则纹理将放大。
在游戏中,通常整个 3D 模型只有一个纹理,因此每个顶点只有一个纹理坐标,因此只有一个映射通道。
Photoshop 在这种情况下通常用于创建和编辑 3D 模型的纹理。经常使用照片来传达逼真的印象。例如:蜥蜴的皮肤 -> 龙的纹理。
颜色混合将两种颜色混合在一起,产生第三种颜色。
第一种颜色称为源颜色,它是正在添加的新颜色。第二种颜色称为目标颜色,它是在渲染目标中已经存在的颜色。每种颜色都有一个单独的混合因子,它决定了每种颜色被组合到最终产品中的比例。一旦源颜色和目标颜色乘以它们的混合因子,结果将根据指定的混合函数进行组合。通常的混合函数是简单的加法。(...) http://msdn.microsoft.com
看看这里: 教程
- 透明物体需要根据它们在视图空间或裁剪空间中的 z 值进行排序
- 将 z 缓冲区写入关闭,但将 z 缓冲区读取打开
- 在绘制预先排序的透明物体时,选择顺序:BackToFront
大多数纹理必须是可贴图的。因此,如果图像重复,则不应该看到边缘。
一个很棒、非常有用的助手是 Photshop 滤镜->其他滤镜->位移效果。
它对于创建无边缘模式非常有用。
1) 将图像边框放到中间。使用滤镜•其他滤镜•位移效果。值应为边框的一半长度。不要忘记选项“用偏移部分替换”!!现在你必须修补生成的边缘。
修补的典型工具
复制和粘贴某些位图部分以及使用蒙版
图章和画笔
2) 你必须再次这样做,因为图像的侧面有边缘。标记侧面的中点,然后再次使用滤镜“位移效果”。将图像移动边框长度的三分之一或四分之一。
现在标记和边缘位于图像的中心。在这里,你必须进行最后的修补。
然后它看起来像这样
高度信息/凹凸贴图
从图像中获取高度信息有点复杂,并不是所有照片都适合获取其高度信息并获得凹凸贴图。您可以在此处找到一个关于如何执行此操作的教程:在 2) 从图像中获取浮雕信息 Galileodesign
您可以在此处找到以下关于如何执行此操作的不错的教程: http://www.riemers.net/ Tutorials
texture = Content.Load<Texture2D> ("riemerstexture");
此行将我们刚刚在项目中加载的资产绑定到纹理变量!
现在我们必须定义 3 个顶点并将它们存储在数组中。我们需要能够存储 3D 位置和纹理坐标。顶点格式为 VertexPositionTexture。我们必须在顶部声明此变量。
VertexPositionTexture[] vertices;
现在我们在我们创建的 SetUpVertices 方法中定义三角形的 3 个顶点
private void SetUpVertices()
{
vertices = new VertexPositionTexture[3];
vertices[0].Position = new Vector3(-10f, 10f, 0f);
vertices[0].TextureCoordinate.X = 0;
vertices[0].TextureCoordinate.Y = 0;
vertices[1].Position = new Vector3(10f, -10f, 0f);
vertices[1].TextureCoordinate.X = 1;
vertices[1].TextureCoordinate.Y = 1;
vertices[2].Position = new Vector3(-10f, -10f, 0f);
vertices[2].TextureCoordinate.X = 0;
vertices[2].TextureCoordinate.Y = 1;
texturedVertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements);
}
对于每个顶点,我们都以顺时针方式定义它在 3D 空间中的位置。
接下来,我们定义纹理中的哪个 UV 坐标对应于顶点。请记住:(0,0) 纹理坐标位于纹理图像的左上角,(1,0) 位于右上角,(1,1) 位于右下角。
不要忘记从你的 LoadContent 方法调用 SetUpVertices 方法
SetUpVertices ();
现在我们的顶点已设置好,我们的纹理图像已加载,现在我们绘制三角形
在 Draw 方法中,在调用 Clear 方法之后添加此代码
Matrix worldMatrix = Matrix.Identity;
effect.CurrentTechnique = effect.Techniques["TexturedNoShading
"];
effect.Parameters["xWorld"].SetValue(worldMatrix);
effect.Parameters["xView"].SetValue(viewMatrix);
effect.Parameters["xProjection"].SetValue(projectionMatrix);
effect.Parameters["xTexture"].SetValue(texture);
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.VertexDeclaration = texturedVertexDeclaration;
device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, 1);
pass.End();
}
effect.End();
我们需要指示我们的显卡从纹理图像中采样每个像素的颜色。这正是我的效果文件中的 TexturedNoShading 技术所做的,因此我们将其设置为活动技术。由于我们没有为我们的向量指定任何法线,因此我们无法期望效果进行任何有意义的阴影计算。
如系列 1 中所述,我们需要将世界矩阵设置为单位矩阵,以便三角形在定义的位置进行渲染,并将视图矩阵和投影矩阵设置为显卡可以将 3D 位置映射到 2D 屏幕坐标。
最后,我们将纹理传递给技术。然后我们实际上从顶点数组中绘制三角形,如第一系列中所做的那样。
运行此操作应该已经为您提供了一个纹理三角形,显示了纹理图像的一半!要显示整个图像,我们只需要通过添加第二个三角形来扩展我们的 SetUpVertices 方法
private void SetUpVertices()
{
vertices = new VertexPositionTexture[6];
vertices[0].Position = new Vector3(-10f, 10f, 0f);
vertices[0].TextureCoordinate.X = 0;
vertices[0].TextureCoordinate.Y = 0;
vertices[1].Position = new Vector3(10f, -10f, 0f);
vertices[1].TextureCoordinate.X = 1;
vertices[1].TextureCoordinate.Y = 1;
vertices[2].Position = new Vector3(-10f, -10f, 0f);
vertices[2].TextureCoordinate.X = 0;
vertices[2].TextureCoordinate.Y = 1;
vertices[3].Position = new Vector3(10.1f, -9.9f, 0f);
vertices[3].TextureCoordinate.X = 1;
vertices[3].TextureCoordinate.Y = 1;
vertices[4].Position = new Vector3(-9.9f, 10.1f, 0f);
vertices[4].TextureCoordinate.X = 0;
vertices[4].TextureCoordinate.Y = 0;
vertices[5].Position = new Vector3(10.1f, 10.1f, 0f);
vertices[5].TextureCoordinate.X = 1;
vertices[5].TextureCoordinate.Y = 0;
}
我们只是为第二个三角形添加了另外 3 个顶点,以完成纹理图像。不要忘记调整您的 Draw 方法,以便您渲染 2 个三角形而不是仅 1 个三角形
device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, 2, VertexPositionTexture.VertexDeclaration);
现在运行此代码,您应该会看到整个纹理图像,由 2 个三角形显示!
资源: http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2/Textures.php
http://help.adobe.com/de_DE/Photoshop/11.0/WS0BA787A7-E4AC-4183-8AB7-55440C51F95B.html
http://openbook.galileodesign.de/photoshop_cs4/photoshop_cs4_16_3d_003.htm#mj2240859ba9be43f9c3ad8c93d649ad05
http://de.wikipedia.org/wiki/UV-Koordinaten
http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2/Textures.php