【发布时间】:2013-12-22 05:30:09
【问题描述】:
我正在尝试在我的 3D 应用程序中进行 HDR 渲染。
我知道,为了获得场景中的平均光线,您需要将渲染输出下采样到 1x1 纹理。这就是我目前正在努力的地方。
我已经设置了一个 1x1 分辨率的渲染目标,我将在该目标上绘制上一个渲染输出。我尝试使用简单的 SpriteBatch Draw 调用并使用目标矩形将输出绘制到该渲染目标。然而,希望我能发现别人没有想到的东西实在是太希望了,结果实际上并不是整个场景被下采样到 1x1 纹理,看起来好像只绘制了左上角的像素,不管我有多少使用目标矩形或比例重载播放。
现在,我正在尝试进行另一个四屏渲染通道,使用着色器技术对场景进行采样,并将单个像素渲染到渲染目标中。所以公平地说,标题有点误导,我想做的是对均匀分布在表面上的像素网格进行采样,然后将它们平均出来。但这就是我难过的地方。
我遇到了这个教程: http://www.xnainfo.com/content.php?content=28
在可以下载的文件中,有几个下采样示例,我最喜欢的一个是使用循环遍历 16 像素,将它们平均并返回。
到目前为止,我所做的任何事情都无法产生可行的输出。出于调试目的,下采样的纹理被渲染到我的屏幕一角。
我已将 HLSL 代码修改为如下所示:
pixelShaderStruct vertShader(vertexShaderStruct input)
{
pixelShaderStruct output;
output.position = float4(input.pos, 1);
output.texCoord = input.texCoord + 0.5f;
return output;
};
float4 PixelShaderFunction(pixelShaderStruct input) : COLOR0
{
float4 color = 0;
float2 position = input.texCoord;
for(int x = 0; x < 4; x++)
{
for (int y = 0; y < 4; y++)
{
color += tex2D(getscene, position + float2(offsets[x], offsets[y]));
}
}
color /= 16;
return color;
}
这里的这一行是我认为我犯了错误的地方:
color += tex2D(getscene, position + float2(offsets[x], offsets[y]));
我从未正确理解 tex2D 采样中使用的 texCoord 值是如何工作的。
在制作运动模糊效果时,为了产生正常的外观效果,我不得不转发这样的无穷大值,我担心它会被四舍五入到零,而其他时候,需要转发像 30 和 50 这样的大值来产生可能占据屏幕三分之一的效果。
不管怎样,我的问题是:
给定一个屏幕四边形(因此,平面),我如何增加或修改 texCoord 值以生成一个像素网格,均匀分布并在其上采样?
我尝试过使用:
color += tex2D(getscene, position + float2(offsets[x] * (1/maxX), offsets[y] * (1/maxY)));
其中 maxX 和 maxY 是屏幕分辨率,
color += tex2D(getscene, position + float2(offsets[x] * x, offsets[y] * y));
...和其他“黑暗中的镜头”,所有结果最终都相同:最终生成的像素似乎与我屏幕正中间的像素相同,好像这是唯一的像素正在采样。
如何解决?
另外,这些纹理坐标是如何工作的? (0,0) 在哪里?最大值是多少?
提前谢谢大家。
【问题讨论】: