【问题标题】:UV mapping a procedural cylinder in Unity在 Unity 中对程序圆柱体进行 UV 映射
【发布时间】:2019-08-07 09:21:04
【问题描述】:

我有一种方法可以根据包含高度、半径和边数的变量创建圆柱体。

网格可以生成任意数量的边,但我真的很难理解这应该如何映射到 UV。

圆柱体的每一边都是由两个三角形组成的四边形。 三角形共享顶点。

我认为 uv 代码的位置是正确的,但是我不知道什么值适合? 现在纹理在网格的所有侧面都被拉伸/弯曲。 请帮助我理解这一点。

private void _CreateSegmentSides(float height)
{
    if(m_Sides > 2) { 
        float           angleStep   = 360.0f / (float) m_Sides;
        BranchSegment   seg         = new BranchSegment(m_NextID++);
        Quaternion      rotation    = Quaternion.Euler(0.0f, angleStep, 0.0f);

        int index_tr = 0, index_tl = 3, index_br = 2, index_bl = 1;
        float u0 = (float)1 / (float) m_Sides;
        int max = m_Sides - 1;

        // Make first triangles.
        seg.vertexes.Add(rotation * (new Vector3(m_Radius, height, 0f)));
        seg.vertexes.Add(rotation * (new Vector3(m_Radius, 0f, 0f)));
        seg.vertexes.Add(rotation * seg.vertexes[seg.vertexes.Count - 1]);
        seg.vertexes.Add(rotation * seg.vertexes[seg.vertexes.Count - 3]);

        // Add triangle indices.
        seg.triangles.Add(index_tr);    // 0
        seg.triangles.Add(index_bl);    // 1
        seg.triangles.Add(index_br);    // 2
        seg.triangles.Add(index_tr);    // 0
        seg.triangles.Add(index_br);    // 2
        seg.triangles.Add(index_tl);    // 3

        seg.uv.Add(new Vector2(0, 0));
        seg.uv.Add(new Vector2(0, u0));
        seg.uv.Add(new Vector2(u0, u0));
        seg.uv.Add(new Vector2(u0, 0));

        for (int i = 0; i < max; i++)
        {
            seg.vertexes.Add(rotation * seg.vertexes[seg.vertexes.Count - 2]);      // new vertex

            seg.triangles.Add(seg.vertexes.Count - 1);  // new vertex
            seg.triangles.Add(seg.vertexes.Count - 2);  // shared
            seg.triangles.Add(seg.vertexes.Count - 3);  // shared

            seg.vertexes.Add(rotation * seg.vertexes[seg.vertexes.Count - 2]);      // new vertex

            seg.triangles.Add(seg.vertexes.Count - 3);  // shared
            seg.triangles.Add(seg.vertexes.Count - 2);  // shared
            seg.triangles.Add(seg.vertexes.Count - 1);  // new vertex

            // How should I set up the variables for this part??
            // I know they are not supposed to be zero.
            if (i % 2 == 0) {
                seg.uv.Add(new Vector2(0, 0));
                seg.uv.Add(new Vector2(0, u0));
            } else {
                seg.uv.Add(new Vector2(u0, u0));
                seg.uv.Add(new Vector2(u0, 0));
            }
        }
        m_Segments.Add(seg);
    }
    else
    {
        Debug.LogWarning("Too few sides in the segment.");
    }
}

编辑:添加图片

这是圆柱体的样子(单边三角形):

这是相同着色器的外观(在平面上):

编辑 2:线框图片

【问题讨论】:

  • 你能提供一张图片吗?
  • @Menyus 已添加图片
  • 你也可以提供阴影+线框图片吗?
  • @Menyus 添加了线框图片

标签: unity3d mesh uv-mapping procedural


【解决方案1】:

所以你的线框是好的(你只链接了线框,但我要求阴影线框:这是一个shaded wireframe,但它是好的)。

你的纹理看起来像这样的原因是因为它试图将你的图像拉伸到任何高度,所以它在 1m 高度的圆柱体上看起来不错,但在 1000m 高度的圆柱体上看起来会被拉伸,所以你实际上需要动态拉伸这个 uv 贴图。

1m 高圆柱体的示例,纹理很好,因为它是 1x1 尺寸:

2m 高圆柱纹理的示例因为长度为 2x1 尺寸的两倍而被拉伸:

所以你可以做的是,如果你总是生成相同高度的圆柱体,你可以在统一内调整它,在称为平铺的纹理属性处,只需增加纹理的 x 或 y 维度,不要忘记制作纹理重复自己。 你的汽缸盖也应该是这样的(这不是必须的,但是是的):

【讨论】:

  • 感谢您的回答。实际上,我的对象根本没有那么大或拉伸,所以它有点离题了。我的问题是为每一侧计算正确的 UV 坐标。如果您看到前两张图片,则说明圆柱体的 UV 计算不正确,因此纹理以一种奇怪的方式拉伸。我认为如果坐标正确,它应该看起来与第二张图像非常相似。
  • 你也可以发布一个不透明的阴影线框吗? :)(可能只在周日晚上在 gf parents atm 回答)
  • 我没有用于播放模式的线框着色器。而且我不能同时为编辑器选择阴影和线框,我没有同时选择两者。但是,您有阴影和线框。这只是一个关于如何计算循环中每个步骤的 UV 坐标的问题。
  • 使用阴影 + 线框我可以看到你在“奇怪的结构”下的意思,顺便说一句(阴影线框):[1]:i.stack.imgur.com/3FnzI.jpg,它在场景视图选项卡上
  • 我在 Unity 版本 2018.8f1 (hdrp) 中没有该选项。奇怪地拉伸我的意思是它应该看起来与图片中的平面完全一样,具有相同的纵横比清晰度。我一直在使用顶点是 uv 坐标,现在看起来更好了,但还是有问题。必须有一个明确的方法来做到这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
  • 2018-08-05
  • 2013-05-04
  • 2012-01-09
  • 2021-02-14
  • 1970-01-01
相关资源
最近更新 更多