# Geometry clipmap normals

## Recommended Posts

Hi, I've been getting nowhere with this for ages now! My geometry clipmap normal map blending just doesn't blend! Each level is 129 vertices wide (128 polygons), with a 256 normal map over the top. I'm 99% sure my fragment shader is ok as I have tested it with solid colour transitions instead of normal maps etc. I've also checked that my XY and ZW normals are ok (4 normals (in a quad shape) at a finer level all have the same coarser normal which correlates to the normal at the coarser level) So I think I'm missing some aspect of how texture filtering or something works? The edges of my levels look 'roughly' ok, but have a crack where the resolution of the normal map changes... Desperate for help! :( Thanks, Hybrid

##### Share on other sites
One other thing.. am i correct in thinking that my normal map UV's need never change? (i have a seperate vertex and UV array)

##### Share on other sites
Which version of geometry clipmap are you implementing ? the first one, or the GPU accelerated one (using vertex textures) ?
And could you post some screenshots of the problem ?

In my implementation, in the vertex shader, I compute a morphing value which I then use to interpolate between current values and coarser values (I use the same morphing vaule for the height and the normals / colors) ... so if it works for the height, it should also work for anything else :s

##### Share on other sites
Yeah the first one with no vertex textures..

my height morphing works fine, and I've tested that the alpha value is correctly passed to the fragment shader and used correctly to morph the two normals.

but when i use the normal maps it just looks like the levels aren't blending at all.

im at work at the mo but will try post a screenshot over the weekend :)

one thing im unsure of is:
am i ok to use a level width of power of two + 1 ? (i.e. 129) and then a normal map at double resolution which spans polygons (128 * 2 = 256) ?

this means, that a normal is computed from the four vertices surrounding it at the next finer level (because it is double resolution of the current level), and the coarser normal is computed from the four surrounding vertices at the current level.

##### Share on other sites
Yeah, that shouldn't cause any blending problems ...
I can't really help you until I see some screenshot or shader code, so I'll try to come back here this WE :) Or next monday if nobody helped you in the meantime :p

##### Share on other sites
Cheers i really appreciate it - I'm pretty busy the w/e but I'll defo get some more details up by sunday evening at the latest, shader code and a screenshot :)

##### Share on other sites
Im just wondering,
because I have 129 vertices across a level, and a normal map of 256 (128*2) i'm effectively using face normals (one normal per quad) is this what is causing me problems?

I've seen 2 clipmap implemntations.. one using 127 (power of 2 - 1), the other using 129 (power of 2 + 1) for a level... maybe I need to change that? :
If i switch to 127 vertices, and have a 256 normal map, my UV's wouldnt quite reach 1.0 ...

maybe i need some clarity on how i should be implementing this stuff... :(

Hybrid

##### Share on other sites
Hi,

image can be found at

fragment code:

// this contains 2 normals in xy/zw
float4 fPackedNormal = tex2D(t2NormalMapSampler, IN.fUV);

// normal at this level
float3 fNormal1 = float3(
fPackedNormal.x,
sqrt(1.0f - (fPackedNormal.x * fPackedNormal.x) - (fPackedNormal.y * fPackedNormal.y)),
fPackedNormal.y);

// normal at coarser level
float3 fNormal2 = float3(
fPackedNormal.z,
sqrt(1.0f - (fPackedNormal.z * fPackedNormal.z) - (fPackedNormal.w * fPackedNormal.w)),
fPackedNormal.w);

// blended normal based on alpha
float fAlpha = IN.fColour.w; // we stored the level alpha in the output colour's alpha
float3 fBlendedNormal = float3((fAlpha * fNormal1) + ((1 - fAlpha) * (fNormal2)));

// output raw normal map as a test
OUT.fColour = float4(fBlendedNormal.xyz, 1);

as you can see im just showing the raw normal maps for now, disregarding lighting :)

##### Share on other sites
Hi,
When I look closely on the edges of the clipmaps, there seem to be a smal region where the normals are actually interpolated, but it's like the coarser normal stored in the normal map is not correct ...
(see the highlighted area in your screenshot (click))
Did you try to show the coarser normals for each level, and check if they are correct ?
(I would just replace "sqrt(1.0f - (fPackedNormal.x * fPackedNormal.x) - (fPackedNormal.y * fPackedNormal.y))" by 1.0f and then normalize the result though :))

##### Share on other sites
I've looked over my code for genrating my normal map after looking at what you've put, and I'm pretty sure you're right (and I'm pretty sure I know why)

I wasn't taking into account bilinear filtering properly, so for any normal, i was presuming that it's coarser normal would be the same as the normal of the larger poly it sat on.

This isn't true as the normal would be being interpolated, so instead of my coarser normals being stored as:
a, a, b, b, c, c, (1D example)

they should be being stored as:
a, ab midpoint, b, bc midpoint, c, etc

does this sound correct?

What's the best way to do this?
At present i do this: (pseudocode assuming double resolution normal map)

polywidth = 128
normwidth = 256

for(vertx=0 to polywidth)
for(verty=0 to polywidth)
{
cache_TL_vertices(x,y) // store the 4 vertices that apply to this polygon at next finer level (Top-Left)
cache_TR_vertices(x,y) // store the 4 vertices that apply to this polygon at next finer level (Top-Right)
cache_BL_vertices(x,y) // store the 4 vertices that apply to this polygon at next finer level (Bottom-Left)
cache_BR_vertices(x,y) // store the 4 vertices that apply to this polygon at next finer level (Bottom-Right)

// 4 normals for this level
calc_TL_normal(TL_vertices);
calc_TR_normal(TR_vertices);
calc_BL_normal(BL_vertices);
calc_BR_normal(BR_vertices);

// the bit thats wrong
calc_whole_quad_normal(); // use the top left vert of the TL vertices, bottom right vert of the BR vertices, etc to create a normal which will be stored as the coarser normal for this group of 4 normals
}

does this sound like the problem to you?
what's the best way to fix it?

really appreciate your help so far! :)

Hybrid

##### Share on other sites
Ok, so you compute the normals for a quad if I understood well ... so you end up with something like :
|-------------||      |      ||  TL  |  TR  ||      |      ||-------------||      |      ||  BL  |  BR  ||      |      ||-------------|

For the current level, you compute the normals of the 4 quads, you encode the value in the R and G channels of your normal map. Then you compute the normal for the big quad, and store it in the B and A channels of the normal map ?
Sounds ok ...
To compute the coarser normal, you juste have to add the 4 normals (TL, TR, BL and BR) and divide by 4. And you store the value in the 4 pixels used to store the current normals for TL, TR, BL and BR.

If you don't care to share your code, you can send it by email, and I can have a look at it (although I might not found anything wrong :) )

##### Share on other sites
Hey, thanks a lot, you seem to fully understand how I am implementing my normal maps with all that TL/TR/BL/BR stuff :)

tried to fix it last night based on my own ideas (failed), and then tried your suggestions just now after reading your reply.. and its still broken! ...Looking remarkably similar to how it always has! :(

have sent you a PM with some code excerpts... feel rude sending you loads of code but am bit desperate, sorry :
Hybrid

##### Share on other sites
It seems to me that the edge problem is due to bilinear filtering with wrap addressing mode. Have you tried clamp addressing mode?

##### Share on other sites
Hi,

although toggling clamping on and off produces different visuals, it doesn't solve the problem,

with clamping on, a border becomes subtley visible around each level, with it off, there is no border, but the levels do not blend either.

i think im failing to understand something about the theory of how the normal map should be implemented and how bilinear filtering works :(

##### Share on other sites
The code seems ok, are you sure you are getting the correct alpha values?
You could output alpha directly in your shader as a gray scale color to check it out.

##### Share on other sites
I think the alpha value is correct since it's the same as the one used to morph heights, and there doesn't seem to be any gap between clipmaps ...

I'll take a look at the codes :)

##### Share on other sites
Cheers matey!

Regarding the alpha, yeah those values are correct, as you suggested I have already verified that by outputting the alpha directly as greyscale, and also yes the heights are morhping correctly :)

thanks for the suggestions tho guys :( hehe

Hybrid

##### Share on other sites
In my clip mapper I needed to offset the U by 1/texturewidth and my V by 1/textureheight. This is because the value of a texture element when it is being iterpolated is only exact at the dead center of a pixel. i.e. UV of 0.0, 0.0 blends the top corner pixel with either the border color, or the color of the pixels at the other four corners. This could cause what you are seeing in your screen shot.
Also try changing the blend border width in your clipmap to cover more area and you might get a better idea of what is going on. Its hard to tell when its only one unit across.

##### Share on other sites
oh my god :)

ok my normal blending isn't perfect... but it suddenly looks a whole lot better!!!! AND even better i understand *why* that change is necessary, muchos thankyous dude :)

still think my coarser normals are slightly wrong (think i need to take a midpoint of surrounding coarser normals to simulate what bilinear filtering will do) but at least now I feel that I've (with a little help) sorted the biggest part of this problem out!!

saddest thing is.. that fix took about 2 mins to put in :( lol

thanks! :)

##### Share on other sites
Post new screen shots? Maybe we can help further :)

##### Share on other sites
Hey I'm going away tonight so won't be able to add any further info now until sunday evening :)

i had applied the half pixel offset in my c++ code for the UVs, but realised this would break when the terrain moved around, so I'm going to undo that change so the UVs are scaled 0-1 like before, and put the half pixel offset fix into the fragment shader code, using the alpha value to scale it to the edges, this way i think my original UVs will never need to change when the clipmap updates?

Hybrid

##### Share on other sites
Yeah thats what I did, I passed the texture size to the shader and did the UV offsets in there.

##### Share on other sites
Hey chaps, sorry long time no reply!

Sorted my normals ... almost! Blending is as good as I can get it without doing some more sampling to better approximate bilinear filtering, but the pixel/texel size on screen means the edges would never be apparant anyway so I'm happy with that!

Having a strange second problem now... when I move my clipmap around I'm getting garbage along the seems of my texture, but apart from that it's moving around fine!

Take a look...

http://www.justdlit.co.uk/rich/no_movement.JPG
http://www.justdlit.co.uk/rich/moved.JPG

Any ideas?

PS. it behaves pretty much the same regardless of texture clamping/wrapping

##### Share on other sites
Hi,

I've verified my textures, and no corruption appears in the actual textures themselves, so it must be down to my shader.

Texture wrapping is enabled, and that's all that's relevant I think..!

The part of my shader that retrieves my packed normal is as follows:
(the half pixel offset code is disabled for now as it doesn't affect the problem)

**********************

// this contains 2 normals in xy/zw
float4 fPackedNormal = ((tex2D(t2NormalMapSampler, IN.fUV) * 2.0f) - 1.0f);

**********************

but im pretty sure this code is fine..!
Has anyone seen anything like this before? Or got any ideas wht it could be?
It looks like it's blending right back across the whole texture rather than wrapping?

Hybrid

## Create an account

Register a new account

• ## Partner Spotlight

• ### Forum Statistics

• Total Topics
627662
• Total Posts
2978515

• 10
• 10
• 12
• 22
• 13