OpenGL - 保持纹理宽高比
OpenGL - Maintain texture width to height ratio
我有一个 256x256 的板条箱纹理和一个两倍长的平面。
我想保持纹理的纵横比并控制它的比例因子,而不是将它拉伸到所有角落,如下所示。
这是我的对象数据:
// Vertex Positions
Vector3 vertices = new Vector3[] {
new Vector3( 1, 0, 1),
new Vector3( 3, 0, 1),
new Vector3( 3, 1, 1),
new Vector3( 1, 1, 1)};
// Index Order
int[] indices = new int[] {0, 1, 2, 0, 2, 3};
// Texture Co-ordinates
Vector2 texcoords = new Vector2[] {
new Vector2 (0.0f, 0.0f),
new Vector2 (1.0f, 0.0f),
new Vector2 (1.0f, 1.0f),
new Vector2 (0.0f, 1.0f)};
// Normals
Vector3 normals = new Vector3[] {
new Vector3 (0.0f, 0.0f, 1.0f),
new Vector3 (0.0f, 0.0f, 1.0f),
new Vector3 (0.0f, 0.0f, 1.0f),
new Vector3 (0.0f, 0.0f, 1.0f)};
我启用了以下纹理重复:
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, Convert.ToInt32(TextureWrapMode.Repeat));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, Convert.ToInt32(TextureWrapMode.Repeat));
通过将纹理坐标与平面的高度和宽度相匹配,纹理会按预期重复。
// Texture Co-ordinates
Vector2 texcoords = new Vector2[] {
new Vector2 (0.0f, 0.0f),
new Vector2 (2.0f, 0.0f),
new Vector2 (2.0f, 1.0f),
new Vector2 (0.0f, 1.0f)};
但是,我希望所有 256x256 纹理的显示大小一致,无论平面大小如何。
根据纵横比调整纹理坐标。
例如,如果您的图块具有 2:1(宽度:高度)纵横比,则您的纹理坐标在 X 轴上的范围为 0-2,而不是 0-1。这将导致纹理在 X 中平铺两次。
您需要检查 X 是否大于 Y,反之亦然。如果是前者,请按 quadWidth / quadHeight 缩放 X。否则,按 quadHeight / quadWidth 缩放 texCoord.y。
这样,您的最小尺寸将从 0 到 1,而较大的尺寸将调整以匹配您的纹理方面。
您可以将纹理宽度和高度(或纵横比,但宽度和高度有时非常有用,所以我只是将它们分别以 float2 uniform 分别发送为 x 和 y)到您的着色器,并在那里进行更正。
OP 的补充评论:
这成功了。通过计算平面宽度 (x2 - x1)
和纹理偏移 (x1 % 1)
,纹理现在水平对齐 "world grid"。
// Texture Co-ordinates
Vector2 texcoords = new Vector2[] {
new Vector2 (TextureOffset, 0.0f),
new Vector2 (TextureOffset + Width, 0.0f),
new Vector2 (TextureOffset + Width, 1.0f),
new Vector2 (TextureOffset, 1.0f)};
我有一个 256x256 的板条箱纹理和一个两倍长的平面。
我想保持纹理的纵横比并控制它的比例因子,而不是将它拉伸到所有角落,如下所示。
这是我的对象数据:
// Vertex Positions
Vector3 vertices = new Vector3[] {
new Vector3( 1, 0, 1),
new Vector3( 3, 0, 1),
new Vector3( 3, 1, 1),
new Vector3( 1, 1, 1)};
// Index Order
int[] indices = new int[] {0, 1, 2, 0, 2, 3};
// Texture Co-ordinates
Vector2 texcoords = new Vector2[] {
new Vector2 (0.0f, 0.0f),
new Vector2 (1.0f, 0.0f),
new Vector2 (1.0f, 1.0f),
new Vector2 (0.0f, 1.0f)};
// Normals
Vector3 normals = new Vector3[] {
new Vector3 (0.0f, 0.0f, 1.0f),
new Vector3 (0.0f, 0.0f, 1.0f),
new Vector3 (0.0f, 0.0f, 1.0f),
new Vector3 (0.0f, 0.0f, 1.0f)};
我启用了以下纹理重复:
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, Convert.ToInt32(TextureWrapMode.Repeat));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, Convert.ToInt32(TextureWrapMode.Repeat));
通过将纹理坐标与平面的高度和宽度相匹配,纹理会按预期重复。
// Texture Co-ordinates
Vector2 texcoords = new Vector2[] {
new Vector2 (0.0f, 0.0f),
new Vector2 (2.0f, 0.0f),
new Vector2 (2.0f, 1.0f),
new Vector2 (0.0f, 1.0f)};
但是,我希望所有 256x256 纹理的显示大小一致,无论平面大小如何。
根据纵横比调整纹理坐标。
例如,如果您的图块具有 2:1(宽度:高度)纵横比,则您的纹理坐标在 X 轴上的范围为 0-2,而不是 0-1。这将导致纹理在 X 中平铺两次。
您需要检查 X 是否大于 Y,反之亦然。如果是前者,请按 quadWidth / quadHeight 缩放 X。否则,按 quadHeight / quadWidth 缩放 texCoord.y。
这样,您的最小尺寸将从 0 到 1,而较大的尺寸将调整以匹配您的纹理方面。
您可以将纹理宽度和高度(或纵横比,但宽度和高度有时非常有用,所以我只是将它们分别以 float2 uniform 分别发送为 x 和 y)到您的着色器,并在那里进行更正。
OP 的补充评论:
这成功了。通过计算平面宽度 (x2 - x1)
和纹理偏移 (x1 % 1)
,纹理现在水平对齐 "world grid"。
// Texture Co-ordinates
Vector2 texcoords = new Vector2[] {
new Vector2 (TextureOffset, 0.0f),
new Vector2 (TextureOffset + Width, 0.0f),
new Vector2 (TextureOffset + Width, 1.0f),
new Vector2 (TextureOffset, 1.0f)};