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

Vertex Programming

Started by weasalmongler Oct 5, 2002 at 11:23 AM 15 replies 650+ views
Original Post
weasalmongler
weasalmongler
Hello all, I am trying to do dynamic lightmapping using vertex programs. I am using OpenGL''s Vertex Program and I wish to implement this using its scripting language:
  
texCoords.pos[0] = ((vert.pos[0]-m_lightPos.pos[0])/(m_brightness*2.0f))+0.5f;
	texCoords.pos[1] = ((vert.pos[1]-m_lightPos.pos[1])/(m_brightness*2.0f))+0.5f;
	texCoords.pos[2] = ((vert.pos[2]-m_lightPos.pos[2])/(m_brightness*2.0f))+0.5f;

	glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texCoords.pos[0], texCoords.pos[1]);	
	glMultiTexCoord2fARB(GL_TEXTURE1_ARB, texCoords.pos[2], 0.0f);
  
I have this so far:
  
unsigned char transform_pplight [] = 
		"!!VP1.0\n"
        "#Simple transform and calculating Lightmap positions\n"
		"#Params:\n"
		"#c[32] = Light Position\n"
		"#c[33] = Brightness * 2.0\n"
		"#c[34] = Constant +0.5\n"
        "\n"
		"DP4   o[HPOS].x, c[0], v[OPOS] ;	# object x MVP -> clip\n"
		"DP4   o[HPOS].y, c[1], v[OPOS] ;\n"
		"DP4   o[HPOS].z, c[2], v[OPOS] ;\n"
		"DP4   o[HPOS].w, c[3], v[OPOS] ;\n"
        "\n"
		"MOV   o[COL0], v[COL0] ;     # col = primary colour\n"
		"\n"
		"#Calculate Texture Coordinates of lightmap\n"
        "MOV   R0, v[OPOS];    #Vertex Pos\n"
        "MOV   R1, c[32];      #Light Pos\n"
		"ADD   R2, R0, -R1;    #Get Distance Vector\n"
		"RCP   R3, c[33]       #1/(Brightness*2)\n"
		"MUL   R4, R2, R3      #Distance/(Brightness*2)\n"
		"ADD   R5, R4, c[34]   #(Distance/(Brightness*2)+0.5\n"
		"MOV   o[TEX0].xy, R5.xy\n"
		"MOV   o[TEX1].x, R5.z\n"
		"END";
  
Unfortunatley the whole area is dark, but I can make out some things so its not completley black. Any help as to what I did wrong would be greatly appriciated. Thanks. - Weasalmongler
weasalmongler
weasalmongler
There has got to be someone out who knows about this? Please?

- Weasalmongler
coelurus
coelurus
I can't help you straight out, but perhaps a little?

The easiest way to fix vertex programs is to comment out all the critical parts (in the beginning, _everything_, except transformation). Then, add some operations one by one, like color-assign, then set the texture-coords to fixed values, then try to get the distane-vector right etc... It takes some work to get it to work right, but hey, who had the first person using vertex programs to ask?

[edited by - coelurus on October 6, 2002 12:30:51 PM]
Yann L
Yann L
I just flew over your source, and saw this: "RCP R3, c[33]". RCP expects a scalar as second parameter, try "RCP R3, c[33].x" instead. I''m not sure what happens if you specify a vector (never tried), it might default to x or the vertex program might not be accepted at all (more likely).

Oh and make sure, that all three components (xyz) of c[34] contain the 0.5 constant.
weasalmongler
weasalmongler
Thanks for helping guys... I am still trying, your suggestions didn''t work Yann, but thanks for the help . Anyone else willing to offer help would be much appriciated... but until that time I''ll keep fiddling, but its not easy

- Weasalmongler
davepermen
davepermen
you never use brightness*2 in your code, so why storing it as a constant? you only use 1/(brightness*2), so store this in c[33]..

code then:

        
!!VP1.0
#Simple transform and calculating Lightmap positions
#Params:
#c[32] = Light Position
#c[33] = 1/(Brightness * 2.0)
#c[34] = Constant + 0.5

DP4 o[HPOS].x, c[0], v[OPOS];# object x MVP -> clip
DP4 o[HPOS].y, c[1], v[OPOS];
DP4 o[HPOS].z, c[2], v[OPOS];
DP4 o[HPOS].w, c[3], v[OPOS];

MOV o[COL0], v[COL0]; # col = primary colour

#Calculate Texture Coordinates of lightmap
MOV R0, v[OPOS]; #Vertex Pos
MOV R1, c[32]; #Light Pos
ADD R2, R0, -R1; #Get Distance Vector
MUL R4, R2, c[33]; #Distance/(Brightness*2)
ADD R5, R4, c[34]; #(Distance/(Brightness*2)+0.5
MOV o[TEX0].xy, R5.xy;
MOV o[TEX1].x, R5.z;
END


and there where no ; behind the last 4 instructions..

btw, if you store 1/(brightness*2) and .5 in the same register, say like this:
c[33].x = 1/(brightness*2)
c[33].y = .5
then you can do it like that, i think:
MAD R5,R2,c[33].x,c[33].y;
saves another instruction..

and MOV R1,c[32] is useless as well..

optimized version (not 100% sure if it works, can't test here)


        
#Calculate Texture Coordinates of lightmap
MOV R0, v[OPOS]; #Vertex Pos
ADD R0, R0, -c[32]; #Get Point to Light Distance Vector
MAD R0, R0, c[33].x, c[33].y; #Distance/(Brightness*2)+0.5
MOV o[TEX0].xy, R0.xy;
MOV o[TEX1].x, R0.z;
END


hope it works now..

oh, and, you can get an error string report, that points to the faulty part of an invalid vertex_program. quite useful..

"take a look around" - limp bizkit
www.google.com

[edited by - davepermen on October 7, 2002 4:07:01 AM]
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia
My Page davepermen.net | My Music on Bandcamp and on Soundcloud
Yann L
Yann L
Yeah, his VP was very unoptimized. But I didn't suggest optimizations, as he only seem to begin with VPs. And how did that saying go: "First make it work, then optimize it".

Matter of fact is: VPs can be a bit confusing at the beginning. The problem is, that you can't always just take out your SW vertex computations and plug in the VP instead. Don't forget, that you lose things such as the texture matrix, clipplanes, etc.

Weasalmongler: OK, try this approach: First, take out the VP. Put in your own vertex code (running on the CPU) again. Make it work 100%. Then, replace it step by step with the vertex program, but do not modify the vertex array format yet (eg. still stream in your own texcoords, even if they are ignored in the VP. That way, you'll be able to pin-point the exact location of the error, without inducing additional bugs).

So at first, put only the matrix transform in the VP, all other properties (colours, texcoords, etc) are simply passed over from the vertex array streams. Basically, your VP is a no-op. If it doesn't work, then you have a major problem with your VP being accepted by the GL. Always check the value of GL_PROGRAM_ERROR_POSITION_(NV/ARB) after loading a VP, to see if it is valid. Or check GL_PROGRAM_ERROR_STRING_ARB.

If it works, replace a part of your texcoord computations, then the whole one. If everything works, you can take out your CPU based vertex code, and remove the remaining obsolete vertex streams (texcoords).

/ Yann

[edited by - Yann L on October 7, 2002 9:07:20 AM]
weasalmongler
weasalmongler
Thanks people . I already had done most of what you said Yann, but thanks . The only faulty part was really the Tex coord generator part. The rest worked I think. I did have a software version of it working and it worked fine, its just htis vertex program that Had me stumped. I have only just begun with these so thatnks for the help, I started about 4 days ago using em . I''ll go and try ur idea, and post again with the results. THanks again
weasalmongler
weasalmongler
Hmm, still doesn't work, even with the changes. I think I'm on to something though. What is a standard vector that you should pass to the vertex program. Is this a valid one?

vec(0.0f, 0.0f, 0.0f, 0.0f);

Or this?

vec(0.0f, 0.0f, 0.0f, 1.0f);

I am not sure what the difference is, but I think that some problems are occuring coz I am only writing to 2 of the parts of the output TEX0 and TEX1 registers, when they should all be written.

THanks

- WEasalmongler

EDIT: THis is weird.... If I do this:

MOV o[TEX0], v[TEX0];
MOV o[TEX1], v[TEX1];

I get the correct texture UV's (with white lines all over it for some reason :S) as they are generated by software. If I do this:

MOV o[TEX0].xy, v[TEX0].xy;
MOV o[TEX1].xy, v[TEX1].xy;

I get a black screen. Very odd... ANy help would be appriciated thanks.


[edited by - weasalmongler on October 7, 2002 6:52:36 PM]
Yann L
Yann L
OK, you MUST make sure that the .w component of the result texcoord registers is 1.0f, at least for normal (non-projective) texturing. Keep in mind, that the GPU will still perform the perspective division, ie. it will divide the .xyz components by .w after your vertex program. A value of 0 will yield an infinite texture coordinate (not good in your case).

What HW are you running on, and are you using the ARB or NV extension ? If you run on nVidia, the texcoord result registers will always be initialized to (0,0,0,1) by default. But that''s not necessarily the case of other hardware, and one should not rely on this nVidia default behaviour (as the ARB VP does not define a default value !).

/ Yann
weasalmongler
weasalmongler
I am on Windows XP, GeForce4 Ti4600. I am using NVidia Vertex PRograms, not the ARB equivalent. . THanks for that info, I was not sure what W was for.

- Weasalmongler
Yann L
Yann L
Yeah, should''ve guessed you were using the NV version from the source, duh, well it was late last night

If you''re on nVidia, .w *should* be initialized to 1. But from what you described, it seems that this is not the case. What happens, if you manually write 1.0f into both o[TEX0].w and o[TEX1].w ? BTW: o[TEX*].w is equivalent to the q-coordinate used in the normal fixed function pipeline.

And you''re sure you haven''t enabled 3D texturing, cubemaps or similar (which would require a valid .z component) ?
weasalmongler
weasalmongler
OK, I am not using 3D Textures, or Cubemaps. I am using Register Combiners for hardware lighting. I have made much progress, but I now have a small problem. Here is the code that works...


  

"!!VP1.0\n"
"#Simple transform and calculating Lightmap positions\n"
"#Params:\n"
"#c[32] = Light Position\n"
"#c[33] = 1.0f/(Brightness * 2.0)\n"
"#c[34] = Constant +0.5\n"
"\n"
"DP4 o[HPOS].x, c[0], v[OPOS] ; # object x MVP -> clip\n"
"DP4 o[HPOS].y, c[1], v[OPOS] ;\n"
"DP4 o[HPOS].z, c[2], v[OPOS] ;\n"
"DP4 o[HPOS].w, c[3], v[OPOS] ;\n"
"\n"
"MOV o[COL0], v[COL0] ; # col = primary colour\n"
"\n"
"#Calculate Texture Coordinates of lightmap\n"
"MOV R0, v[OPOS] ; #Vertex Pos\n"
"MOV R1, c[32]; #Light Pos\n"
"ADD R2, R0, -c[32] ; #Get Distance Vector\n"
"MUL R4, R2, c[33] ; #(Distance/(Brightness*2))\n"
"ADD R5, R4, c[34] ; #(Distance/(Brightness*2)+0.5\n"
"MOV o[TEX0].xy, R5 ;\n"
"MOV o[TEX1].x, R5.z ;\n"
"END";



The big problem is a graphics artifact on all the surfaces. THere are lots of varying width and direction white lines that are all over the surfaces. I am confused as to what causes them as it works without the Shaders... does anyone have an idea what could be causing it?

-Weasalmongler

P.S. THanks Yann, you are being really helpful, I am learning a lot.
Yann L
Yann L
quote:

The big problem is a graphics artifact on all the surfaces. THere are lots of varying width and direction white lines that are all over the surfaces. I am confused as to what causes them as it works without the Shaders... does anyone have an idea what could be causing it?


Weird. Define ''white lines all over the surfaces'', perhaps a screenshot will help. And it''s hard to guess the source of the problem, without knowing what algorithm you actually use (what kind of textures are we talking about, how''s the regcom pipeline set up, etc).
weasalmongler
weasalmongler
OK, I am putting together a little test program (I will be adding bump mapping soon I hope, but I need to sort this first). I have put what I have up on my teams artist''s webspace, so you can see the problem in action. Its a very small zip, about 418KB.

Program Illustrating Problem

As it is only a little test thing, I am not using anything special (make it work first.. then improve ). I have created my textures as GL_RGBA8. I am not using vertex arrays (I''ll add them once this works). I am using standard 2D texturing, nothing fancy. Thats why I am a bit confused as to why this artifact appears. I have got this program running in software without the vertex program and it runs fine... any help would be much appriciated THanks.

- Weasalmongler
weasalmongler
weasalmongler
OK, never mind, I was incredibly stupid. I had the depth buffer on when doing the second pass, so some parts were not drawn, sorry to waste your time . THanks for everyones help, you''ve been great.

- Weasalmongler
Yann L
Yann L
Hehe, OK

In fact, it explains why you got different results with the SW and the vertex program version. Without knowing, you run into an nVidia bug: NV_vertex_program has a different floating point accuracy behaviour than the fixed function pipeline.

You rendered the first pass with the fixed function pipeline, and the second one with the vertex program, right ? As the generated fragment depths of both passes will be slightly different due to the accuracy problem, the z comparison will fail and cause z-fighting. That''s why it is highly discouraged to mix the fixed function pipeline and NV_vertex_program on multiple passes of the same face.

NV_vertex_program1_1 solved this problem. Quoting the specs:


This extension also supports a position-invariant vertex program option. A vertex program is position-invariant when it generates the _exact_ same homogenuous position and window space position for a vertex as conventional OpenGL transformation (ignoring vertex blending and weighting).

By default, vertex programs are _not_ guaranteed to be position-invariant because there is no guarantee made that the way a vertex program might compute its homogenous position is exactly identical to the way conventional OpenGL transformation computes its homogenous positions. In a position-invariant vertex program, the homogeneous position (HPOS) is not output by the program. Instead, the OpenGL implementation is expected to compute the HPOS for position-invariant vertex programs in a manner exactly identical to how the homogenous position and window position are computed for a vertex by conventional OpenGL transformation. In this way position-invariant vertex programs guarantee correct multi-pass rendering semantics in cases where multiple passes are rendered and the second and subsequent passes use a GL_EQUAL depth test.


/ Yann

Topic Locked

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

Sign in to reply to this topic.