Sign in to follow this  
soku11

[D3D9] Simple problem with tex coords.

Recommended Posts

Hi :) I've got a very strange problem with rendering a simple quad on the screen. Positions of the vertices aren't important (I think). The texture size is 512x128 px. The fragment I want to display is positioned in (0,0) and has the dimensions of 32x32. When I calculte the tex coords for some vertices I can see that some of them are equal to 0.25 (32/128). This means that when I try to render this quad I sometimes get texture colors from row y=31 and sometimes from y=32 :/ So when I try to animate this quad by rotating it or moving I get wrong parts of the texture. Is it a bug? Is there a more appropriate way of fixing it than leaving blank pixels around texture fragments? Thanks for any help.

Share this post


Link to post
Share on other sites
try disabling the texture filter. or enable it and turn on texturemode border with a color of your choice.

Share this post


Link to post
Share on other sites
When I set the sampler states like this:

MinFilter=None;
MagFilter=None;
MipFilter=None;

I get some strange pixels on the screen and ID3DXEffect::SetTechnique() fails :/ And the solution with border is when my tex coords aren't in range [0;1] and this is not the case here - I think...

Thanks anyway :) Anybody has a better solution?

Share this post


Link to post
Share on other sites
Your shader is bad. Fix it.
If you want us to help, you'll have to post both the shader code and the code which uses the shader.

Share this post


Link to post
Share on other sites
Hi,

I think it's not only a filtering issue.

If you wish pixel perfect rendering for your 2d sprites you need to follow this steps here

Hope it's what you need.

Share this post


Link to post
Share on other sites
My technique file is rather simple:

const float4x4 worldViewProj;

struct VsInput
{
float2 position : POSITION;
float2 texCoord : TEXCOORD0;
float4 color : COLOR0;
};

struct VsOutput
{
float4 position : POSITION;
float2 texCoord : TEXCOORD0;
float4 color : COLOR0;
};

texture tex0;

sampler2D sampler0=sampler_state
{
texture=tex0;
MinFilter=point;
MagFilter=point;
};

VsOutput vsMain(in VsInput input)
{
VsOutput output=(VsOutput)0;

output.position=mul(float4(input.position,1.0f,1.0),worldViewProj);
output.texCoord=input.texCoord;
output.color=input.color;

return output;
}


static float3 COLOR_KEY={1.0f,0.0f,1.0f};

float4 psMain(in VsOutput input) : COLOR0
{
float4 output=(float4)0;

output=tex2D(sampler0,input.texCoord);
if(output.r==COLOR_KEY.r && output.g==COLOR_KEY.g && output.b==COLOR_KEY.b)
discard;

output*=input.color;

return output;
}

technique std
{
pass
{
Cullmode=ccw;
Lighting=false;
ZEnable=false;
ZWriteEnable=false;

VertexShader=compile vs_2_0 vsMain();
PixelShader=compile ps_2_0 psMain();
}
}


It's something like color key sprite shader. I know I can use alpha test (if(output.a<0.5f) discard;) but I use simple bmp files.

The worldViewProj matrix is simply a projection matrix, because it's a 2D view. I set the matrix using this function:

D3DXMatrixOrthoOffCenterLH(&matrices.projection,0.0f,width,height,0.0f,-1.0f,1.0f);

Unfortunately everything seems fine to me :/

About the article: I've found earlier a similiar but shorter one about it. The solution presented there was to change by 0.5 some limit variables in the projection matrix. I changed it in many ways, but nothing helped :/

Share this post


Link to post
Share on other sites
You should look at the debug runtime output too. It might say what you're doing wrong with the shader. ;)
Also, either the MipFilter should be "none" or you should take the mipmap edge transparency into account when rendering your triangles.

Share this post


Link to post
Share on other sites
I am looking at the runtime output with max output debug level in d3d. There are no errors there, only warnings about ignoring states. Disabling the mip filter doesn't help me solve the problem :/

Share this post


Link to post
Share on other sites
You'll have to either recompile everything with the debug d3dx library or check the return value of SetTechnique.

Share this post


Link to post
Share on other sites
I'm not quite sure what for... I don't have any errors at maximum debug level, everything draws fine. Only setting every filter mode to none doesn't give me proper frame and setTechnique() call fails...

Share this post


Link to post
Share on other sites
That's the problem. Shader doesn't work because SetTechnique doesn't work.
Only the debug d3dx library outputs errors to the output window.
But you can try to look up the error code and its explanation too.

Share this post


Link to post
Share on other sites
Hmpf... Are you sure? I just figured out that since it compiles and works with point filtering, setting all filters to none is just impossible (and stupid?). And what's the difference between none and point filtering? Point filtering takes the nearest pixel - that I know. However I just have no clue how "none filtering" works.

Btw. SetTechnique fails because there is no valid technique in the file. Finding technique fails because of the filter. When I try to set MagFilter to none in technique file:

MagFilter=none;


I get this error in output window:

Direct3D9: (ERROR) :Unsupported mag filter.


So is it relevant to the problem?

Share this post


Link to post
Share on other sites
There is no such thing as "NONE" filtering for minification or magnification. That is why the debug output tells you it's an invalid setting. NONE is only valid for MipFilter, which causes the GPU to just use the top-level mipmap.

Share this post


Link to post
Share on other sites
So I was right :) However the problem is still not solved :/ I'm starting to feel that the only solution is to use texture files with one pixel border around sprites...

Share this post


Link to post
Share on other sites
I guess nothing will be better than a border there.. you could make several textures there but it's more expensive and kills the whole point of sprite atlases.

EDIT: One thing popped in my mind - how about changing texture coordinates to exclude the "evil" borders?

Share this post


Link to post
Share on other sites
Can you tell something more about changing texture coordinates? Because I don't quite understand how and what's the benefit...

Share this post


Link to post
Share on other sites
It's simple. You just add/subtract 0.5 / 1 / 1.5 * size of a pixel as required to get hard borders.
But really, adding transparent borders is much better. Why do you want to avoid that option?

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