Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

blend

Started by mars_vertex May 20, 2012 at 4:10 AM 3 replies 1.4k views
Original Post
mars_vertex
mars_vertex

Multi-texturing can be implemented via blending using a multi-pass technique.

The idea is as follows: We draw the geometry once on the first pass with a base texture;

we then draw the geometry again with alpha blending enabled and a second texture,

where the alpha channel and blend operations specify how the secondary texture should be blended with the geometry drawn in the first pass;

we next draw the geometry again with alpha blending enabled and a third texture, where the alpha channel and blend operations specify how the third texture should be blended with the previously drawn geometry. We can keep doing this repeatedly, each pass layering on more and more details. The benefit of this technique is that you are not limited by any hardware restrictions that might limit how many textures you can sample simultaneously in a single pass. The downside of this technique is that it requires you to render the same geometry repeatedly



//=============================================================================
// pointlight.fx by Frank Luna (C) 2004 All Rights Reserved.
//
// Does ambient, diffuse, and specular lighting with a point light source.
//=============================================================================

uniform extern float4x4 gWorld;
uniform extern float4x4 gWorldInvTrans;
uniform extern float4x4 gWVP;
uniform extern float3 gEyePosW;
uniform extern float4 gAmbientMtrl;
uniform extern float4 gDiffuseMtrl;
uniform extern float4 gSpecMtrl;
uniform extern float gSpecPower;

uniform extern float4 gAmbientLight;
uniform extern float4 gDiffuseLight;
uniform extern float4 gSpecLight;
uniform extern float3 gLightVecW;
uniform extern texture gTex;
//uniform extern texture gTex1;
//uniform extern texture gTex2;
//uniform extern texture gTexBlend;
sampler TexS = sampler_state
{
Texture = <gTex>;
MinFilter = Anisotropic;
MagFilter = LINEAR;
MipFilter = LINEAR;
MaxAnisotropy = 8;
AddressU = wrap;
AddressV = wrap;
};
struct OutputVS
{
float4 posH : POSITION0;
float4 diffuse : COLOR0;
float4 spec : COLOR1;
float2 tiledTexC : TEXCOORD0;
};
OutputVS DirLightTexVS(float3 posL : POSITION0, float3 normalL : NORMAL0, float2 tex0 : TEXCOORD0)
{
// Zero out our output.
OutputVS outVS = (OutputVS)0;

// Transform normal to world space.
float3 normalW = mul(float4(normalL, 0.0f), gWorldInvTrans).xyz;
normalW = normalize(normalW);

// Transform vertex position to world space.
float3 posW = mul(float4(posL, 1.0f), gWorld).xyz;
// Ambient Light Computation.
float3 ambient = (gAmbientMtrl*gAmbientLight).rgb;

// Diffuse Light Computation.
float s = max(dot(normalW, gLightVecW), 0.0f);
float3 diffuse = s*(gDiffuseMtrl*gDiffuseLight).rgb;
// Specular Light Computation.
float3 toEyeW = normalize(gEyePosW - posW);
float3 reflectW = reflect(-gLightVecW, normalW);
float t = pow(max(dot(reflectW, toEyeW), 0.0f), gSpecPower);
float3 spec = t*(gSpecMtrl*gSpecLight).rgb;

outVS.diffuse.rgb = diffuse + ambient;
outVS.diffuse.a = gDiffuseMtrl.a;
outVS.spec = float4(spec,0.0f);

// Transform to homogeneous clip space.
outVS.posH = mul(float4(posL, 1.0f), gWVP);
outVS.tiledTexC = tex0*16.0f;
// Done--return the output.
return outVS;
}
float4 DirLightTexPS(float4 diffuse : color0, float4 spec : color1, float2 tileTexC : texcoord0) : COLOR
{
float3 c0 = tex2D(TexS, tileTexC).rgb;
return float4(c0 + spec.rgb, diffuse.a);
}
technique DirLightTexTech
{
pass P0
{
// Specify the vertex and pixel shader associated with this pass.
vertexShader = compile vs_3_0 DirLightTexVS();
pixelShader = compile ps_3_0 DirLightTexPS();
//fillmode = wireframe;
}
pass P1
{
vertexShader = compile vs_3_0 DirLightTexVS();
pixelShader = compile ps_3_0 DirLightTexPS();
AlphaBlendEnable = true;

SrcBlend = zero;
DestBlend = SrcColor;
BlendOp = Add;
}
pass P2
{
vertexShader = compile vs_3_0 DirLightTexVS();
pixelShader = compile ps_3_0 DirLightTexPS();
AlphaBlendEnable = true;

SrcBlend = zero;
DestBlend = SrcColor;
BlendOp = Add;
}
/*pass P3
{
vertexShader = compile vs_3_0 DirLightTexVS();
pixelShader = compile ps_3_0 DirLightTexPS();
AlphaTestEnable = true;
AlphaFunc = GreaterEqual;
AlphaRef = 220;
}*/
}



[color=#ff0000]How to realize this problem, I now have 3 texture, I added alpha channel for them, here is my HLSL code, but no, hope this helps

Nik02
Nik02
This is a bit of an outdated technique on modern hardware. Nowadays, you want to minimize the number of state changes and draw calls - the hardware can handle a large amount of simultaneous textures just fine.

Anyway, your blend states are incorrect, assuming I understood what you're trying to do. The "zero" factor means transparent black, not the color at the destination or source. http://msdn.microsof...8(v=vs.85).aspx
Niko Suni
mars_vertex
mars_vertex

This is a bit of an outdated technique on modern hardware. Nowadays, you want to minimize the number of state changes and draw calls - the hardware can handle a large amount of simultaneous textures just fine.

Anyway, your blend states are incorrect, assuming I understood what you're trying to do. The "zero" factor means transparent black, not the color at the destination or source. http://msdn.microsof...8(v=vs.85).aspx

Thank you for your advice, I just want to achieve this effect. As the consolidation of knowledge
Hardware can now also handle a lot of texture, so no need to remember is this technology do?

OutputPixel = SourcePixel ? SourceBlendFactor + DestPixel ? DestBlendFactor
OutputPixel = SourcePixel ? (0, 0, 0, 0) + DestPixel ? (1, 1, 1, 1)
OutputPixel = (0, 0, 0, 0) + DestPixel
OutputPixel = DestPixel

Textbooks are given examples, I think 0 does not necessarily mean that transparency is black?
TomKQT
TomKQT
What you are trying to do and how does your current result look like?

What I see is that in your 3 passes you are rendering always the same stuff, unless you are changing some variable(s) between the passes from your c++ code, which cannot be seen in your post.

Btw, the math in your last post doesn't correspond to your blending settings, it should rather be:

OutputPixel = SourcePixel ? SourceBlendFactor + DestPixel ? DestBlendFactor
OutputPixel = SourcePixel ? (0, 0, 0, 0) + DestPixel ? SourceColor
OutputPixel = DestPixel ? SourceColor

Which means that each pass multiplies its resulting color with the color already in the backbuffer and this product is written to the backbuffer. Whether this is right or wrong depends on what you are really trying to achieve.
mars_vertex
mars_vertex

What you are trying to do and how does your current result look like?

What I see is that in your 3 passes you are rendering always the same stuff, unless you are changing some variable(s) between the passes from your c++ code, which cannot be seen in your post.

Btw, the math in your last post doesn't correspond to your blending settings, it should rather be:

OutputPixel = SourcePixel ? SourceBlendFactor + DestPixel ? DestBlendFactor
OutputPixel = SourcePixel ? (0, 0, 0, 0) + DestPixel ? SourceColor
OutputPixel = DestPixel ? SourceColor

Which means that each pass multiplies its resulting color with the color already in the backbuffer and this product is written to the backbuffer. Whether this is right or wrong depends on what you are really trying to achieve.



I want the result is the three texture blending, each texture has his own alpha channel, were determined for each texture contribute to the number of pixels,
The final formation of the ground texture.In my c++ code, each pass using different texture and the corresponding matrix, essential to according to the different texture of different mixed, later because the test to write the same alpha test.
In front of me is a Blend mathematical representation, is to illustrate
Nik02: The "zero" factor means transparent black, not the color at the destination or source.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.