【问题标题】:Transforming Vertices onto Sphere in Vertex Shader在顶点着色器中将顶点转换为球体
【发布时间】:2014-06-04 23:25:28
【问题描述】:

我正在为 Unity 项目编写一个(希望如此)行星着色器。我对着色器比较陌生,据我了解,这里的语言是 CG Shader 的一个子集,称为 ShaderLab。

我的问题是这可以在着色器中完成吗?我有将坐标映射到球体的公式,但我只是弄得一团糟。我在 XNA 项目中使用相同的公式将平面从单位立方体映射到单位球体,并且效果很好。我做错了什么?

哦,我正在 Unity 中放置在 (0, 1, 0),比例为 (1, 1, 1) 的库存平面预制件上进行测试。

注意事项:

  • appdata_base :一种由位置、法线和一个纹理坐标组成的顶点格式
  • _Object2World:来自 Unity 的当前模型矩阵
  • UNITY_MATRIX_VP:当前视图 * Unity 的投影矩阵

这是我的顶点着色器:

struct v2f {
    float4 pos : SV_POSITION;
    float3 col : COLOR0;
};

v2f vert(appdata_base v) {
    v2f o;
    o.pos = v.vertex;
    o.pos = mul(_Object2World, o.pos); // _Object2World is the current model matrix from UNITY

    o.pos.x *= sqrt(1 - o.pos.y * o.pos.y / 2 - o.pos.z * o.pos.z / 2 + o.pos.y * o.pos.y * o.pos.z * o.pos.z / 3);
    o.pos.y *= sqrt(1 - o.pos.z * o.pos.z / 2 - o.pos.x * o.pos.x / 2 + o.pos.z * o.pos.z * o.pos.x * o.pos.x / 3);
    o.pos.z *= sqrt(1 - o.pos.x * o.pos.x / 2 - o.pos.y * o.pos.y / 2 + o.pos.x * o.pos.x * o.pos.y * o.pos.y / 3);

    o.pos = mul(UNITY_MATRIX_VP, o.pos);            
    o.col = v.normal * 0.5 + 0.5;

    return o;
}

【问题讨论】:

    标签: unity3d shader vertex-shader cg


    【解决方案1】:

    我在我的代码中发现了一个愚蠢的错误。我将“o.pos.x”设置为它的新值,然后使用我刚刚为“o.pos.x”计算的新值计算“o.pos.y”的结果。下面的代码可以很好地回答我的问题。

    进一步评论,在 Unity 的顶点着色器中可以将坐标映射到球体。然而,我的最终目标是不可能的,或者更具挑战性的是将地形坐标映射到球体上。 Unity 不允许旋转地形网格,并且似乎施加了其他限制。使用更高级的顶点着色器也许可以实现这样的映射。

    struct v2f {
        float4 pos : SV_POSITION;
        float3 col : COLOR0;
    };
    
    v2f vert(appdata_base v) {
        v2f o;
    
        float4 p = v.vertex;
    
        p.x *= sqrt(1 - v.vertex.y * v.vertex.y / 2 - v.vertex.z * v.vertex.z / 2 + v.vertex.y * v.vertex.y * v.vertex.z * v.vertex.z / 3);
        p.y *= sqrt(1 - v.vertex.z * v.vertex.z / 2 - v.vertex.x * v.vertex.x / 2 + v.vertex.z * v.vertex.z * v.vertex.x * v.vertex.x / 3);
        p.z *= sqrt(1 - v.vertex.x * v.vertex.x / 2 - v.vertex.y * v.vertex.y / 2 + v.vertex.x * v.vertex.x * v.vertex.y * v.vertex.y / 3);
    
        o.pos = mul(UNITY_MATRIX_MVP, p);
        o.col = v.normal * 0.5 + 0.5;
    
        return o;
    }
    

    【讨论】:

    • “地形网格”是什么意思?
    • 另外,为什么要在着色器中转换为球体?
    • @SergeyKrusch 对我来说,在着色器中变换地形似乎是获得球形地形的最简单方法。你会如何建议我将地形扭曲成一个球体?
    • 您可以在应用程序代码中执行完全相同的操作(在 C# 或 JavaScript 中)。这取决于您更改源网格的频率。如果很少:我会在应用程序中这样做。如果经常,那么,好的,着色器是一种选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多