在顶点着色器中将顶点转换为球体

时间:2014-06-04 23:25:28

标签: unity3d shader vertex-shader cg

我正在为Unity项目编程(希望)行星着色器。我对着色器比较陌生,据我所知,这里的语言是CG Shader的一个子集,叫做ShaderLab。

我的问题是可以在着色器中完成吗?我有公式将coords映射到一个球体,但我只是弄得一团糟。我在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;
}

1 个答案:

答案 0 :(得分: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;
}