BGE/UPBGE/RangeGE planet terrain generation problems

Hello everyone, I need help - I’m trying to make a planetary landscape generator that works from downloadable elevation maps - the maps are seamless, however, during generation at the equator, an incomprehensible stretching of the offset occurs, if instead of height textures, procedural textures from the mathematical noise module are used, for some reason there is no such problem - can anyone tell me why this happens? and are there any possible solutions? for example, to read a height map, just like it does procedural texture?
I have already tried different options, but I have not been able to make a normal offset or read the height map as seamless, although I have made a UV scan on 6 sides of the sphere - I’ve added the script I’m working on.
TestGen.py (5.1 KB)


I could not upload the range file here because it is 178Mb large - but if necessary, I can link to it

To get a good result on a generic geometry (a plane, a sphere or any other shape) I would use triplanar mapping, you can use the vertex position in objectSpace (local coords) or in worldSpace (global coords) to sample the texture.
I would work with local coordinates in this case, because then you can get the same result regardless of the current orientation of the planet.
This is what I get using a this seamless texture:

Calculate the 3 UV coordinates for each plane
Sample 3 times using the 3 UVs
And the values obtained are modulated based on the corresponding weights

for v in range(mesh.getVertexArrayLength(0)):
    vert = mesh.getVertex(0, v)
    
    pos_LS = vert.getXYZ() #vertex coords object space
    n = pos_LS.normalized() #vertex normal in object space
    #n = vert.normal #you can also use this
    
    UV_XY = [pos_LS[0]*UVScale,pos_LS[1]*UVScale]
    UV_XZ = [pos_LS[0]*UVScale,pos_LS[2]*UVScale]
    UV_YZ = [pos_LS[1]*UVScale,pos_LS[2]*UVScale]
    
    height_XY = readBuffer(buffer, UV_XY,w,h,channels)[0]
    height_XZ = readBuffer(buffer, UV_XZ,w,h,channels)[0]
    height_YZ = readBuffer(buffer, UV_YZ,w,h,channels)[0]
    
    weight_XY = pow(fabs(n.dot(Vector([0,0,1]))),blendingFac)
    weight_XZ = pow(fabs(n.dot(Vector([0,1,0]))),blendingFac)
    weight_YZ = pow(fabs(n.dot(Vector([1,0,0]))),blendingFac)
    
    H = (height_XY*weight_XY+height_XZ*weight_XZ+height_YZ*weight_YZ)
    
    o = n*(H*terrainHeight)#offsetVec in objSpace
    vert.XYZ = (pos_LS[0]+o[0], pos_LS[1]+o[1],pos_LS[2] +o[2])
    vert.color=Vector([H,H,H,1.0])

recalculateNormals(mesh)

Here in the .zip there is the .blend that I used to test the code
triplanar diplacer.zip (1.3 MB)

1 Like

thank you - I’ll try your version - it looks very interesting - but I checked the scan itself and how the height texture is loaded on it and it is normally deployed - I thought there would be stretching - but the texture itself loads normally - so my version of the offset is not correctly implemented


I probably need to try your version to get a triplanar projection and vertex displacement

I used upbge 0.2.5 to make the file I sent.
I think there are no problems with range… anyway try replacing something in your code with what is useful for you from mine, then let me know if you’ve solved it!

yes, of course - I’ll try to do it now as soon as everything is ready, I’ll let you know - it really looks great, I didn’t even think to use the image buffer to read images from it - although I constantly saw it in the API documentation, for some reason I was fixated on reading textures as strings by XY


yes, everything works fine - a brilliant example - thank you, I have no words how cool you did it

1 Like