I am trying to procedurally generate planets in Unity. The actual planet is already done, but now I am trying to add clouds. For this I created a PBR-Graph shader that draws the clouds based on some noise. It works fine on a quad and even on a plane.
The problem is, that I now created 6 meshes that form a sphere, using a script to go around the planet. I have applied the shaded material to the meshes, but for some reason it behaves, as if the entire mesh would be a single pixel, as in I don't get the white cloud shapes moving around with transparent parts inbetween, like I do on a plane, but instead the entire mesh is transparent or white or gray or partially transparent, like a single pixel from the plane. As the clouds move on the plane, the meshes around the planet flicker and change accordingly.
Could someone help me to figure this out? I don't know why its doing that and its really weird.
Basically the entire mesh acts like a single pixel of the texture, while objects like planes and quads work correctly. I can even get it to work on a sphere, but only on one I created manually by doing new 3D-Object - Sphere and then applying the shaded material to it.
As I want to be able to generate planets with a script, this wouldn't work as it involves me doing something manually...
Here is my code:
This is how the meshes are created:
for (int i = 0; i < 6; i++){
if(cloudMeshFilters[i] == null){
GameObject meshObj = new GameObject("cloudMesh");
meshObj.transform.parent = transform;
meshObj.AddComponent<MeshRenderer>();
cloudMeshFilters[i] = meshObj.AddComponent<MeshFilter>();
cloudMeshFilters[i].sharedMesh = new Mesh();
}
cloudMeshFilters[i].GetComponent<MeshRenderer>().sharedMaterial = cloudMaterial;
cloudMeshes[i] = new CloudMeshes(shapeSettings, cloudHeight, cloudMeshFilters[i].sharedMesh, resolution, directions[i]);
}
And this is the cloudMeshes class:
public class CloudMeshes
{
int resolution;
Vector3 localUp;
Vector3 axisA;
Vector3 axisB;
Mesh mesh;
ShapeSettings settings;
int height;
public CloudMeshes(ShapeSettings settings, int height, Mesh mesh, int resolution, Vector3 localUp)
{
this.mesh = mesh;
this.resolution = resolution;
this.localUp = localUp;
this.settings = settings;
this.height = height;
axisA = new Vector3(localUp.y, localUp.z, localUp.x);
axisB = Vector3.Cross(localUp, axisA);
}
public void ConstructMesh(){
Vector3[] vertices = new Vector3[resolution * resolution];
int[] triangles = new int[(resolution - 1) * (resolution - 1) * 6];
int triIndex = 0;
for(int y = 0; y < resolution; y++){
for(int x = 0; x < resolution; x++){
int i = x + y * resolution;
Vector2 percent = new Vector2(x,y) / (resolution - 1);
Vector3 pointOnUnitCube = localUp + (percent.x - .5f) * 2 * axisA + (percent.y - .5f) * 2 * axisB;
Vector3 pointOnUnitSphere = pointOnUnitCube.normalized;
vertices[i] = pointOnUnitSphere * (settings.planetRadius + height);
if (x != resolution - 1 && y != resolution - 1)
{
triangles[triIndex] = i;
triangles[triIndex + 1] = i + resolution + 1;
triangles[triIndex + 2] = i + resolution;
triangles[triIndex + 3] = i;
triangles[triIndex + 4] = i + 1;
triangles[triIndex + 5] = i + resolution + 1;
triIndex += 6;
}
}
}
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
}
The ConstructMesh() method is called after the for loop at the top has run.
Sorry for any incorrect indentations, that happend when pasting the code here...