Я хочу уменьшить входную текстуру с 800x600 до одной четверти (200x150 пикселей). Но если я это сделаю, я смогу увидеть лишь небольшую часть изображения. Кажется, что кадровый шейдер не сэмплирует всю текстуру. В следующем примере показано создание эффекта глубины резкости.
Вершинный шейдер:
#version 330
uniform UVertFrameBuffer
{
mat4 m_ScreenMatrix;
};
uniform UDofInvertedScreenSize
{
vec2 m_InvertedScreenSize;
};
// -----------------------------------------------------------------------------
// in variables
// -----------------------------------------------------------------------------
layout(location = 0) in vec3 VertexPosition;
// -----------------------------------------------------------------------------
// out variables
// -----------------------------------------------------------------------------
struct SPixelCoords
{
vec2 tcColor0;
vec2 tcColor1;
};
out SPixelCoords vs_PixelCoords;
// -----------------------------------------------------------------------------
// Program
// -----------------------------------------------------------------------------
void main()
{
vec4 Position = vec4(VertexPosition.xy, 0.0f, 1.0f);
vec4 PositionInClipSpace = m_ScreenMatrix * Position;
vec2 ScreenCoords = VertexPosition.xy;
// -----------------------------------------------------------------------------
vs_PixelCoords.tcColor0 = ScreenCoords + vec2(-1.0f, -1.0f) * m_InvertedScreenSize;
vs_PixelCoords.tcColor1 = ScreenCoords + vec2(+1.0f, -1.0f) * m_InvertedScreenSize;
// -----------------------------------------------------------------------------
gl_Position = PositionInClipSpace;
}
Фрагментный шейдер:
#version 330
uniform sampler2D g_ColorTex;
uniform sampler2D g_DepthTex;
uniform UDofDownBuffer
{
vec2 m_DofNear;
vec2 m_DofRowDelta;
};
// -----------------------------------------------------------------------------
// Inputs per vertice
// -----------------------------------------------------------------------------
struct SPixelCoords
{
vec2 tcColor0;
vec2 tcColor1;
};
in SPixelCoords vs_PixelCoords;
// -----------------------------------------------------------------------------
// Output to graphic card
// -----------------------------------------------------------------------------
layout (location = 0) out vec4 FragColor;
// -----------------------------------------------------------------------------
// Program
// -----------------------------------------------------------------------------
void main()
{
// Initialize variables
vec3 Color;
float MaxCoc;
vec4 Depth;
vec4 CurCoc;
vec4 Coc;
vec2 RowOfs[4];
// Calculate row offset
RowOfs[0] = vec2(0.0f);
RowOfs[1] = m_DofRowDelta.xy;
RowOfs[2] = m_DofRowDelta.xy * 2.0f;
RowOfs[3] = m_DofRowDelta.xy * 3.0f;
// Bilinear filtering to average 4 color samples
Color = vec3(0.0f);
Color += texture(g_ColorTex, vs_PixelCoords.tcColor0.xy + RowOfs[0]).rgb;
Color += texture(g_ColorTex, vs_PixelCoords.tcColor1.xy + RowOfs[0]).rgb;
Color += texture(g_ColorTex, vs_PixelCoords.tcColor0.xy + RowOfs[2]).rgb;
Color += texture(g_ColorTex, vs_PixelCoords.tcColor1.xy + RowOfs[2]).rgb;
Color /= 4.0f;
// Calculate CoC
...
// Calculate fragment color
FragColor = vec4(Color, MaxCoc);
}
Входная текстура имеет размер 800x600, а выходная текстура — 200x150 пикселей. В качестве m_InvertedScreenSize я использую 1/800 и 1/600 пикселей. Это правильно?
Я загружаю два треугольника, которые представляют собой экранные координаты OpenGL.
QuadVertices[][1] = {
{ 0.0f, 1.0f, 0.0f, },
{ 1.0f, 1.0f, 0.0f, },
{ 1.0f, 0.0f, 0.0f, },
{ 0.0f, 0.0f, 0.0f, }, };
QuadIndices[][2] = {
{ 0, 1, 2, },
{ 0, 2, 3, }, };
Моя экранная матрица переводит эти вершины в пространство отсечения через ортогональную матрицу.
Position(0.0f, 0.0f, 1.0f);
Target(0.0f, 0.0f, 0.0f);
Up(0.0f, 1.0f, 0.0f);
LookAt(Position, Target, Up);
SetOrthographic(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
Следующие изображения показывают исходную текстуру и результат. Первый — это исходное изображение без понижающей дискретизации. Во-вторых, это реальная сэмплированная текстура. И третья — это текстура с пониженной частотой дискретизации с вычислением ScreenCoords *= 4.0f;.