I'm programming a (hopefully) planetary shader for a Unity project. I'm relatively new to shaders, and as I understand the language here is a subset of CG Shader called ShaderLab.
我正在为一个联合项目设计一个(希望)行星着色器。我对着色器比较陌生,我理解这里的语言是一个叫做ShaderLab的CG着色器的子集。
My question is can this be done in a shader? I have the formulas to map coords to a sphere, but I just get a tangled mess. I used the same formulas in an XNA project to map planes from a unit cube to a unit sphere and it worked fine. What am I doing wrong?
我的问题是,这能在着色器中完成吗?我有把坐标映射到球面的公式,但我只是得到了一个混乱的混乱。我在XNA项目中使用了相同的公式,将平面从一个单位立方体映射到一个单位球体,它运行得很好。我做错了什么?
Oh, and I'm testing this on a stock plane prefab in Unity placed at (0, 1, 0), scale (1, 1, 1).
哦,我在一个平面预置的平面上测试它(0,1,0),标度(1,1,1)
Things to note:
注意事项:
- appdata_base : a vertex format that consists of position, normal and one texture coordinate
- appdata_base:由位置、正常和一个纹理坐标组成的顶点格式。
- _Object2World : current model matrix from Unity
- _Object2World:来自Unity的当前模型矩阵。
- UNITY_MATRIX_VP : current view * projection matrix from Unity
- UNITY_MATRIX_VP:当前视图*来自Unity的投影矩阵。
Here is my vertex shader:
这是我的顶点着色器:
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 个解决方案
#1
1
I found a silly mistake in my code. I was setting 'o.pos.x' to it's new value, then figuring the result for 'o.pos.y' using the new value I just calculated for 'o.pos.x'. The code below works satisfactorily in answering my question.
我在我的代码中发现了一个愚蠢的错误。我是设置的o.pos。x'到它的新值,然后计算结果。y'用我刚才计算的新值。下面的代码很好地回答了我的问题。
To comment further, mapping coordinates to a sphere is possible in a vertex shader in Unity. However, my end goal is impossible or much more challenging which is to map terrain coordinates onto a sphere. Unity doesn't allow terrain meshes to be rotated and seemingly imposes other restrictions. It might be possible to achieve such mapping with a more advanced vertex shader.
若要进一步评论,在一个顶点着色器中,可以将坐标映射到一个球体。然而,我的最终目标是不可能的,或者更具有挑战性的是将地形坐标映射到一个球体上。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;
}
#1
1
I found a silly mistake in my code. I was setting 'o.pos.x' to it's new value, then figuring the result for 'o.pos.y' using the new value I just calculated for 'o.pos.x'. The code below works satisfactorily in answering my question.
我在我的代码中发现了一个愚蠢的错误。我是设置的o.pos。x'到它的新值,然后计算结果。y'用我刚才计算的新值。下面的代码很好地回答了我的问题。
To comment further, mapping coordinates to a sphere is possible in a vertex shader in Unity. However, my end goal is impossible or much more challenging which is to map terrain coordinates onto a sphere. Unity doesn't allow terrain meshes to be rotated and seemingly imposes other restrictions. It might be possible to achieve such mapping with a more advanced vertex shader.
若要进一步评论,在一个顶点着色器中,可以将坐标映射到一个球体。然而,我的最终目标是不可能的,或者更具有挑战性的是将地形坐标映射到一个球体上。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;
}