Sign in to follow this  
prux

Lens distortion2

Recommended Posts

hey there, this kind of problem was already discussed here: http://www.gamedev.net/community/forums/topic.asp?topic_id=543188 with the last post, but I need something else. I quote the solution: [quote]Instead of solving it mathematically, you could also use a "DU/DV" map:
float4 PixelShaderFunction(float2 texCoord: TEXCOORD0) : COLOR0
{
        // Get offset
        // Use the quad texcoords ( [0,0]..[1,1] )
        // Convert the offset contents red/green from [0..1] to [-1..+1]
        float2 offset 2 * tex2D( dudvMap, quadTexCoord.xy ).rg - 1;

        // Apply distortion strength with a custom parameter
        offset.xy *= distortionScale.xy;

        // Apply offset on the quadTexcoords
        float2 offsetTexCoords = quadTexCoord.xy + offset.xy;

        // Grab result
	return tex2D( ScreenSampler, offsetTexCoords.xy );
}
The DU/DV map uses 2 colors, red and green. Red is the x offset, green the y. Since you might want it bi-directional, you need to rescale it from [0..1] to [-1..+1]. If you do so, also keep that in mind when drawing the DU/DV map. Pixels with ZERO offset have the values {red:128, green:128}. As a side-note, be carefull when grabbing pixels from your screenSampler at the borders. The offset might put the texcoords outside the [0..1] range. This could generate strange effects at the borders of your screen. You could prevent this by simply smoothing the offsets towards zero, either in the texture itself, or shader-wise. Greetings, Rick[/quote] the only missing thing is, the offset values are byte-byte only. This -128..127 range isnt enough for me, I want more. I know how to build a "bigger" bumpmap but how to modify this example?

Share this post


Link to post
Share on other sites
and if I use D3DFMT_X8R8G8B8 format? Sorry but I trust in these format better than your "exotic" one =)

EDIT: unfortunatly, it doesnt work, in the old solution, when I set "10" to each element of the matrix, it really offsetted the picture by 10 pixel right-down, but now I have to give a very big value to something even happen....

Share this post


Link to post
Share on other sites
Quote:
Original post by prux
the only missing thing is, the offset values are byte-byte only. This -128..127 range isnt enough for me, I want more. I know how to build a "bigger" bumpmap but how to modify this example?


Quote:
Original post by prux
and if I use D3DFMT_X8R8G8B8 format? Sorry but I trust in these format better than your "exotic" one =)


Is it the floating point in the texture that you don't like or the not being rgba8? if its floating point you could use D3DFMT_G16R16 since you only need the x/y offset, the texture would be the same size bit give you 16 bit precision for x/y

another option would be to use the mathematical model presented beforehand where you will get the better precision without a texture and if you want to modify the distortion you only have to modify the shader not a texture.

Share this post


Link to post
Share on other sites
Quote:
Original post by prux
and if I use D3DFMT_X8R8G8B8 format? Sorry but I trust in these format better than your "exotic" one =)

EDIT: unfortunatly, it doesnt work, in the old solution, when I set "10" to each element of the matrix, it really offsetted the picture by 10 pixel right-down, but now I have to give a very big value to something even happen....

What exactly were you expecting? Two-channel 32bpp formats are hardly 'exotic,' and there's no magic ImprovePrecision() function in HLSL-- 8 bits is 8 bits.

Share this post


Link to post
Share on other sites
Quote:
Original post by prux
and if I use D3DFMT_X8R8G8B8 format? Sorry but I trust in these format better than your "exotic" one =)

EDIT: unfortunatly, it doesnt work, in the old solution, when I set "10" to each element of the matrix, it really offsetted the picture by 10 pixel right-down, but now I have to give a very big value to something even happen....


G16R16F is anything but exotic. 16-bit floating-point was well supported on the earliest D3D9 GPU's.

There's no reason switching the format shouldn't work for you, at least based on the code you've shown. I would suggest doing some debugging in PIX to see what kinds of values you're writing to the texture, and what's happening in your shader.

Share this post


Link to post
Share on other sites
thx the replies,

I forgot to tell that I need to do it in 1.4, DX8. I found out that the code works under DX9 2.0 PS and not with the DX8 one. The HLSL code:

sampler2D input0 : register(s0);
sampler2D input1 : register(s1);
float4 main(float2 uv : TEXCOORD0, float2 uv2 : TEXCOORD1) : COLOR
{
float4 Color = tex2D(input1, uv2);
uv2.x = uv.x + (Color.r * 256);
uv2.y = uv.y + (Color.g * 256);
Color = tex2D(input0, uv2);
return Color;
}



and this is how the compiler compiled:

2.0

//
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.08.299.0000
//
// fxc /nologo /Tps_2_0 /Emain shader.ps
//
//
// Parameters:
//
// sampler2D input0;
// sampler2D input1;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// input0 s0 1
// input1 s1 1
//

ps_2_0
def c0, 256, 0, 0, 0
dcl t0.xy
dcl t1.xy
dcl_2d s0
dcl_2d s1
texld r0, t1, s1
mad r0.x, r0.x, c0.x, t0.x
mad r0.y, r0.y, c0.x, t0.y
texld r0, r0, s0
mov oC0, r0

// approximately 5 instruction slots used (2 texture, 3 arithmetic)


1.4

//
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.08.299.0000
//
// fxc /nologo /Tps_1_4 /Emain shader.ps
//
//
// Parameters:
//
// sampler2D input0;
// sampler2D input1;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// input0 s0 1
// input1 s1 1
//

ps_1_4
def c0, 256, 256, 256, 0
texcrd r0.xyz, t0
texld r1, t1
mad r2.x, r1.x, c0.x, r0.x
mad r2.yz, r1.y, c0, r0.y
phase
texld r0, r2

// approximately 5 instruction slots used (3 texture, 2 arithmetic)


and it also says: "shader.ps(9): warning X4704: literal values outside range -1 to 1 are clamped on all ps_1_x shading models"

what is the difference here between 1.4 and 2.0? I know 1.4 is outfashioned but I really need it.

Share this post


Link to post
Share on other sites
The main issue causing that warning in 1.4 for that shader is that pixel shader 1.4 used fixed point integers, where 2.0 uses floating point (minimum of 24 bit precision).

However I'm not sure why you want to multiply your colours by 256 before adjusting the UVs with them - UVs go from 0-1 across the whole texture. I'd suggest multiplying them by something much smaller than 1.0

Share this post


Link to post
Share on other sites
Sadly, now everything is that simple. Lets see this picture (I modified to G16R16 format):

http://prux.uw.hu/bm.gif

and the source.

sampler2D input0 : register(s0);
sampler2D input1 : register(s1);
float4 main(float2 uv : TEXCOORD0, float2 uv2 : TEXCOORD1) : COLOR
{
float2 Color = tex2D(input1, uv2).rg;
Color.x = 0.5; Color.y = 0.5;
return tex2D(input0, Color);
}


the result now is RED.

the Color.x = 0.4; Color.y = 0.8; results BLUE as it's expected.

but Color.x = 0.5; Color.y = 0.5; is somewhat yellow and brown - which is not in the picture. Is it somehow resized the base image?

Share this post


Link to post
Share on other sites
okay it solved, maybe some of you interested in that.
Texture format is D3DFMT_R16G16 it works under PS 1.4 too.
The matrix coordinates need to be recalculated

texX = 65536 * (XVALUE * (1 / PICTUREWIDTH))
texY = 65536 * (YVALUE * (1 / PICTUREHEIGHT))

sorry for a lot of stupid post I didnt see the things clearly.

Share this post


Link to post
Share on other sites

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