PDA

View Full Version : OGL blending



yang11
01-08-2001, 12:54 PM
hi,
I am doing some real-time image processing using OGL and stuck by the blending function.

I need to compute the absolute difference between several images.
Iout = abs(I1-I2), or Iout = sqr(I1-I2).

Is there anyway to compute this completely in OGL, either using blending function or multi-texture£¿

any help is appreciated.

DFrey
01-08-2001, 02:03 PM
No, I think the closest blending mode available is GL_EXT_blend_subtract. But that simply subtracts and then clamps the output. And there aren't many consumer cards available that support that extension. And I don't know of any cards that support abs or sqrt in hardware. Then again, OpenGL really wasn't designed to do DSP.

[This message has been edited by DFrey (edited 01-08-2001).]

DFrey
01-08-2001, 02:15 PM
I just came to the realization that you can produce the abs of the difference in just a few passes on a Geforce, or any card that supports both GL_EXT_blend_minmax and GL_EXT_blend_subtract.

yang11
01-08-2001, 04:18 PM
I can think of doing this in several pass.

First render Iout1 = I1-I2
then render Iout2 = I2-I1,
then blend Iout1 and Iout2 using blending function blend_max

The only problem with this method is how to store the intermediate result Iout1. I really don't want to use glRead/Write pixel for bandwidth reasons. If multi-texture supports substraction, this seems to be a doable solution.

cass
01-08-2001, 05:49 PM
You can do this with NV_register_combiners to do the subtraction *AND* the clamped sum:



const0 = (0,0,0,1);
{
alpha
{
discard = tex0;
discard = tex1 * -const0;
spare0 = sum();
}
}
{
alpha
{
discard = tex0 * -const0;
discard = tex1;
spare1 = sum();
}
}
fragment.a = spare0 + spare1;


This works because spare0 and spare1 are clamped to the range [0,1] before the sum.

Hope this helps...
Cass

yang11
01-08-2001, 06:42 PM
Thank you for the reply.
I never used the register combiner myself.
My first question is that why discard is not clamped.

To be exact, I need to evaluate the following equation on a per pixel basis

Alpha = sum(abs(Ii-I0)), i= 1..4

Originally, I was think about doing this with the accumulation buffer.
Do you think it is possible to compute this with the register combiner?

Thanks lot!!!

cass
01-09-2001, 06:21 AM
Yang,

The register combiners work in the range [-1,1], and there's no absolute value. You can, however, calculate the absolute value of a difference as

abs(Ii-I0) = clamp(0,1, Ii-I0) + clamp(0,1, I0-Ii)

And you can calculate the sum by doing this in 4 passes with additive blending (glBlendFunc(GL_ONE,GL_ONE)).

I would encourage you to read the NV_register_combiners spec to better understand all the options available.

Hope this helps -
Cass

yang11
01-17-2001, 08:06 AM
hi, cass,
Thank you for your help.
I look through the NV_register_combiner spec.
I am not sure how to do the sum for the alpha value in the final combiner stage.
It seemed to me the G register is just a map from combiner register to the output.

Can I map a input register to more than one variables (say spare0 --> A and B) during the combiner stage?
I think I could compute (a-b)^2 this way.


thank you.

ruigang

cass
01-17-2001, 08:12 AM
Ugh. You're right. You can do this sum for the RGB, but not fragment alpha.

LordKronos
01-17-2001, 09:45 AM
Here is an alternative that MIGHT be acceptable.

in combiner 0 alpha, calculate tex0 + (1-tex1). Since tex0 & tex1 are in the 0 to 1 range, output is in the 0 to 2 range. Scale output by 1/2, and we now have it back into the 0 to 1 range. Store this in spare 0 alpha.

in combiner 1 alpha:
A = 1
B = spare 0 alpha - 0.5
C = -1
D = spare 0 alpha - 0.5
use the mux function and scale the output by 2. Store the result in spare 0 alpha

in the final combiner, select spare 0 alpha into G

If I figured everything correctly, this should get you the absolute value of tex0-tex1. The one thing to note here is that since we scale by 1/2 before storing to spare 0, you will lose some precision in the calculation (unless the register combiners' registers have at least 9 bits of preceission, and I cant remember if they do or not).

Tada!!!