Sunday, January 25, 2015
XElevation, My first mobile game
Please Try it https://play.google.com/store/apps/details?id=com.oxene.games.xelevation
Wednesday, October 8, 2014
Bloom effect with Gaussian blur
In continuation from previous post about Render To Texture,
After rendering scene to texture, we can apply post-processing filters such as blur effect.
Here is the screenshot of what we are trying to achieve by combining FBO and Gaussian Blur
To achieve this,
1) Render scene to texture
2) Apply Gaussian Blur on texture in above step
3) Combine above 2 textures to get Bloom Effect
| Original Texture | Horizontal blur applied | Vertical blur applied | Final result |
As usual code is available in Google Code.
public void RenderGaussianBlur()
{ GLES20.glViewport(0, 0, fboWidth, fboHeight);float ratio = (float)fboWidth/(float)fboHeight;
float a = 5f;
Matrix.orthoM(m_fProjMatrix, 0, -a*ratio, a*ratio, -a*ratio, a*ratio, 1, 10); Matrix.multiplyMM(m_fVPMatrix, 0, m_fProjMatrix, 0, m_fViewMatrix, 0);//render scene to texture fboTex
RenderToTexture();//apply blur filter
Blur(); }
I’ll discuss here about Gaussian Blur filter alone, since FBO is covered in previous post.
we use Gaussian Blur with linear approximation in 2 steps.
1) Apply vertical blur filter on texture and render it to another texture.
2) Apply horizontal blur on above rendered texture.
below is code both steps.
public void BlurStep(int step)
{//apply horizontal blur
if (step == 1) GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIdStep1); else if (step == 2)//apply vertical blur GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIdStep2); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT); vertexBuffer.position(0); GLES20.glVertexAttribPointer(iPositionRTT, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer2); GLES20.glEnableVertexAttribArray(iPositionRTT); texBuffer.position(0); GLES20.glVertexAttribPointer(iTexCoordsRTT, 2, GLES20.GL_FLOAT, false, 0, texBuffer1); GLES20.glEnableVertexAttribArray(iTexCoordsRTT); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); if (step == 1) GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fboTex); else if (step == 2) GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fboTexStep1); GLES20.glUniform1i(iTexLocRTT, 0); Matrix.setIdentityM(m_fModel, 0); Matrix.multiplyMM(m_fMVPMatrix, 0, m_fVPMatrix, 0, m_fModel, 0); GLES20.glUniformMatrix4fv(iVPMatrix, 1, false, m_fMVPMatrix, 0); if (step == 1) GLES20.glUniform1i(iDirection, 0); else if (step == 2) GLES20.glUniform1i(iDirection, 1); GLES20.glUniform1f(iBlurScale, 1.0f); GLES20.glUniform1f(iBlurAmount, 20f); GLES20.glUniform1f(iBlurStrength, 0.5f); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); }Most important part of blur filter is blur shader. There are many approaches for achieving blur effect without compromising render speed.
To learn more about linear sampling, please follow this link.
precision mediump float;varying vec2 v_texCoords;uniform sampler2D u_texId;uniform int direction;uniform float blurScale;uniform float blurAmount;uniform float blurStrength;float GaussianFunction(float x, float dev)
{ return ((1.0/sqrt(2.0*3.142857*dev))*exp(-(x*x)/(2.0*dev)));} void main()
{ float dev = blurAmount*0.5*0.5; dev *= dev; vec4 color = vec4(0.0,0.0,0.0,0.0); vec4 temp = vec4(0.0,0.0,0.0,0.0); float strength = 1.0 - blurStrength; float half1 = float(blurAmount)*0.5; float texel = 1.0/128.0; int count = int(blurAmount); if (direction == 0) { for (int i=0;i<count;i++) { float offset = float(i) - half1; temp = texture2D(u_texId, v_texCoords+vec2(offset*texel*blurScale,0.0))*GaussianFunction(offset*strength, dev); color += temp; } } else { for (int i=0;i<count;i++) { float offset = float(i) - half1; temp = texture2D(u_texId, v_texCoords+vec2(0.0,offset*texel*blurScale))*GaussianFunction(offset*strength, dev); color += temp; } } gl_FragColor = clamp(color, 0.0, 1.0); gl_FragColor.w = 1.0;}
Saturday, February 1, 2014
Render To Texture (RTT)
In this post I’ll cover only FBO, Gaussian blur will be covered in next post.
To achieve this render scene to Frame Buffer Object (FBO), which is off-screen rendering technique, which allows us to render scene to a texture. We can use this texture to apply any post-processing filters.
Here is screenshot of what we are trying to achieve
In this post I’ll try to cover
1) Load images from Assets folder (android specific)
2) Initialize FBO
3) Render to FBO
4) Use rendered FBO texture in other scene
As usual code is available in Google Code.
Load images from Assets folder
This is a straight forward, not much code is involved. Below is the codeInitialize FBO
This is the most important part in using FBO, once initialization is done properly rest of the process is very simple.I’ll put initialization in below steps.
a) Generate Frame Buffer
b) Generate Texture, to use with frame buffer
c) Generate Render Buffer
d) Bind Frame buffer generated in first step
e) Bind texture
f) Define texture parameters like format, dimension and min/mag filters.
g) Bind render buffer and define buffer dimension
h) Attach texture FBO color attachment
i) Attach render buffer to depth attachment
Make sure that dimensions are in POT (Power Of Two), because some devices may not support NPOT textures.
On a general note, to be on the safe side use images with POT dimensions.
Below is the code part for initializing FBO
Render to FBO
Rendering to FBO is same as normal rendering except for two initial steps1) Bind the frame buffer to which we rendering
2) Set the viewport size to FBO width and height
Use rendered FBO texture in other scene
Now that we have rendered scene to texture, we can use this texture in other scenes or for post-processing etc.,That’s it in this post. Next post will be on Gaussian blur.
If you have any related questions/queries or If you find any mistakes in this post please do leave a comment.








