Sign in to follow this  

geoclipmaps toroidal update

This topic is 3736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

ive been trying to implement toroidal updates on a texture to later use with geoclipmaps for the last 4-5 days... ive "successfully" implemented the rendering of the two quads that render to the update region and they are correctly placed in the different shapes... ... and ive also solved the problems with the update regions wrapping... by adjusting the update region size in these cases... ive "somewhat" implemented toroidal updates... where the texture is correctly updated when and only when you update strictly horizontal OR vertical... simply by drawing the region outside of the cliptexture based on the "virtual camera position" (real center of the clipmap) to the current update region my problem is however with diagonal moves where u get a L or + shaped updateregion... i cant find any logical way to correctly update this... i have a basetexture size and a cliptexture size and an camera position... any help or suggestions would be very appreciated EDIT:: maybe i should mention that im doin the updates on the gpu with rtt [Edited by - Dragon_Strike on September 18, 2007 3:39:42 AM]

Share this post


Link to post
Share on other sites
EDIT:: well it seems like blunt man is right... but i cant see what wrong with my code then... it works with vertical or horizontal but gets weird with diagonal move


this is my current code that works horizontally and vertically... id appreciate any suggestions..


void UpdateLevel(bool skip = false)
{
HRESULT hr = 0;

RTT0->beginScene();

UpdateShader->PreKernel();
UpdateShader->BeginPass(0);

V(UpdateShader->SetTexture("Tex0", HeightMap0->GetTex()));
V(UpdateShader->SetVector("EyePos", &Cur_World_Eye));
V(UpdateShader->SetFloat("ClipSize", ClipSize));


// Offset_World_Eye = Cur_World_Eye-Last_World_Eye in world space
Offset_World_Eye = Cur_World_Eye-Last_World_Eye;

// Last_Clip_Eye = last updatepos in clipspace
// Cur_Clip_Eye = current updatepos in clipspace
// Offset_Clip_Eye = updateoffset in clipspace
Last_Clip_Eye = Cur_Clip_Eye;
Offset_Clip_Eye = Offset_World_Eye/ClipSize;
Cur_Clip_Eye += Offset_Clip_Eye;

float Px1 = Last_Clip_Eye.x;
float Px2 = Cur_Clip_Eye.x;
float Pz1 = Last_Clip_Eye.z;
float Pz2 = Cur_Clip_Eye.z;

float xFrom = fract(min(Px1,Px2));
float xTo = fract(max(Px1,Px2));
float zFrom = fract(min(Pz1,Pz2));
float zTo = fract(max(Pz1,Pz2));

// if moving backwards then we want to take samples from the leftdir = -x
if (Offset_Clip_Eye.x < 0)
{
Px1 -= 1;
Px2 -= 1;
float temp = Px1;
Px1 = Px2;
Px2 = temp;
}

// ScreenQuad->RenderPart(quad origion, quad dest)... where 0.0 is screen lower left and 1.0 is screen top right
// meaning ScreenQuad->RenderPart(0.0,1.0) renders to the entire viewport
if (xFrom > xTo) // if updateregion wraps
{
UpdateShader->SetVector("Update", &D3DXVECTOR4(int(Px1), int(Pz1), fract(Cur_Clip_Eye.x),fract(Cur_Clip_Eye.z)));
UpdateShader->CommitChanges();
ScreenQuad->RenderPart(D3DXVECTOR2(xFrom,0.0f), D3DXVECTOR2(1.0f,1.0f));

UpdateShader->SetVector("Update", &D3DXVECTOR4(int(Px1)+1, int(Pz1), fract(Cur_Clip_Eye.x),fract(Cur_Clip_Eye.z)));
UpdateShader->CommitChanges();
ScreenQuad->RenderPart(D3DXVECTOR2(0.0f,0.0f), D3DXVECTOR2(xTo,1.0f));

}
else
{
UpdateShader->SetVector("Update", &D3DXVECTOR4(int(Px1), int(Pz1), fract(Cur_Clip_Eye.x),fract(Cur_Clip_Eye.z)));
UpdateShader->CommitChanges();
ScreenQuad->RenderPart(D3DXVECTOR2(xFrom,0.0f), D3DXVECTOR2(xTo,1.0f));
}


// if moving backwards then we want to take samples from the downdir = -z
if (Offset_Clip_Eye.z < 0)
{
Pz1 -= 1;
Pz2 -= 1;
float temp = Pz1;
Pz1 = Pz2;
Pz2 = temp;
}

if (zFrom > zTo) // if updateregion wraps
{
UpdateShader->SetVector("Update", &D3DXVECTOR4(int(Px1), int(Pz1), fract(Cur_Clip_Eye.x),fract(Cur_Clip_Eye.z)));
UpdateShader->CommitChanges();
ScreenQuad->RenderPart(D3DXVECTOR2(0.0f, zFrom), D3DXVECTOR2(1.0f,1.0f));

UpdateShader->SetVector("Update", &D3DXVECTOR4(int(Px1), int(Pz2), fract(Cur_Clip_Eye.x),fract(Cur_Clip_Eye.z)));
UpdateShader->CommitChanges();
ScreenQuad->RenderPart(D3DXVECTOR2(0.0f,0.0f), D3DXVECTOR2(1.0f,zTo));
}
else
{
UpdateShader->SetVector("Update", &D3DXVECTOR4(int(Px1), int(Pz1), fract(Cur_Clip_Eye.x),fract(Cur_Clip_Eye.z)));
UpdateShader->CommitChanges();
ScreenQuad->RenderPart(D3DXVECTOR2(0.0f,zFrom), D3DXVECTOR2(1.0f,zTo));
}

Last_World_Eye.z = Cur_World_Eye.z; // Set new update pos
Last_World_Eye.x = Cur_World_Eye.x; // Set new update pos

UpdateShader->EndPass();

UpdateShader->PostKernel();

RTT0->endScene();
}




and the update shader

uniform extern texture Tex0;
uniform extern float3 EyePos;
uniform extern float ClipSize;

uniform extern float4 Update;

sampler Tex = sampler_state
{
Texture = <Tex0>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};

struct OutputVS
{
float4 posH : POSITION0;
float2 tex0 : TEXCOORD0;
};

OutputVS RadarVS(float3 posL : POSITION0, float2 tex0 : TEXCOORD0)
{

OutputVS outVS = (OutputVS)0;

outVS.posH = float4(posL, 1.0f);

float2 ClipPos = (posL.xy+1.0)*0.5;

float ratio = ClipSize/4096.0f;
ClipPos.x = (ClipPos.x+Update.x) * ratio;
ClipPos.y = (ClipPos.y+Update.y) * ratio;

outVS.tex0 = ClipPos.xy;

return outVS;
}

float4 RadarPS(float2 tex0 : TEXCOORD0) : COLOR
{
return tex2D(Tex, tex0).rrrr;
}

technique RadarTech
{
pass P0
{
// Specify the vertex and pixel shader associated with this pass.
vertexShader = compile vs_3_0 RadarVS();
pixelShader = compile ps_3_0 RadarPS();
}
}








[Edited by - Dragon_Strike on September 22, 2007 6:51:05 AM]

Share this post


Link to post
Share on other sites
I ran into the same problems, and fixed them by seperating my Update function into an UpdateX and UpdateY function. I can't really remember the details I am afraid! All I remember is that my x and y variables were getting updated in incorrect orders and this would cause my UpdateXAndY function to work incorrectly. Maybe you have the same problem..
If you completely seperate X and Y functions then your algorithm could look like:
calculateXMove
updateX
calculateYMove
updateY

Share this post


Link to post
Share on other sites
ive looked at the GPU Gems code.. but it doesnt cover this issue...

i think ive found what the problem is...

Free Image Hosting at www.ImageShack.us


as u can see in the pic the x update region just continues where it left of... should it be like this? if not what should happen when u keep moving diagonally "up"

EDIT:: Ive uploaded the project if anyone wants to take a look at it...Project Download

Share this post


Link to post
Share on other sites

This topic is 3736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this