Geometry clipmap normals

Started by
22 comments, last by Hybrid666 16 years, 9 months ago
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
Advertisement
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)
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
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.
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
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 :)
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
Hi,

image can be found at
http://www.justdlit.co.uk/adam/clipmapnormalmap.JPG

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 :)
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 ?
Your fragment shader seems 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 :))
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

This topic is closed to new replies.

Advertisement