Generating heightmap for each side on unit cube

Started by
1 comment, last by raRaRa 9 years, 8 months ago

Hello! This is my first post here so be nice! ;)

Like everybody else, I'm working on a procedural planet engine, except it's going to run on your browser using WebGL! The project is going fairly well and I've already morphed a unit cube to sphere using Philip Nowell's method at http://mathproofs.blogspot.com/2005/07/mapping-cube-to-sphere.html

I've also implemented Quadtree for LOD management, frustum view culling and horizon culling. You can try my latest demo at http://jontrausti.com/frustum1/

So far so good! My next step (surprise!) is generating heightmap for each side of the unit cube. I've implemented Simplex 3d noise shader that will render once per terrain patch (quadtree node) to a texture. I pass in the four cube space corners of the terrain patch to the noise shader. My problem is not knowing how to lerp/interpolate between those corner positions.

I've been Googling all day and I came across one blog that was facing the same problem. On his blog he's passing the four cube space corners of a terrain patch to the shader. Here's his shader: (taken from http://britonia.wordpress.com/2009/12/23/noise-part-iii-gpu/)


float4 PS_INoise(float2 inTexCoords : TEXCOORD0) : COLOR0
{
    float land0 = (float)0;

    // Get the direction, from the origin (top-left) to the end vector (bottom-right).
    float3 xDirection = xNE - xNW;
    float3 zDirection = xSW - xNW;

    // Scale the distance by the texture coordinate (which is between 0 and 1)
    xDirection *= inTexCoords.x
    zDirection *= 1 - inTexCoords.y;

    // Lerp outward from the originSY (top-left) in the direction of the end vector (bottom-right)
    float3 lerpedWorldPos = xNW + xDirection + zDirection;

    land0 = doTerrainNoise(lerpedWorldPos);
    return land0;
}

Here's my shader converted to GLSL:


    vec3 xNW = v0;
    vec3 xNE = v1;
    vec3 xSW = v2;
    
    // Get the direction, from the origin (top-left) to the end vector (bottom-right).
    vec3 xDirection = xNE - xNW;
    vec3 zDirection = xSW - xNW;

    // Scale the distance by the texture coordinate (which is between 0 and 1).
    xDirection *= gl_FragCoord.x;
    zDirection *= 1.0 - gl_FragCoord.y;

    vec3 pos = xNW + xDirection + zDirection;

I'm mapping xNW to v0 which is the top left vertex, xNE to the top right vertex (v1) and xSW to the bottom left vertex (v2).

This works fine for the first node that represents a whole side on the cube, but once it splits to four children the top left children gets a correct heightmap but the other 3 (top right, bottom right and bottom left) get the same heightmap as the top left node.

Here's a picture showing the problem more clearly. The first picture shows when the face has one node.

OdwSi0b.png

Second picture shows when it has split to four nodes:

0N900yF.png

And here are the four coordinates I pass to the shader:

The first node before its split to four children:


[-1,  1, 1] v0
[ 1,  1, 1] v1
[-1, -1, 1] v2
[ 1, -1, 1] v3

The four children:

Top left:


[-1, 1, 1] v0
[ 0, 1, 1] v1
[-1, 0, 1] v2
[ 0, 0, 1] v3

Top right:


[0, 1, 1] v0
[1, 1, 1] v1
[0, 0, 1] v2
[1, 0, 1] v3

Bottom left:


[-1,  0, 1] v0
[ 0,  0, 1] v1
[-1, -1, 1] v2
[ 0, -1, 1] v3

And so forth...

It would be greatly appreciated if someone could help me in the right direction. In the mean time I'm going to attempt to find out why I keep getting the top left node correct. This has to be some simple problem that I just can't see.

Thanks!

Kindest regards,

Jon Arason

Advertisement

I'm having trouble following your logic without the full shader but the problem seems pretty obvious that you're repeating the same noise values for each leaf of your quad tree. Your quad tree data should be something along the lines of:

  • Cube Face (Noise Parameters = 0.0, 0.0 -> 1.0, 1.0f)
    • Sub Face 0 (Noise Parameters = 0.0, 0.0 -> 0.5, 0.5)
    • Sub Face 1 (Noise Parameters = 0.5, 0.0 -> 1.0, 0.5)
    • Sub Face 2 (Noise Parameters = 0.0, 0.5 -> 0.5, 1.0)
    • Sub Face 3 (Noise Parameters = 0.5, 0.5 -> 1.0, 1.0)

Right now it looks like you're basically passing around the first sub face's noise space coordinates to all children, but it's hard to say without more insight into your noise generation.

Thanks for the feedback AdeptStrain. It turned out to be a simple mistake on my part when I was converting the HLSL shader to GLSL. The original shader was using inTexCoords which I changed to gl_FragCoord. After switching to the texture coordinates everything started working normally.

Now I just need to figure out how to make each face match each other. :-)

Thanks!

This topic is closed to new replies.

Advertisement