Lookup tables using Textures

Started by
19 comments, last by nara 14 years, 12 months ago
Hi, I would like to know how to assign values for textures using DirectX. I'm having a texture which at the time of rendering to the screen size would like to modify based on the screen position. I can get the screen position using the Vertex shaders, but to know what action to be taken in the pixel shader i would like to have the look up table. I'm using DirecX 9. Thanks in advance.
Advertisement
Hi,

You don't need to get screen positions while using lookup tables. Just use full-screen quads and while processing'em, use a variable /w semantic "TEXCOORD0", also you don't need to write a vertex shader for this.

Example: Writing z/w position data retrieving World Space position from this texture
//writinguniform extern float4x4 g_WVP;void VS_ZW (float4 posL : POSITION0,            out float4 posH : POSITION0,            out float4 posH2: TEXCOORD1){  posH = posH2 = mul(posL, g_WVP);}float4 PS_ZW(float4 posH2 : TEXCOORD1) : COLOR0{  return float4 (posH2.z/posH2.w, 0, 0, 0);}//retrieving (we wrote z/w values above to a 2D Render Target Texture, and now we're passing it here as myZWTex).uniform extern float4x4 g_InvViewProj;uniform extern texture myZWTex;sampler smpZW = sampler_state{  texture = <myZWTex>;  MinFilter = LINEAR;  MagFilter = LINEAR;  MipFilter = LINEAR;  AddressU = CLAMP;  AddressV = CLAMP;};float4 ProcessZW (float2 t : TEXCOORD0) : COLOR0{  float z = tex2D (smpZW, t).r; // z/w value  float x = 2 * (t.x) - 1;  float y = 2 * (1 - t.y) - 1;  float4 posW = mul(float4(x, y, z, 1), g_InvViewProj);  posW.xyz /= posW.w;  //...  return SOME_COLOR;}


Just look at ProcessZW shader, it's a pixel shader and while using lookup textures, I just use a TEXCOORD0 semantic variable, t.

There's no "hard", and "the impossible" takes just a little time.
Hi Thanks for your reply.

Can you also let me know how I can assign the look-up tables values to the Texture Quad in the C++ program so that the same can be referred in PS as given by you. My lookup table values are a series of float values.

Thanks,
Hi,

It will be better if you tell what you want to do ;)

Quote:My lookup table values are a series of float values


Just describe your problem and I think I can help you ;)
There's no "hard", and "the impossible" takes just a little time.
Hi

I will explain my problem in a simpler way.

I have a image of 1920x1080 (don't worry about the size though as it will vay), and this is made up of a series of small image arranged in a different way (just like puzzle).

Now for the actual problem - I will have to render a screen of 1280x1024 (again not fixed) and for this to render i will have to arrange the images from the 1920x1080 in a specific manner such that it will have to be addressed at the pixel level.
So i have a look up table of 1280x1024 which says that for pixel
position 1 look into x1y1 position of 1920x1080
position 2 look into x2y2 position of 1920x1080 and so on so forth.

My current approach is to find the screen position which corresponds to 1280x1024 in the pixel shader. However i'm unable to pass the look table values required for the mapping.

I hope you have got my requirement.

Nara
Ok,

Using pixel shader may not be a good idea. Just let's try the simplest approach.

You're sure that your lookup tex. has size of 1280x1024.

1 - You've to create this texture with MANAGED POOL:
D3DXCreateTexture (pD3DDevice, 1280, 1024, 1, D3DUSAGE_DYNAMIC, format(*), D3DPOOL_MANAGED, &pLookUpTex);


(*)Format is important here, if your lookup values consist of;
- only 1 float value, you can use either D3DFMT_R16F or D3DFMT_R32F.
- two float values, you can use D3DFMT_G16R16F.
- three float values, you can use either D3DFMT_X8R8G8B8 or D3DFMT_A2R10G10B10.
- four float values, you can use either D3DFMT_A8R8G8B8 or D3DFMT_A16B16G16R16F.
(You should check the device for format whether it supports or not).

2 - Lock the entire region and just fill whatever you want:
D3DLOCKED_RECT LRect;pLookUpTex->LockRect (0, &LRect, NULL, 0);BYTE* pBits = (BYTE*)LRect.pBits;for (UINT y = 0; y < 1024; y++){   D3DCOLOR* pColor = (D3DCOLOR*)(pBits + LRect.pitch * y);   for (UINT x = 0; x < 1280; x++)   {       pColor[x] = WHAT_VALUE_YOU_WANT;   }}pLookUpTex->UnlockRect (0);


Hope this helps.

Regards,
Rohat.
There's no "hard", and "the impossible" takes just a little time.
Hi Rohat,

Thanks for your reply. It definitely throws some light for me. The reason for the pixel shader is we need to do this on multiple frames and also the final sample can be of different arrangement.

I still have one question, which is since i have to pass the position of my initial texture (1920x1080) as look up table, do i need to convert it into texture coordinates.

Thanks for the help.

Nara
Hi,

Quote:... do i need to convert it into texture coordinates?


No, you don't.
There's no "hard", and "the impossible" takes just a little time.
Hi, I have implemented the code but my output doesn't seem to be coming correct. Here is what i'm doing.

Here is my CPP code where i'm creating the texture and assigning values.
hr = D3DXCreateTexture(g_pd3dDevice,1280,1024,1,					D3DUSAGE_DYNAMIC,D3DFMT_R16F,D3DPOOL_DEFAULT ,&R_MapXTex);D3DLOCKED_RECT pLockedRect;	hr= R_MapXTex->LockRect(0,&pLockedRect,0,0);BYTE* pBits = (BYTE*)pLockedRect.pBits;for (UINT y = 0; y < 1024; y++){	Point *CurPoint =(Point*)(pBits + pLockedRect.Pitch * y);	for (UINT x = 0; x < 1280; x++)	{ 	CurPoint[x].x = ((x*1.5) / 960)-1; // converting 1920 coords 	CurPoint[x].y = ((y) / 540)+1; // converting 1080 coords	}}R_MapXTex->UnlockRect (0);


My Vertex shader code
struct VertexShaderOutput{    float4 Position : POSITION0;    float4 ScreenPosition : TEXCOORD0;};VertexShaderOutput Main_VS(VertexShaderInput input){    VertexShaderOutput output;    //processing geometry coordinates    float4 worldPosition = mul(float4(input.Position,1),WorldMatrix);    output.Position = worldPosition ;    output.ScreenPosition = output.Position;    return output;}


My pixel shader is as below
PS_OUTPUT Main_PS(VertexShaderOutput input,		 sampler View1TexSampler,		 sampler View2TexSampler,{	float4 FinalColor =0;        float2 R_Cord =0;	R_Cord = tex2D(View2TexSampler,input.ScreenPosition.xy);        FinalColor.r = tex2D(View1TexSampler,R_Cord).r;        output.diffuse = FinalColor;        return output;}


For some reason the output screen looks blank. I think the coordinates passed from view2texsampler to view1texsampler is the culprit. Not sure if there is the worldview conversion which is causing the problem.

Please suggest.

[Edited by - nara on April 21, 2009 3:01:06 AM]
Hi Nara,

I saw that you're using two values per pixel:

Quote:
   CurPoint[x].x = ((x*1.5) / 960)-1; // converting 1920 coords    CurPoint[x].y = ((y) / 540)+1; // converting 1080 coords


But you've created your texture with format D3DFMT_R16F. You should use D3DFMT_G16R16F. Also, you're casting as "Point". You don't need to do this. You can use D3DCOLOR.
I recommend you to use that snippet (or something like):
...hr = D3DXCreateTexture(g_pd3dDevice, 1280, 1024, 1, D3DUSAGE_DYNAMIC, D3DFMT_G16R16F, D3DPOOL_DEFAULT ,&R_MapXTex);D3DLOCKED_RECT pLockedRect;	hr= R_MapXTex->LockRect(0,&pLockedRect,0,0);BYTE* pBits = (BYTE*)pLockedRect.pBits;for (UINT y = 0; y < 1024; y++){	D3DCOLOR *CurPoint =(D3DCOLOR*)(pBits + pLockedRect.Pitch * y);	for (UINT x = 0; x < 1280; x++)	{ 	CurPoint[x].r = ((x*1.5) / 960)-1; // converting 1920 coords 	CurPoint[x].g = ((y) / 540)+1; // converting 1080 coords        //Store in r and g channels	}}R_MapXTex->UnlockRect (0);


Now let's look at your shader. In VS, TEXCOORD0 semantic of your VS output equals to worldposition. I guessed that you're asking whether your conversion above must be converted to tex. coords or not from your "do i need to convert it into texture coordinates?" question, sorry :) If you're just passing your "conversion table" texture to shader, you don't need to transform texcoords. Also I think that you don't need a VS either. Just use a PS with one parameter:

PS_OUTPUT Main_PS(float2 t : TEXCOORD0,		 sampler View1TexSampler,		 sampler View2TexSampler,{	float4 FinalColor =0;        float2 R_Cord =0;	R_Cord = tex2D(View2TexSampler,t).rg; //we've stored in r and g channels        FinalColor.r = tex2D(View1TexSampler,R_Cord).r;        output.diffuse = FinalColor;        return output;}


Hope this helps.
There's no "hard", and "the impossible" takes just a little time.

This topic is closed to new replies.

Advertisement