Well, I added more samples, the quality is a bit better.
The shader now look like this :
static const char g_szVertexShader_BloomBlur[] =
"#extension GL_ARB_texture_rectangle : enable\n"
"precision mediump float;\n"
"uniform vec4 Local0;\n"
"varying vec4 texCoord[16];\n"
"void main(void)\n"
"{\n"
"texCoord[0] = gl_MultiTexCoord0 + Local0;\n"
"texCoord[1] = gl_MultiTexCoord0 + Local0 * 1.250;\n"
"texCoord[2] = gl_MultiTexCoord0 + Local0 * 1.375;\n"
"texCoord[3] = gl_MultiTexCoord0 + Local0 * 1.500;\n"
"texCoord[4] = gl_MultiTexCoord0 + Local0 * 1.625;\n"
"texCoord[5] = gl_MultiTexCoord0 + Local0 * 1.750;\n"
"texCoord[6] = gl_MultiTexCoord0 + Local0 * 1.875;\n"
"texCoord[7] = gl_MultiTexCoord0 + Local0 * 2.000;\n"
"texCoord[8] = gl_MultiTexCoord0 - Local0;\n"
"texCoord[9] = gl_MultiTexCoord0 - Local0 * 1.250;\n"
"texCoord[10] = gl_MultiTexCoord0 - Local0 * 1.375;\n"
"texCoord[11] = gl_MultiTexCoord0 - Local0 * 1.500;\n"
"texCoord[12] = gl_MultiTexCoord0 - Local0 * 1.625;\n"
"texCoord[13] = gl_MultiTexCoord0 - Local0 * 1.750;\n"
"texCoord[14] = gl_MultiTexCoord0 - Local0 * 1.875;\n"
"texCoord[15] = gl_MultiTexCoord0 - Local0 * 2.000;\n"
"gl_Position = ftransform();\n"
"}\n";
static const char g_szFragmentShader_BloomBlur[] =
"#extension GL_ARB_texture_rectangle : enable\n"
"precision mediump float;\n"
"uniform sampler2DRect Texture0;\n"
"varying vec4 texCoord[16];\n"
"void main(void)\n"
"{\n"
"vec3 col1 = texture2DRect(Texture0, texCoord[0].xy).rgb;\n"
"vec3 col2 = texture2DRect(Texture0, texCoord[1].xy).rgb;\n"
"vec3 col3 = texture2DRect(Texture0, texCoord[2].xy).rgb;\n"
"vec3 col4 = texture2DRect(Texture0, texCoord[3].xy).rgb;\n"
"vec3 col5 = texture2DRect(Texture0, texCoord[4].xy).rgb;\n"
"vec3 col6 = texture2DRect(Texture0, texCoord[5].xy).rgb;\n"
"vec3 col7 = texture2DRect(Texture0, texCoord[6].xy).rgb;\n"
"vec3 col8 = texture2DRect(Texture0, texCoord[7].xy).rgb;\n"
"vec3 col9 = texture2DRect(Texture0, texCoord[8].xy).rgb;\n"
"vec3 col10 = texture2DRect(Texture0, texCoord[9].xy).rgb;\n"
"vec3 col11 = texture2DRect(Texture0, texCoord[10].xy).rgb;\n"
"vec3 col12 = texture2DRect(Texture0, texCoord[11].xy).rgb;\n"
"vec3 col13 = texture2DRect(Texture0, texCoord[12].xy).rgb;\n"
"vec3 col14 = texture2DRect(Texture0, texCoord[13].xy).rgb;\n"
"vec3 col15 = texture2DRect(Texture0, texCoord[14].xy).rgb;\n"
"vec3 col16 = texture2DRect(Texture0, texCoord[15].xy).rgb;\n"
"gl_FragColor.rgb = gl_FragColor.rgb / 16.0;"
"gl_FragColor.rgb = (col1 + col2 + col3 + col4 + col5 + col6 + col7 + col8 + col9 + col10 + col11 + col12 + col13 + col14 + col15 + col16) / 16.0;\n"
"gl_FragColor.a = 1.0;\n"
"}\n";
The only thing is that I can't get past 16 arrays.
Your steps are similar to the one I have :
- Make the screen darker
- Blur the darkened texture to texture (setting a radius)
- Render full screen (1/2 resolution)
- Repeat # of times
- Combine normal and blurred scenes (using glActiveTextureARB)
- Render full screen
I'm not sure about enhancing the code. Do you have some examples ?
It's how it looks like from (rough) code :
int screenWidth = m_3DViewport[2];
int screenHeight = m_3DViewport[3];
int blurTexWidth = m_3DViewport[2]>>1;
int blurTexHeight = m_3DViewport[3]>>1;
DarkenShader->Bind();
DarkenShader->SetParameter4f( 0, m_varBloomDarkenPower, 0, 0, 0 );
RenderScaledFSQ( blurTexWidth, blurTexHeight, screenWidth, screenHeight );
blurshader->Bind();
for( i=0;i < m_varBloomNumSteps; i++ )
{
blurShader->param4f..( 0, radius0, ... );
renderFSQ( blurTexWidth, blurTexHeight );
copysubimage2D( RECTANGLE_ARB, ..., WindowSize[y] - blurTexHeight, blurTexWidth, blurTexHeight );
blurShader->param4f..( 0, radius1, ... );
renderFSQ( blurTexWidth, blurTexHeight );
copysubimage2D( RECTANGLE_ARB, ..., WindowSize[y] - blurTexHeight, blurTexWidth, blurTexHeight );
}
combineShader->Bind();
combineShader->param4..( 0, scale, 0, 0, 0 );
bindTex( RECTANGLEARB, screen );
activetexARB( GL_TEXTURE1_ARB );
bindtex( RECTANGLEARB, blurtex);
activetexARB( GL_TEXTURE0_ARB );
RenderFSQ( screenWidth, screenHeight );
combineShader->Unbind();
I'm not sure what newest games use to make a perfect high quality performances bloom :S