简体   繁体   English

XNA RenderTarget半像素偏移

[英]XNA RenderTarget half pixel offset

I have come across this great explanation regarding DX9 and accordingly, XNA's catch regarding the pixel offsetting when attempting to render to a target texture for the purpose of using Post Process pixel shader effects: 我遇到了有关DX9的出色解释,因此,为了使用后期处理像素着色器效果,当尝试渲染到目标纹理时,XNA涉及到像素偏移的问题:

Since reading that article I did notice that the image produced by my Engine code is somewhat blurry, not 100% crisp, when using post process effects. 自从阅读了这篇文章后,我确实注意到,使用后期处理效果时,引擎代码生成的图像有些模糊,而不是100%清晰。 I do have the code for skipping post process effects, so it can be ran on slower machines. 我确实有跳过后处理效果的代码,因此可以在速度较慢的计算机上运行。

I have tried to implement the solution presented in the article and I noticed it did help to some extent, however the image is still not quit crisp, that is, I do not believe I am achieving 1:1 pixel mapping in my rendering code. 我已经尝试实现本文中介绍的解决方案,但我注意到它确实在一定程度上有所帮助,但是图像仍然不清晰,也就是说,我不相信我在渲染代码中实现了1:1像素映射。

I am using the following Shader code in my post process shader effect: 我在后期处理着色器效果中使用以下着色器代码:

PixelShaderStruct vertShader(VertexShaderStruct input)
{
    PixelShaderStruct output;
    input.pos.X -=  halfPixel.X;
    input.pos.Y -=  halfPixel.Y;
    output.position = float4(input.pos, 1);
    output.texCoord = input.texCoord;

    return output;
}

I am forwarding the following variable as halfPixel variable: 我将以下变量作为halfPixel变量转发:

bloom.Parameters["halfPixel"].SetValue(new Vector2(0.5f / (float)Game1.maxX, 0.5f / (float)Game1.maxY));

MaxX and MaxY are correct integer numbers for the resolution currently used, at all times. 对于任何时候, MaxXMaxY始终是当前使用的分辨率的正确整数。

I am achieving following results with this code. 通过此代码,我将获得以下结果。

Without post process shaders: http://i690.photobucket.com/albums/vv263/Eudaimonium/3D%20Renderings/test2_zps1fb27bcf.png As crisp as it gets. 没有后期处理着色器: http : //i690.photobucket.com/albums/vv263/Eudaimonium/3D%20Renderings/test2_zps1fb27bcf.png尽可能清晰。

However, using the post process shaders (and consequently, using more than several render-to-target passes): http://i690.photobucket.com/albums/vv263/Eudaimonium/3D%20Renderings/test1_zps64a20018.png 但是,使用后期处理着色器(并因此使用多个渲染到目标通道): http : //i690.photobucket.com/albums/vv263/Eudaimonium/3D%20Renderings/test1_zps64a20018.png

As you can see by the white bounding box outlines, it appears the lower-left border pixels of edges are somewhat crisp, but blurred in up-right direction resulting in incorrect result. 如您所看到的白色边框轮廓所示,边缘的左下边界像素看起来有些清晰,但是在右上方向模糊,导致结果不正确。

I have made sure that MSAA is turned off at starting of the game and every resolution change. 我确保在游戏开始和每次更改分辨率时都关闭MSAA。

I can't figure out what's wrong. 我不知道怎么了。

I think you missed the relevant paragraph in the article you linked: 我认为您错过了链接文章中的相关段落:

Note, that when I say “subtract a half-pixel from position,” what I mean is “move the position of the quad one half-pixel towards the upper-left. 请注意,当我说“从位置减去半像素”时,我的意思是“将四分之一半像素的位置移到左上角。 To do this, you actually add (-1/width, +1/height). 为此,您实际上要添加(-1 / width,+ 1 / height)。 The reason for the signs (-, +) is that you're moving left and up. 符号(-,+)的原因是您向左和向上移动。 In post-projection space, -x is left, and +y is up. 在投影后空间中,-x左,+ y向上。 The reason that it's 1/width instead of 0.5/width is because, in clip space, the coordinates range from -1 to 1 (width 2), and not from 0 to 1 (width 1) like they do in textures, so you need to double the movement to account for that. 之所以是1 /宽度而不是0.5 /宽度,是因为在剪辑空间中,坐标的范围是-1到1(宽度2),而不是0到1(宽度1),就像它们在纹理中一样,所以您需要加倍动作以解决该问题。

So change 所以改变

input.pos.X -= halfPixel.X;
input.pos.Y -= halfPixel.Y;

to

input.pos.X -= halfPixel.X;
input.pos.Y += halfPixel.Y;

and use (1f / width, 1f / height) as your halfPixel value. 并使用(1f / width, 1f / height)作为您的halfPixel值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM