Forums
Shaders under OSX - Printable Version

+- Forums (https://www.vdrift.net/Forum)
+-- Forum: Project (https://www.vdrift.net/Forum/forumdisplay.php?fid=4)
+--- Forum: Development (https://www.vdrift.net/Forum/forumdisplay.php?fid=9)
+--- Thread: Shaders under OSX (/showthread.php?tid=916)



Shaders under OSX - aegidian - 02-25-2008

There seem to be a number of problems with the current shaders and Mac OS X's OpenGL drivers. I know that's why they are disabled in the current build and I thought I should investigate a little...

shaders with shadows: no gloss map, frame rate at 16fps.
[Image: badshaders.jpg]

shaders without shadows: gloss map okay, frame rate at 115fps.
[Image: badshaders2.jpg]

Number one is that shadowing and brake lights are not being correctly applied. Indeed the brake light texture seems to be being applied to the landscape, as well as being permanently 'ON' on the car. With the shadows ON the gloss map is also FU.

The second (IMO) more serious problem is that the glsl code is causing OpenGL to fall back to software rendering of the shader effects. This simply should not be happening,as the shaders in themselves are not at all complex. The 'full' fragment.glsl is definitely the culprit in this case.

I've played with this shader a bit and unwinding the loop, restriking the arrays as pairs of variables and moving variable declarations to the head of the block improve the framerate up to around 25-30fps, but something in there is still causing a major graphics pipeline problem.


Remedies:

1. clean up the code.

shaders/full/fragment.glsl is currently stuffed with comment cruft and should be cleaned and have more helpful comments added.

Arrays should be avoided and loops unrolled if possible.

2. look to the uniform variables - the brake light texture is being applied to the landscape - that shouldn't happen at all. The texture should be cleared or a different shader used for the car as distinct from the landscape.


Disclaimer:
My knowledge of shaders is based on the minimal work I did introducing them in Oolite, and reading around the problems of software fallback on the Apple lists. If I'm treading on anyone's toes in criticising their coding style, please don't take it personally. My code is also crap - often.

-- Giles.


- thelusiv - 02-25-2008

I'm not sure if I can add much to the shaders discussion, because I know almost nothing about them. However it strikes me that in your screenshots some of the fonts are off. It looks as if a different font is being used than the one we include for framerate, lap counter, and the numbers on the face of the tachometer. What's up with that?

Joe tends to leave a lot of comments behind when he codes, and I've cleaned up a ton of them for him in VDrift before, it's no big deal.

I'm interested in the cleanup work you've done on the shaders - I think we (Joe & I) as coders tend to think of unrolling loops and other kinds of optimization is best left up to the compiler - but maybe this kind of thing doesn't apply to shaders. (Again I'm more or less ignorant on the subject of shaders...)

In other threads discussing OS X issues with graphics, and falling back on software rendering, it has been mentioned that there are still problems with OS X's implementation of OpenGL 2.0. Are you sure the problems lie within the shader code and not within OS X? (More grains of salt with reading this: I don't have any Apple machines...)


- aegidian - 02-26-2008

thelusiv Wrote:I'm interested in the cleanup work you've done on the shaders - I think we (Joe & I) as coders tend to think of unrolling loops and other kinds of optimization is best left up to the compiler - but maybe this kind of thing doesn't apply to shaders. (Again I'm more or less ignorant on the subject of shaders...)

In other threads discussing OS X issues with graphics, and falling back on software rendering, it has been mentioned that there are still problems with OS X's implementation of OpenGL 2.0. Are you sure the problems lie within the shader code and not within OS X? (More grains of salt with reading this: I don't have any Apple machines...)

In the case of this code the arrays and loops consist of only two entries/iterations. It's unfortunate that different implementations of OpenGL (not just Apple's) treat optimisations in different ways.

In Apple's case there is a distinct problem with assigning heap space within loops or within conditional branches within GLSL, so unrolling these simple cases provides an instant fix.

I'll decruft the other shaders and see what I can do to fix full/fragment.glsl by comparing it with full-noshadow/fragment.glsl and see if Apple's software fallback can be prevented entirely without affecting the function of the shaders on other hardware. If I can manage this I'll put forward the patch.


Moving the variable declarations to the start of a code block is mostly just a style thing - it's what the orange book does. I only mention it because it helped me understand how the shaders worked and was part of the code that showed an increase in speed.


If I get a chance I'll also look at how the shaders are being used. I assume brake lights are working on other platform (I tried installing a windows XP version but haven't yet got the installation to work - more another time), so looking at how this is implemented may help clue me in to the problem.


Re: Shaders under OSX - abs1nth - 02-26-2008

aegidian Wrote:I know that's why they are disabled in the current build and I thought I should investigate a little...
they were only disabled because of the crash on non-opengl2.0 cards/drivers, which has been fixed, so my plan was to enable them on the next release again. they are on by default in the RC1.

aegidian Wrote:The second (IMO) more serious problem is that the glsl code is causing OpenGL to fall back to software rendering of the shader effects.
are you sure it falls back to software rendering? i'd think this would lead to framerates below 1fps, not 16.

i seem to remember something about a call that determines if the rendering currently is software or hardware - could be used to make sure...
i also seem to remember reading something on the apple opengl lists about a way to prevent software fallbacks, but since we are using SDL and not CGL directly this may not work.

leopards OpenGL drivers include a ton of previously unavailable features (even some that aren't even in the windows opengl drivers), but they are really alpha-state at best (not that tiger was much better anyway). i uncovered many simple ways to reproducibly freeze my machine while working on a simple demo for university. i also had issues with the for loop in glsl fucking everything up.


Re: Shaders under OSX - aegidian - 02-26-2008

abs1nth Wrote:
aegidian Wrote:I know that's why they are disabled in the current build and I thought I should investigate a little...
they were only disabled because of the crash on non-opengl2.0 cards/drivers, which has been fixed, so my plan was to enable them on the next release again. they are on by default in the RC1.

aegidian Wrote:The second (IMO) more serious problem is that the glsl code is causing OpenGL to fall back to software rendering of the shader effects.
are you sure it falls back to software rendering? i'd think this would lead to framerates below 1fps, not 16.

i seem to remember something about a call that determines if the rendering currently is software or hardware - could be used to make sure...
i also seem to remember reading something on the apple opengl lists about a way to prevent software fallbacks, but since we are using SDL and not CGL directly this may not work.

leopards OpenGL drivers include a ton of previously unavailable features (even some that aren't even in the windows opengl drivers), but they are really alpha-state at best (not that tiger was much better anyway). i uncovered many simple ways to reproducibly freeze my machine while working on a simple demo for university. i also had issues with the for loop in glsl fucking everything up.

Yeah, "software rendering of the shader effect". Basically the glsl effect is being done on the CPU rather than the GPU causing a massive slowdown in the rendering pipeline - and yes there's new stuff in leopard that lets you pre-flight shaders to determine if they're being done in the GPU or the CPU ('software fallback').

Also - if I can workout where SDL initialises the OpenGL context there's a NoRecovery flag that can be set that will disable any shaders that cause the fall back - stopping the situation from causing a drop in frame rates. This combined with the pre-flight of shaders would be the ideal all-round situation, but I think a simpler solution is more likely.


I suspect some of the problems I'm seeing may also stem from the texture units being handled differently. glBindTexture(some-texture-unit, 0) doesn't stop the brake-light texture from being rendered for example. Instead to fix this the self_illuminated uniform variable has to be reinstated in the graphics.cpp code and the shader code. even then it still shows up in the landscape as well as the car.


I still don't completely understand VDrift's graphic pipeline yet - I'm piecing stuff together as I work my way through the code. With luck - I may yet find some solutions to this.


- joevenzon - 02-26-2008

Feel free to really dig into the shaders and clean them up. Those shaders were some of the first I ever wrote, so I 1) didn't pay attention to optimization, just coding ease and 2) as I tried different things, I comment out a lot of broken code / wrong ideas and never bothered to remove them.

On your first screenshot, the reason it looks like there's no gloss map is because everything is always in shadow (no specular gets applied when in shadow). So, that's where the real problem is -- something to do with the shadow map lookup.

Also, the reason I had a loop for just 2 iterations was because adding more loops allows for more cascades of the shadow map (so you can get shadows rendered further and further away)... but I left it at 2 due to performance reasons. Still, it's fine if you unroll it.

The brake lights are turned off for other objects by selecting the texture unit and doing:
Code:
glBindTexture(GL_TEXTURE_2D,0);
On windows and linux this makes it so that texture lookups inside the shader yield all zeros. If it doesn't do that on Mac then we should pass in a uniform to the shader instead.

EDIT: I wrote this post this morning but forgot to hit submit. I see you already figured out the brake light thing. The graphics.cpp should be modified to pass in a float uniform for the self illumination, and then the shader should multiply the self illumination texture lookup result by that uniform float. It wouldn't take me very long to make this change but if you want the challenge I can leave it to you.

The VDrift graphics pipeline is self contained to graphics.cpp (which makes some calls to shader.cpp to deal with shaders). The game.cpp file just calls GRAPHICS::BeginScene(), GRAPHICS:Big GrinrawScene(), and GRAPHICS::EndScene(). You should be able to track through those functions and get the gist of it. Basically, if some other object wants to draw something it registers a drawable with the scenegraph and sets that up. The graphics.cpp code asks the scenegraph for drawables and then draws them... it's the only thing (that's supposed to be) doing any real calls to openGL.


- joevenzon - 03-01-2008

I made a couple of small changes to the full shader in the data SVN repository R161 -- just making the G channel of the misc1 texture contain information about how "metallic" the surface is, so it shouldn't conflict with what you're doing... but regardless, instead of having you submit a patch for the work you're doing here, how about I just set you up with SVN access to the data repository? That was SVN takes care of merging parallel changes. If you agree, post or PM your sourceforge username. Later if you need access to the source repository let me know.

By the way, oolite looks pretty cool. I love those sorts of games (Wing Commander: Privateer being a particular favorite).