Sprite tearing due imprecise pixel coordinates (both uv and pos), how to fix it?

Started by
2 comments, last by Headkaze 10 years, 9 months ago

I dont know why exactly stuff happens, its driving me fucking nuts..really fucking hell nuts

Example:

I have 3 buttons on a texture, Those 3 buttons are displayed on the bottom half of the screen, one bellow the other. Button 1 and 3 are perfect.

Button 2 tears, like its struggling to fit in its pixels. Heres what annoys, it just tears on this spot on the screen, after trying everything (setting pos to perfect ints, rounding UVs, doing that even on the shader) it still tears.

I put the button to move up and down on the screen so I can see what happens. That one little bastard just tears on that specific spot bellow half the screen, Id say in an area covering 50 vertical px, after that, bot above and bellow it doesnt tear anymore.

Now the fact is, if I change the UV coords of the button, say giving it button 1 or 3 UVs, it doesnt tear...so its happening both because pos and UVs..

My positions are in ints, Im setting stuff on pixel coordinates. My backbuffer is definetly at the same size of client coord (1280x720), wich matches exactly my viewport, and my projection Im setting using directX math ortho function, giving the 1280x720 coords also (I know I have pixel coords working fine, if I set to move 1 by mouse click, I can see the sprites moving by one px at a time ).

Heres my sprite shader:


vs_out vs_Sprite( float3 pos_p : POSITION, float2 uv_p : TEXCOORD ){

	vs_out output = (vs_out)0;

	//vertex scaling
	pos_p.xy *= res;

	output.pos = mul( float4( pos_p, 1.0f ), mWorld );	

	//camera(view) trafo:
	output.pos = mul( output.pos, mViewProjection ); 
	

	//on screen coords:
	//output.pos = mul( output.pos, mProjection ); 

	//uv offset:
	output.uv = uvRect.xy + (uv_p * uvRect.zw);

	// just pass color on:
	output.color = color;

	return output;	
}

All my sprites use a vertex buffer specifying a 1.0 scale quad (-0.5f to 0.5f, with 0.0f to 1.0f uvs)

I generally create my texture files as equally spaced sprite sheet, so I easily set uvs like "1.0f/3.0f" instead of using px coords, but I dont see how that could have any influence, since in the shader uvs end up as 0.0 to 1.0 anyway (on the sample function), thats why I generally set myself on the 0.0 to 1.0 range, both easier and practical. (tryed already setting uv width / texture width, to see if would solve any imprecision, the result is the same)

Im using nearest sample, of course using linear smooths the issue, but its not even close to what I call a solution, as it blurs instead of fixing.

Heres a image showing the same sprite, same position on screen, same everything, except the uv coords:

Untitled-1.png

You can see the A and Y have lots of aliasing. It of course, doesnt look like that on the texture file, nor in other positions of the screen.

What can/should I do to avoid that? Something I missed? Is it due the vertex buffer being a -0.5 to 0.5 scaled quad?

This is just an specific example where I tryed to focus to figure it out, other sprites end up tearing when moving on the screen (noting to do with vsync, its not screen tearing). Say I grab a sprite with mouse and use it to translate the sprite, mouse also moves on int coords, I can also notice tearing, like the sprite got shortenned by one px horizontally or vertically. Perhaps Im doing some really noob thing.

Advertisement


That one little bastard just tears on that specific spot bellow half the screen, Id say in an area covering 50 vertical px, after that, bot above and bellow it doesnt tear anymore.

Now the fact is, if I change the UV coords of the button, say giving it button 1 or 3 UVs, it doesnt tear...so its happening both because pos and UVs..

sounds like its happening because of the UV coords of button #2 or how you process them. from your description, only button #2's texture gets screwed up, and only at specific screen locations. So there's something wrong with button #2's UV coords, or the way you process them at that location on the screen. if button 2's UV coords are in no way unusual, odds are its the code that uses them. that would be where to look first.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Before my response Id like to express my concern towards the language you are using, swearing 3 times just because you are frustrated on a forum where young creative people regularly visit does not seem very becoming of someone who's been a member for almost 5 years. I am sure many other members of the forum would agree with me that if you truly wish to have help from us, that refraining from that sort of behaviour in the future would be appropriate. At this time I'll take it that you didn't realise your language would offend, I'll try to help this time.

OK to the question you asked, if you are allowing non-integer positioning and scaling of the geometry then the pixels you output may not necessarily ever map to the screen coordinates you are hoping for, to make matters worse even if you get it to work on your computer, it may not look right on others. There are some work around's like adding a half texel (not pixel) offset to your UV's, but it really depends on what interpolation method you are relying upon.

In the end there are only a few options when it comes to this sort of thing, either accept it the way it is, try using higher resolution textures so the sampler can give better results, play with the half texel hack and hope it works for other computers, and/or stick to integer positioning and scaling to help the correct positioning of pixels.

Aimee

We are now on Tumblr, so please come and check out our site!

http://xpod-games.com

Not sure what version of DirectX you're using but check out Directly Mapping Texels to Pixels (Direct3D 9) or Coordinate Systems (Direct3D 10).

This topic is closed to new replies.

Advertisement