Pixel/vertexshaders in OpenGL or equivalent?

Is the regestry combiners in OGL capable of the stuff Nvidia is demonstrating with the DirectX 8’s pixel and vertexshaders. If so, is it hard to convert the effects to OGL? If not, is there any extensions to provide the same functionality?

Register combiners are very similar to pixel shaders, but there are some things that pixel shaders can do that register combiners can’t.

On a side note, hardware support for the DX8 pixel shaders is nonexistent right now. When NVIDIA hardware comes out that supports pixel shaders, there will be an OpenGL extension that has the same functionality.

j

gl_nv_vertex_program is equivalent of MS vertex shaders. I have a small working example of this extension (you need Detonator 7.17).

Originally posted by j:
Register combiners are very similar to pixel shaders, but there are some things that pixel shaders can do that register combiners can’t.

I prefer to look at it the other way around – there are things that register combiners can do that pixel shaders can’t. And those things that pixel shaders can do that register combiners can’t, aren’t available in HW today.

(Specifically, register combiners are better at doing per-pixel math to generate a final color, while pixel shaders support certain forms of dependent texture reads that are not available in any 3D HW today.)

  • Matt

i s it possible to do a full per-pixel lighting engine, even without specular, in real time?, using these combiner things?

You can do full per-pixel lighting, with specular.

Mark’s bumpdemo (torus) and md2shader (Quake 2 models) programs illustrate this.

  • Matt

really? i belive, but if that is so, why the per-pixel shader thing is reserved to geforce2, at least thats what i understand from the nvidia site.
all geforce based per-pixel operation demos i have seen so far, worked on my geforce pro ddr very very well.
is it a feature of all the geforce based cards?

[This message has been edited by okapota (edited 12-26-2000).]

Yes, all GeForce cards can do register combiners.

i learn how to use register combiners, and i see now, ok, a very very nice thing indeed.
not so complicated too.

[This message has been edited by okapota (edited 12-26-2000).]

NVIDIA will also be releasing a “register combiners parser” in the near future that allows you to set your combiners up with a configuration script. I say configuration script, because it’s not a program – it is simply a terse and unambiguous text-based description of combiner configuration.

There will be more details on this very soon, but for the time being, here are an example:

ParseRegisterCombiners(

  "    {                                                            

"
" rgb {
"
" spare0 = expand(tex0) . expand(tex1);
"
" }
"
" alpha {
"
" spare0 = unsigned_invert(tex1) * const0;
"
" }
"
" }
"
" {
"
" rgb {
"
" discard = spare0;
"
" discard = spare0.a;
"
" spare0 = sum();
"
" }
"
" }
"
" out.rgb = spare0;
"
" out.a = zero;
"
);
for (const char ** errors = GetRegisterCombinerParseErrors(); *errors; errors++)
fprintf(stderr, *errors);

I’ll post the equivalent NV_register_combiners code as soon as I get a chance. Anyone want to take a shot at the equivalent code before I post it?

Cass

[This message has been edited by cass (edited 12-27-2000).]

Cass, that sounds quite interesting !

Not that I don’t like the way we set up register combiners these days, but I think it is a bit complex (not difficult: complex !).

How will you expose this functionality ? An extension similar to NV_vertex_program ?

I won’t ask you when this will be available: I guess you aren’t allowed to answer !

Regards.

Eric

For now we’ll expose this by providing the header & lib. It was all built with flex and bison, so we may provide the parser source at some point too.

There’s been some discussion of making an extension like this, but for the time being,
it will remain a separate convenience library.

As for availability, Real Soon Now. It just needs a few things cleaned up, and the guy who’ll do that is out on vacation.

Thanks -
Cass

Originally posted by cass:
I’ll post the equivalent NV_register_combiners code as soon as I get a chance. Anyone want to take a shot at the equivalent code before I post it?

I’ll try:

glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 2);

glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_TEXTURE1_ARB, GL_EXPAND_NORMAL_NV, GL_RGB);
glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE);

glCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_A_NV, GL_TEXTURE1_ARB, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
glCombinerInputNV(GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_B_NV, GL_CONSTANT_COLOR0_NV, GL_SIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerOutputNV(GL_COMBINER0_NV, GL_ALPHA, GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);

glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_C_NV, GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
glCombinerOutputNV(GL_COMBINER1_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE);

glCombinerOutputNV(GL_COMBINER1_NV, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);

glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_ZERO, GL_SIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_ZERO, GL_SIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO, GL_SIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV(GL_VARIABLE_G_NV, GL_ZERO, GL_SIGNED_IDENTITY_NV, GL_ALPHA);

Possibly with GL_UNSIGNED_IDENTITY_NV instead of GL_SIGNED_IDENTITY_NV in a few places, and maybe a different final combiner arrangement.