I am having a procedural terrain generation application. Now i want to generate textures for the terrain based on height.
Say i have got 5 textures for different height levels now for every pixel i calculate the the position of it on the mesh then get its height and then decide which texture to sample from.
Note texture is always a square.
In code it will be something like:
for (int i = 0; i < resolution; i++) {
for (int j = 0; j < resolution; j++) {
tex[i * resolution* 3 + j * 3 + 0] = SampleTextureR(i, j);
tex[i * resolution* 3 + j * 3 + 1] = SampleTextureG(i, j);
tex[i * resolution* 3 + j * 3 + 2] = SampleTextureB(i, j);
}
}
Now SampleTextureR(i, j)
is just like:
for(TextureData* t : txtures){
if(t.heightl > GetMeshElevation(i, j) && t.heightg < GetMeshElevation(i, j))
return t.sampleR(i, j);
}
return 0;
GetMeshElevation
returns height of mesh at a point. t.sampleR() returns unsigned char
value of texture's red pixels at (i, j)
.
heightl
is minimum height of the texture
heightg
is maximum height of the texture
Now the problem is this this is very slow method. How can i make this fast enough to be done in realtime so that the changes to heightl
or heghtg
is immediately reflected. the heightl and heightg are for each texture.
These textures can be upto 4K 4096X4096
Use a varying variable between your vertex and fragment shader. A single float value should suffice, since you're only interested in the height coordinate.
Other than that, introduce 5 uniform varaiables for your textures in the fragment shader and do the calculations on the GPU.
In more detail:
For each fragment you get in the fragment shader the interpolated height value of the current mesh. Depending on the height value you simply select the sample from the desired texture and put that color out.