Sign in to follow this  

blending in all render target

Recommended Posts

hi Im using 2 RT, the first store diffuse color, the second for normals, all use format GL_RGBA8, Id like to be able to do blending in all RT, so when I enable blending, the second RT gets affected as well, but I dont know how to do that, can u point me in the right direction? thx.

Share this post

Link to post
Share on other sites
Huh ... you moved it to OpenGL section then ... hm...

I personally didn't test it (and I can't test it right now), although as far as I'm concerned it will blend all the render targets based upon alpha you will supply, e.g.:

gl_FragData[0] = vec4(color, alpha);
gl_FragData[1] = vec4(normals, alpha);

This should blend the colors and normals based upon blendfunc...

gl_FragData[0] = vec4(color, alpha);
gl_FragData[1] = vec4(normals, 1.0);

This will blend just your colors and not normals.

It should work like this, but as I said I haven't tested yet, I'm using megatexture approach, or do color/normal mixing (blending) inside a shader (as I use some realtime generated noise to have a bit of randomness inside it).
I'll try it in the evening and let you know here.

Share this post

Link to post
Share on other sites
well, ure right. argh but that means I have to 'sacrifice' the alpha channel of each RT, unh well I'll look around for another solution then...Im using the alpha channel of the first RT for specular intensity and of the second for specular power...

Share this post

Link to post
Share on other sites
I'm doing blending inside the shader mostly (e.g. not using GL_BLEND, because I need the alpha channel of RTs (not here though)), e.g. I want blend 4 different materials (diffuse maps + normal maps) in single cell of terrain (I got terrain divided into cells). I send rgba color that says where is which material (red means first, green second, etc.).

E.g. terrain G-buffer shader can look like this (one of mine olders, it can be optimised further a lot):

Vertex shader

// GLSL 330 - e.g. OpenGL 33, core profile (no backwards compatibility), SM 4.0
#version 330
#define GL_core_profile 1
#extension GL_EXT_gpu_shader4 : enable

uniform mat4 Gpu_ModelViewMatrix; // Modelview matrix
uniform mat4 Gpu_ProjectionMatrix; // Projection matrix
uniform mat3 Gpu_NormalMatrix; // 3x3 Modelview matrix inverse transpose

in vec3 Gpu_Vertex; // Vertices
in vec3 Gpu_Normal; // Normals
in vec4 Gpu_MultiTexCoord0; // Tangent
in vec4 Gpu_MultiTexCoord1; // Bitangent
in vec4 Gpu_Parameters; // Weight for texture splatting on terrain

// Variabiles out
out vec3 vertex_vout;
out vec3 depth_vout;
out vec3 normal_vout;
out vec2 texCoord_vout;
out vec3 tangent_vout;
out vec3 bitangent_vout;
out vec4 splatWeights_vout;

void main()
// Just transform everything to view space
vertex_vout = vec3(Gpu_ModelViewMatrix * vec4(Gpu_Vertex, 1.0));
depth_vout = vec3(Gpu_ModelViewMatrix * vec4(Gpu_Vertex, 1.0));
normal_vout = Gpu_NormalMatrix * Gpu_Normal;
tangent_vout = Gpu_NormalMatrix *;
bitangent_vout = Gpu_NormalMatrix * normalize(cross(Gpu_Normal,;
// Texcoords and texture splatting weights
texCoord_vout = vec2(Gpu_MultiTexCoord0.x, 1.0 - Gpu_MultiTexCoord0.y);
splatWeights_vout = Gpu_Parameters;

// Set position for clipping
gl_Position = Gpu_ProjectionMatrix * Gpu_ModelViewMatrix * vec4(Gpu_Vertex, 1.0);

Fragment shader

// GL 3.3, core, SM 4.0
#version 330
#define GL_core_profile 1
#extension GL_EXT_gpu_shader4 : enable

// Diffuse and normal textures
uniform sampler2D buffer_diffuse[4];
uniform sampler2D buffer_normals[4];

// Here goes everything in
in vec3 vertex_vout;
in vec3 depth_vout;
in vec3 normal_vout;
in vec2 texCoord_vout;
in vec3 tangent_vout;
in vec3 bitangent_vout;
in vec4 splatWeights_vout;

// Output according to GL 3.2/3.3 specs, like gl_FragData[]
out vec4 Gpu_FragColor[3];

void main()
// Depth for logarithmic depth buffer and also vertex for depth to pass to deferred shading pass
vec3 vertex = vert_vout;
float depth = dep_vout.z * -1.0;

// Splatting diffuse
vec4 diffuseTex = texture(buffer_diffuse[0], texCoord_vout) * splatWeights_vout.x;
diffuseTex += texture(buffer_diffuse[1], texCoord_vout) * splatWeights_vout.y;
diffuseTex += texture(buffer_diffuse[2], texCoord_vout) * splatWeights_vout.z;
diffuseTex += texture(buffer_diffuse[3], texCoord_vout) * splatWeights_vout.w;

// Splatting normals
mat3 tangentFrame = mat3(normalize(tangent_vout), -normalize(bitangent_vout), norm_vout);
vec3 normalTex = texture(buffer_normals[0], texCoord_vout).xyz * splatWeights_vout.x;
normalTex += texture(buffer_normals[1], texCoord_vout).xyz * splatWeights_vout.y;
normalTex += texture(buffer_normals[2], texCoord_vout).xyz * splatWeights_vout.z;
normalTex += texture(buffer_normals[3], texCoord_vout).xyz * splatWeights_vout.w;
normalTex = normalTex * 2.0 - 1.0;
vec3 normal_vs = normalize(tangentFrame * normalTex);

// Writing out depth for logarithmic depth buffer
gl_FragDepth = log(1.0 * depth + 1.0) / log(1.0 * 10000.0 + 1.0) * 1.0;
depth = vertex.z * -1.0;
// Writing out data, depth in r32f, normals in rgb10a2, color in rgb8 (ldr for now)
Gpu_FragColor[0] = vec4(depth, 0.0, 0.0, 1.0);
Gpu_FragColor[1] = vec4( * 0.5 + 0.5, 1.0);
Gpu_FragColor[2] = vec4(, 1.0);

They're older shaders, but good :) I have more complicated ones (much more), but these pretty much shows how to do splatting inside a shader.

Share this post

Link to post
Share on other sites
that's a good one but my card only support 4 texunit. I have a good technique, but only doable if what u said's true(that blending is done ine all RT).
1. make 3 RT(diff rgb, normal xyz, spec pow+intsty)
2. do splatting
3. collapse the third RT(move the data of 3rd RT to the previous 2 RT).


Share this post

Link to post
Share on other sites
Just 4 texunits? Wow, this seems strange - I think all cards today support at least 16 (NVidia and AMD). What card do you have?

Collapsing third RT into first two would need another MRT pass and shaders that will collapse it (which will probably end being slow - but I can't say, I've never tried it, maybe it's worth a try).

Share this post

Link to post
Share on other sites
well yes it needs another pass(a fullscreen pass with a quad covering the entire screen, only transferring data) so its not that expensive(altho fillrate intensive). well, u might be surprised but yes, only 4 texunit are supported on my geforce7300 gt :(

Share this post

Link to post
Share on other sites
So you got implementation running (of solution you've found)?

Btw. Have you considered buying new GPU (nowadays there are really cheap ones :P and good ones - Supporting up to GL 4.1 and DirectX 11, around EUR 150 - 200 in my country ... and I think there must be even cheaper ... though dunno how is it in your country with HW, I live in middle of Europe)?

Share this post

Link to post
Share on other sites
unfortunately I cant. here in Indonesia the cheapest u can get is $85 for sm4.0 card. besides, almost all people still rely on their dx9 card, so even if I buy new card, I cant force the to do the same. well I'll try implementing it @ weekend, as I dont have access to pc that support shader here :(

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this