Shader implementation questions

Moderator
Posts: 1,140
Joined: 2005.07
Post: #1
I managed to test my demo program on a couple more machines at work today, and have noticed that my shaders seem to be very finicky. For example, on my boss' Mac mini (a PPC version with a Radeon 9200, running Mac OS X 10.3.9) the lighting portion of my shader didn't work at all, and my shadow extrusion shader didn't work either. (both vertex shaders, of course) (as a related note, the cube mapping didn't work, with each of the cube map textures being 1024x1024, which is within its specified boundaries, and for some reason it completely ignored one of my calls to glColor4f() until I changed a way it was rendered; once I changed it back to the way it was, it continued to work fine)

On my coworker's PowerBook (with a Radeon Mobility 9700 and Mac OS X 10.3.9), the shaders mostly worked. However, on the first redraw after enabling them, the colors would be completely off before coming back to what it should be. On some areas (mainly the collision detection area), however, the colors would remain completely off all the time.

On my computer at home (with a Radeon X800 and running Mac OS X 10.4.6), everything works 100%. However, when I was working on my sphere map and cube map shaders, the appearance of where the texture coordinates would appear would change based on where I put a certain block of code. (and where I was moving it to didn't effect any of the dependancies of any part of the code)

All of my shaders are assembly shaders, since I would prefer to continue to support Panther. Are the implementations of assembly shaders unreliable? Is GLSL any better in this area since it's higher level and the "official" shader for OpenGL? I was avoiding GLSL since, as I said, I wanted to continue support for Panther, but if assembly shaders are truly that fickle I guess I won't have much of a choice. Annoyed
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
First, please use the correct OpenGL terminology:

A shader is written in GLSL.
A program is written in a low level assembly. This is usually the language defined by ARB_vertex_program or ARB_fragment_program, although there are other languages such as ATI_text_fragment_shader.

akb825 Wrote:my shaders seem to be very finicky.
...Radeon 9200...
...Radeon Mobility 9700...
...Radeon X800...

These are all very different pieces of hardware, with different limits. It is possible to write programs that will work on the latter two and not the first, by using too many instructions or variables. Shader Builder has some handy little progress bars on the lower left that indicate how close you are to exceeding the limits of the renderer you're developing on (obviously you should develop and test on the lowest-spec machine you intend to support.) You can query these limits and check if your program exceeded them programmatically at run time via glGetProgramivARB(). Limits for all renderers Apple has shipped as of 10.4.3 are listed here (check the block starting with MAX_PROGRAM_ADDRESS_REGISTERS_ARB).

Quote:...for some reason it completely ignored one of my calls to glColor4f()
When you enable a vertex program, you are bypassing the fixed function pipeline. It is up to your program to perform all transformation and output all required attributes (position, color, normal, etc) to the fragment stage.

Quote:Are the implementations of assembly shaders unreliable?
No, they are used by many shipping applications. Read all the specifications I linked above to learn more about them.

Quote:I would prefer to continue to support Panther. Is GLSL any better in this area since it's higher level and the "official" shader for OpenGL?
GLSL is not supported in Panther.

Assembly-level shaders may or may not work depending on the capabilities of the video card the user has.

GLSL does ensure that your shaders will always run, no matter how insufficient your video card is. It doesn't guarantee anything about how fast they will run, though.
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #3
I believe a bit of clarification is in order. (sorry I wasn't too clear on a few parts) First of all, I already checked the length of all my shaders. The longest one I have is 36 instructions, and never used any address registers.

I should have been a little more specific when I talked about ignoring the call to glColor4f, this was actually before I enabled the shaders. Nothing else wrong with the rendering happened, just that. I don't think I messed up with anything setting anything up etc., but I don't know what could have caused it since this happened only with one particular object, and the rest of the colors were correct.

Anyways, to the last part, does the "depending on capabilities" include things such as the order of instructions? Especially since at one point I changed the order, when it didn't change any dependancies, it it changed the output of my shader somewhat. (specifically, it changed how a sphere map looked)

Here are the max attributes used for any of my shaders: 0 address registers, 5 attributes, 36 instructions, 18 parameters, and 6 temporaries. As you can see, all these are well within the specified limits of even the lowly 9200. In case you want to look at them, here's the shaders I generate. (they probably aren't the most efficient, but I was going for what worked as a proof of concept rather than most efficient)

My shader that just calculates lighting takes the original texture coordinates:
Quote:!!ARBvp1.0
TEMP eyePosition, normal;
TEMP LITparams;
TEMP tempLight;
PARAM modelview[4] = {state.matrix.modelview};
PARAM projection[4] = {state.matrix.projection};
PARAM mvInvtrans[4] = {state.matrix.modelview.invtrans};

DP4 eyePosition.x, vertex.position, modelview[0];
DP4 eyePosition.y, vertex.position, modelview[1];
DP4 eyePosition.z, vertex.position, modelview[2];
DP4 eyePosition.w, vertex.position, modelview[3];
#transform the normal
DP3 normal.x, mvInvtrans[0], vertex.normal;
DP3 normal.y, mvInvtrans[1], vertex.normal;
DP3 normal.z, mvInvtrans[2], vertex.normal;
DP3 normal.w, normal, normal;
RSQ normal.w, normal.w;
MUL normal, normal, normal.w;
DP4 result.position.x, eyePosition, projection[0];
DP4 result.position.y, eyePosition, projection[1];
DP4 result.position.z, eyePosition, projection[2];
DP4 result.position.w, eyePosition, projection[3];
#lighting calculations
DP3 LITparams.x, normal, state.light[0].position;
DP3 LITparams.y, normal, state.light[0].half;
MOV LITparams.w, state.material.shininess.x;
LIT LITparams, LITparams;
TEMP diffuse, ambient;
MUL diffuse, vertex.color, state.light[0].diffuse;
MUL ambient, vertex.color, state.material.ambient;
MAD tempLight, LITparams.y, diffuse, ambient;
MAD result.color.xyz, LITparams.z, state.lightprod[0].specular, tempLight;
MOV result.color.w, vertex.color.primary.w;
MOV result.texcoord[0], vertex.texcoord[0];
MOV result.texcoord[1], vertex.texcoord[1];
END

My shader that does lighting and calculates cube mapped texture coordinates
Quote:!!ARBvp1.0
TEMP eyePosition, normal;
TEMP LITparams;
TEMP tempLight;
PARAM modelview[4] = {state.matrix.modelview};
PARAM projection[4] = {state.matrix.projection};
PARAM mvInvtrans[4] = {state.matrix.modelview.invtrans};

DP4 eyePosition.x, vertex.position, modelview[0];
DP4 eyePosition.y, vertex.position, modelview[1];
DP4 eyePosition.z, vertex.position, modelview[2];
DP4 eyePosition.w, vertex.position, modelview[3];
#transform the normal
DP3 normal.x, mvInvtrans[0], vertex.normal;
DP3 normal.y, mvInvtrans[1], vertex.normal;
DP3 normal.z, mvInvtrans[2], vertex.normal;
DP3 normal.w, normal, normal;
RSQ normal.w, normal.w;
MUL normal, normal, normal.w;
DP4 result.position.x, eyePosition, projection[0];
DP4 result.position.y, eyePosition, projection[1];
DP4 result.position.z, eyePosition, projection[2];
DP4 result.position.w, eyePosition, projection[3];
#lighting calculations
DP3 LITparams.x, normal, state.light[0].position;
DP3 LITparams.y, normal, state.light[0].half;
MOV LITparams.w, state.material.shininess.x;
LIT LITparams, LITparams;
TEMP diffuse, ambient;
MUL diffuse, vertex.color, state.light[0].diffuse;
MUL ambient, vertex.color, state.material.ambient;
MAD tempLight, LITparams.y, diffuse, ambient;
MAD result.color.xyz, LITparams.z, state.lightprod[0].specular, tempLight;
MOV result.color.w, vertex.color.primary.w;
TEMP mnkyNormalizedEyePosition;
DP4 mnkyNormalizedEyePosition, eyePosition, eyePosition;
RSQ mnkyNormalizedEyePosition, mnkyNormalizedEyePosition.x;
MUL mnkyNormalizedEyePosition, eyePosition, mnkyNormalizedEyePosition;
TEMP mnkyR;
DP4 mnkyR, mnkyNormalizedEyePosition, normal;
MUL mnkyR, mnkyR, 2;
MUL mnkyR, mnkyR, normal;
SUB mnkyR, mnkyNormalizedEyePosition, mnkyR;
DP4 mnkyR, mnkyNormalizedEyePosition, normal;
MUL mnkyR, mnkyR, 2;
MUL mnkyR, mnkyR, normal;
SUB result.texcoord[0], mnkyNormalizedEyePosition, mnkyR;
MOV result.texcoord[1], vertex.texcoord[1];
END

My shader to extrude shadows:
Quote:!!ARBvp1.0

TEMP amount;
TEMP normal;
TEMP light;
ATTRIB vertexNormal = vertex.normal;
MOV light, state.light[0].position;

#normalize the light
TEMP lightLength;
DP3 lightLength, light, light;
RSQ lightLength, lightLength.x;
MUL light, light, lightLength.x;

TEMP modelview[4];
MOV modelview[0], state.matrix.modelview.row[0];
MOV modelview[1], state.matrix.modelview.row[1];
MOV modelview[2], state.matrix.modelview.row[2];
MOV modelview[3], state.matrix.modelview.row[3];
PARAM projection[4] = {state.matrix.projection};
PARAM mvInvtrans[4] = {state.matrix.modelview.invtrans};

#transform the normal
DP3 normal.x, mvInvtrans[0], vertexNormal;
DP3 normal.y, mvInvtrans[1], vertexNormal;
DP3 normal.z, mvInvtrans[2], vertexNormal;

MOV result.color, vertex.color;

#check the dot product of the light vector and the vertex normal
TEMP dotProduct;
DP3 dotProduct, normal, light;
#make it 1 or 0
TEMP direction;
SLT dotProduct, dotProduct, 0;

MUL direction, light, program.local[0];
MUL direction, direction, dotProduct;
MOV direction.w, 0;
SUB modelview[0].w, modelview[0].w, direction.x;
SUB modelview[1].w, modelview[1].w, direction.y;
SUB modelview[2].w, modelview[2].w, direction.z;

#transform the position to view coordinates
TEMP position;
DP4 position.x, vertex.position, modelview[0];
DP4 position.y, vertex.position, modelview[1];
DP4 position.z, vertex.position, modelview[2];
DP4 position.w, vertex.position, modelview[3];
RCP position.w, position.w;
MUL position, position, position.w;
MOV position.w, 1;

DP4 result.position.x, position, projection[0];
DP4 result.position.y, position, projection[1];
DP4 result.position.z, position, projection[2];
DP4 result.position.w, position, projection[3];

END

I am glad to see that GLSL is guaranteed to work, though I suppose these are supposed to work as well. Annoyed (I did know that GLSL doesn't work in Panther, though, since I said that was why I was shying away from it Rasp)

Thanks for your help. Hopefully I'll be able to get to the bottom of this Annoyed
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #4
Come on, no input from anybody? This is something that I'd like to be able to get fixed, since I don't really want to release a framework with shader support... where the shaders won't work correctly on half the hardware for unknown reasons. Sad
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #5
Either you or Apple have bugs. If they're your bugs, fix them. If they're Apple's bugs, report them. What more do you expect us to say, from the information you've given us?
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #6
I guess I may have done my ambient lighting wrong, which explains some of the incorrect coloring. (I guess differences in implementation of OpenGL can explain the small differences between my co-worker's PowerBook and my PowerMac) None of the shaders worked correctly on my Boss' mini, period. The lighting doesn't work at all, it's as if the LIT command didn't do anything. However, I suppose that could also be yet another difference caused by my ambient lighting Also, the extrusion doesn't work at all. Since it was one of my first shaders that I used left over, I can re-write it and try it again on Monday. Hopefully I'll be able to fix this. Annoyed
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #7
Here's one suggestion (this may be a real bug in the ATI driver):

change
LIT LITparams, LITparams;
to
TEMP littemp;
LIT littemp, LITparams;
MOV LITparams, littemp;
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #8
Makes sense, thanks for the tip. I put it up on another forum for testers after I changed how I handled ambient lighting, and so far no problems. If I encounter any more problems with it, that will be my next change. (I'll know for sure as soon as somebody with a Radeon 9200 posts or on Friday when I can test it on my Boss' mini)
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #9
Ok, it turns out that this line was the problem on the Radeon 9200s:
MUL normal, normal, normal.w;

However, there's another problem just on the Radeon 9200. (God, I'm starting to hate that card) Here's some screens of what it looks like. (it happens for all tests, not just the cube map)
http://homepage.mac.com/noexit/3d/Picture1.png
http://homepage.mac.com/noexit/3d/Picture2.png

So apparently it's ignoring the colors for vertices that are off screen. Any ideas on how I can fix this problem? Or is this a bug I can't get around? (though it seems kind of glaring, so you'd think it would be easy to get around if it's still there; funny thing is, somebody with a Radeon 9000 reported no problems... you'd think they'd be similar in problems as well as abilities being the same generation etc.)
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #10
I seem to recall there being a discussion of that particular bug on the mac-opengl list a while back. You might try searching the archives.
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #11
Thanks for the tip. So far I found a couple mentions, but no replies to those posts, so hopefully I'll find one with a solution if I keep searching.

Edit: bah, I tried every combination I could think of, and none of the mentions had a reply dealing with them. Somebody else with a mini replied and said there was no problem, so it may be OS-specific. After a bit more testing and research, I'll probably be sending a bug report to Apple. (along with the MUL with a swivel on same variable bug)
Quote this message in a reply
schnarr
Unregistered
 
Post: #12
I wonder if the 9200ME problem is because ATI does not support arbfp1 on the 9200 series, only atifs, which I read has a DX-like syntax. I suspect that even more because vertex programs work fine (and the ARB vertex profile is supported).

I see the same problem trying to run a GLSL program on that card, however, which I think should be using the software driver, so I'm not completely sure. I need to experiment more now - I had given up figuring my CPU just couldn't handle it, but I also was under the impression that the 9200 didn't support fragment shaders at all until reading that they did on ATI's site (OGL reports that no fragment shaders are supported, but I didn't check extensions).
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #13
No fragment shaders were used: only vertex shaders. Besides, somebody with a Radeon 9000 said it worked, which supports the same shaders as the 9200.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  ios/mac shader - shared glsl source OptimisticMonkey 2 5,021 Jun 17, 2011 08:59 AM
Last Post: OptimisticMonkey
  passing values from vertex to fragment shader Sumaleth 6 10,272 Feb 18, 2011 01:54 AM
Last Post: Holmes
  Changing Uniform Variables for a Single Shader reapz 3 5,216 Jul 15, 2010 01:29 AM
Last Post: dazza
  Suggestions for Sound Implementation soulstorm 15 7,028 May 15, 2009 07:54 PM
Last Post: Gillissie
  Vertex shader particle billboarding question TomorrowPlusX 3 5,378 Sep 15, 2008 06:46 AM
Last Post: TomorrowPlusX