- Home /
How should I be procedurally texturing an object that has uvs?
Hello!
I'm trying to procedurally generate a planet. I can generate the planet, it's just texturing I'm having a hard time with. The object is a cube that has it's points normalised and then ridged multifractal noise applied to each point. That works fine.
What I'm trying to do now is texture it. The desired outcome being a planet of solid colour, with this colour value changing depending on the height of peaks (distance from its center). The object has the UVs of a cube. I create a texture2D and I've started by going through the loop for each of the vertices and drawing a pixel on the texture. This is what I get:
So, obviously I shouldn't be drawing a pixel on each vertex, but I want to have different pixel values for different vertex heights, so this way seemed to make sense to me.
Here's the function where I generate the mesh and texture. Most of this you don't have to worry about, it's just near the bottom after the 'Procedural Texturing:' comment. I left the rest in, just in case it's helpful. I understand why this isn't working, I just don't understand how I should be doing it instead. Does anyone have any advice?
void GenerateMesh()
{
perlin = new Perlin(seed);
fractal = new FractalNoise(h, lacunarity, octaves, perlin);
PlanetTexture = new Texture2D(imageWidth, imageHeight, TextureFormat.RGB24, false);
renderer.material.mainTexture = PlanetTexture;
Mesh mesh = GetComponent<MeshFilter>().mesh;
baseVertices = mesh.vertices;
Vector3[] vertices = new Vector3[baseVertices.Length];
for(int i=0;i<vertices.Length;i++)
{
Vector3 vertex = baseVertices[i];
// Normalise the cube to make a quadsphere
vertex = vertex.normalized;
// Initialise it as something, could be anything.
float noise = 1f;
// Create noise on vertex depending on which noise is selected
switch (noiseType)
{
case NoiseType.Perlin:
noise = perlin.Noise(vertex.x, vertex.y, vertex.z);
break;
case NoiseType.RidgedMultifractal:
noise = fractal.RidgedMultifractal3 (vertex.x, vertex.y, vertex.z, offset, gain);
break;
case NoiseType.HybridMultifractal:
noise = fractal.HybridMultifractal3 (vertex.x, vertex.y, vertex.z, offset);
break;
case NoiseType.fBm:
noise = fractal.BrownianMotion3 (vertex.x, vertex.y, vertex.z);
break;
}
noise = noise * scale;
vertex.x *= (1.0f + noise);
vertex.y *= (1.0f + noise);
vertex.z *= (1.0f + noise);
vertices[i] = vertex;
// Procedural texturing:
pixelUV = new Vector2(mesh.uv[i].x, mesh.uv[i].y);
pixelUV.x *= PlanetTexture.width;
pixelUV.y *= PlanetTexture.height;
// convert to int because setPixel doesn't accept floats
pixelUVx = Mathf.RoundToInt(pixelUV.x);
pixelUVy = Mathf.RoundToInt(pixelUV.y);
PlanetTexture.SetPixel(pixelUVx, pixelUVy, Color.black);
}
mesh.vertices = vertices;
mesh.RecalculateNormals();
mesh.RecalculateBounds();
// Apply the texture changes
PlanetTexture.Apply();
}
Thank you!
Could you write what result do you want to achieve? Currently your output is a dotted texture, probably with size of 256x256. Pixels are blurred because of texture size - if you increase the size, they will become smaller, if you descrease size, they will be larger.
I'm trying to have a fully textured object, not just dotted, with the colour value changing depending on the height of the vertex (distance from the center).
One way of getting a solid color with the value changing depending on height is to use Vertex colors. You need a shader that supports Vertex colors (most shaders don't). Simply set the color you want at each vertex in the $$anonymous$$esh.colors array.
What I've done now is written a surface shader which changes vertex colours based on their distance from the object center. It's pretty much what I wanted to do in the first place and runs real time. I just hadn't used shaders before!
I think that setting vertex colors in the script is a better idea in your case. Just prepare an array of colors like you do for vertices, set them inside for loop, and then assign to mesh.colors (or mesh.colors32).
Your answer
Follow this Question
Related Questions
Coin shine 1 Answer
Setting mipmaps 0 Answers
How do I texture a Procedural Mesh based on its angle? 1 Answer
MineCraft Textures 1 Answer
Gradient background 3 Answers