View Full Version : OGL blending
01-08-2001, 12:54 PM
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.
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).]
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.
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.
You can do this with NV_register_combiners to do the subtraction *AND* the clamped sum:
const0 = (0,0,0,1);
discard = tex0;
discard = tex1 * -const0;
spare0 = sum();
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...
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?
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 -
01-17-2001, 08:06 AM
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.
Ugh. You're right. You can do this sum for the RGB, but not fragment alpha.
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).
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.