入力テクスチャを 800x600 から 4 分の 1 (200x150 ピクセル) にダウンサンプリングしたいと考えています。しかし、そうすると、画像が少ししか見えなくなります。frament シェーダはテクスチャ全体をダウンサンプリングしていないようです。次の例では、被写界深度効果を作成します。
頂点シェーダー:
#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 の画面座標を表す 2 つの三角形をアップロードします。
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);
次の画像は、入力テクスチャと結果を示しています。1つ目は、ダウンサンプリングなしの元の画像です。2 番目は、実際にダウン サンプリングされたテクスチャです。3 つ目は、ScreenCoords *= 4.0f; を計算してダウン サンプリングされたテクスチャです。