Hard Light Productions Forums
Modding, Mission Design, and Coding => FS2 Open Coding - The Source Code Project (SCP) => Topic started by: Talon 1024 on October 29, 2007, 04:39:10 pm
-
I'm very curious about GLSL. I'm not sure if it works on my computer. Yes, I have upgraded my video drivers to the latest version and yes, I can see normal maps in FS2.
A few questions:
1. Is there a program I can use to test to see if my GLSL works?
2. How can I code these shaders, and more importantly, implement them into FS2?
-
If you can see normal maps in-game then you know that GLSL is working, since they aren't used otherwise. You can also check the debug log, in the OpenGL init section, as it will list the shaders that compiled and are in use, as well as giving a "Using GLSL" status.
When I get back home I'll post a set of the shaders that we use in the game now. You can then play around with these and see what sort of improvements/changes that you can make. One good thing to try out, whether you are a beginner or a pro, is ATI's RenderMonkey. That is basically an IDE for shaders, and gives you the ability to play around with what's possible, test out exsiting shaders, and see the results in real-time.
-
dont suppose you could plug a heat distortion shader into weapons and explosions?
-
Attached is the current shader set that the game has internally. You can just put these in data/effects/ and they will override the ones embedded in the game. The vertex shaders are in individual files since each one is paired up with multiple fragment shaders. By the time 3.7 gets here we will most likely have a different file format for these things, rather than a plain shader, so it will be easier to tell what is what.
The basic pairings for the shaders are like so:
b-vert.sdr (support for base only: "base" being defuse map, fogging and lighting)
b-frag.sdr - base
bg-frag.sdr - base+glow
bs-frag.sdr - base+spec
bgs-frag.sdr - base+glow+spec
bn-vert.sdr (support for base+normal)
bn-frag.sdr - base+normal
bgn-frag.sdr - base+glow+normal
bsn-frag.sdr - base+spec+normal
bgsn-frag.sdr - base+glow+spec+normal
bnh-frag.sdr - base+normal+height
bgnh-frag.sdr - base+glow+normal+height
bsnh-frag.sdr - base+spec+normal+height
bgsnh-frag.sdr base+glow+spec+normal+height
be-vert.sdr (support for base+env)
bse-frag.sdr - base+spec+env
bgse-frag.sdr - base+glow+spec+env
bne-vert.sdr (support for base+normal+env)
bsne-frag.sdr - base+spec+normal+env
bgsne-frag.sdr - base+glow+spec+normal+env
bsnhe-frag.sdr - base+spec+normal+height+env
bgsnhe-frag.sdr - base+glow+spec+normal+height+env
A bit convoluted, I know, but it's a method with the least amount of problems at this point. The code will be further tuned and rewritten as time goes on, so that we will have different shader sets for different detail levels and light settings. That will be a large number of shaders that will be created, but you will have maximum control of how much effects you want in exchange for the performance.
dont suppose you could plug a heat distortion shader into weapons and explosions?
Not until the material system. Right now we just don't have the ability to work with individual effects.
[attachment deleted by ninja]
-
so the materials system is not a myth then?
-
Hopefully Bobboau will complete what he has been working on previously, or offer a diff that someone else can work from. We need it either way though, so at some point a material system will be introduced, regardless of who writes it.
-
Argh. These shaders are a disaster. Shader Model 3.0 is required, so there's no chance of running them on radeons 9xxx. The specific implementation details vary from one card to another and some things may work on cards that do not support SM 3.0 just because, for example, the instruction limit is larger than required by standard. A quick run of cgc (nvidia's shader compiler) on the most basic vertex shader (b-vert.sdr):
./cgc -oglsl -profile vs_2_0 b-vert.sdr>/dev/null
(0) : error C6001: Temporary register limit of 12 exceeded; 14 registers needed to compile program
97 lines, 1 errors.
./cgc -oglsl -profile vs_2_x b-vert.sdr>/dev/null
(0) : error C6002: Instruction limit of 256 exceeded; 632 instructions needed to compile program
97 lines, 1 errors.
./cgc -oglsl -profile vs_3_0 b-vert.sdr>/dev/null
97 lines, 0 errors.
The instruction number seems way too high here.
At all cost avoid branching! Be aware that on SM 2.0 hardware the support for branching is done by calculating both paths and multiplying one result by 1 and the second one by 0 and then summing them up. Simple proof:
uniform float dotV;
void main()
{
float specLight;
if (dotV > 0.0) {
specLight = pow(dotV, gl_FrontMaterial.shininess);
} else {
specLight = 0.0;
}
gl_FragColor = vec4(0,0,0,specLight);
}
produces:
MOVR R0.y, {0}.x;
MOVR R0.x, {0};
MOVR R0.z, gl_FrontMaterial$shininess.x;
SGTRC HC.x, dotV, R0.y;
POWR R0.x(NE), dotV.x, R0.z;
MOVR o[COLR].w, R0.x;
MOVR o[COLR].xyz, {0}.x;
The equivalent shader that does not use branching
uniform float dotV;
void main()
{
float specLight;
specLight = pow(max(0.0,dotV), gl_FrontMaterial.shininess);
gl_FragColor = vec4(0,0,0,specLight);
}
produces the following code:
MOVR R0.x, {0};
MAXR R0.x, R0, dotV;
MOVR o[COLR].xyz, {0}.x;
POWR o[COLR].w, R0.x, gl_FrontMaterial$shininess.x;
The
if (i > n_lights) {
return;
}
in render_vertex_light() does not help at all on SM 2.0 hardware, because, as said earlier, all the following code will be calculated anyway.
All that branching should be removed ASAP.
-
I knew that SM3.0 was basically going to be a requirement with these, I just couldn't find a way around it. I have asked for help several times with these and not received anything that actually help get them more compatible. So, anything you can provide would be appreciated...
I was trying to avoid the pow() on the cards that didn't need it because it's so expensive of an operation. The cards that did need it weren't really going to get any benefit either way as far as I could tell, so I didn't really bother with it. I'm happy to change it if my reasoning is wrong though.
Regrading the "if (i > n_lights)" branch, I tried over a dozen ways to get all of that working, but that was the only way that worked on all of the test cards and didn't inccur a huge performance penalty on cards that actually did support branching. That is one thing that I fought with for quite a while, trying to come up with a way to make that not necessary. If you have another suggestion for making that work then I'd be more than happy to hear it.
-
I was trying to avoid the pow() on the cards that didn't need it because it's so expensive of an operation. The cards that did need it weren't really going to get any benefit either way as far as I could tell, so I didn't really bother with it. I'm happy to change it if my reasoning is wrong though.
Branching, even on SM 3.0 cards, should only be used when when the potential gains are big enough. It's definitely not wanted to avoid something as simple as pow(max()). I did some quick test (not using fs2, as it's capped at 120 fps) and I've got around 620 fps for shader using pow(max()) and around 550 fps for shader that did if(a<0) b=0 else b=pow(a).
Regrading the "if (i > n_lights)" branch, I tried over a dozen ways to get all of that working, but that was the only way that worked on all of the test cards and didn't inccur a huge performance penalty on cards that actually did support branching. That is one thing that I fought with for quite a while, trying to come up with a way to make that not necessary. If you have another suggestion for making that work then I'd be more than happy to hear it.
I think that the canonical way of overcoming this problem is either providing different shaders for different number of lights or generating shaders procedurally.
-
Branching, even on SM 3.0 cards, should only be used when when the potential gains are big enough. It's definitely not wanted to avoid something as simple as pow(max()). I did some quick test (not using fs2, as it's capped at 120 fps) and I've got around 620 fps for shader using pow(max()) and around 550 fps for shader that did if(a<0) b=0 else b=pow(a).
Hmm, then I was definitely on the wrong track there. I'll be sure to make the change for the next build then.
Oh, and you can use the -no_fps_capping cmdline option to disable the FPS cap if you want to test without any limit.
Regrading the "if (i > n_lights)" branch, I tried over a dozen ways to get all of that working, but that was the only way that worked on all of the test cards and didn't inccur a huge performance penalty on cards that actually did support branching. That is one thing that I fought with for quite a while, trying to come up with a way to make that not necessary. If you have another suggestion for making that work then I'd be more than happy to hear it.
I think that the canonical way of overcoming this problem is either providing different shaders for different number of lights or generating shaders procedurally.
The problem that we have, as I see it anyway, is that we don't have lightmap support so every light must be dynamic, and our renderer is so inefficient that we can't multi-pass render for lighting effectively. In order to keep the instruction limit low enough for SM2.0, we would only be able to render 3 lights in a single pass. I had started to work up extra shaders which would be for different number of lights, but it would only come at a significant cost to either performance or lighting effects (to the point of being a serious step back).
Since multiple passes are so expensive for us, and we need to support 8 lights at a minimum, it would absolutely kill performance. This isn't going to be a problem in 3.7 though, since I'm rewriting the code specifically to remedy this problem, but for now we have to choose which compromise to make. I decided to not worry so much about SM2.0 in order to keep the performance within exceptable limits. Some more changes will be made to 3.6.11 to speed things up and improve compatibility, but the biggest changes aren't likely to happen until 3.7.
I have searched for other options, but with the current engine limitations, I just couldn't see how to get the typical techniques used in modern engines to work for us. The FS2 code base simply wasn't written for this stuff to be feasible, and it's going to take more time to do all of the rewriting necessary to make it possible to do these things effectively.
-
Does this mean that changes to the shaders in future builds may make them more Radeon 9xxx compatible, or are those of us with those cards stuck without shader support?
-
Does this mean that changes to the shaders in future builds may make them more Radeon 9xxx compatible, or are those of us with those cards stuck without shader support?
Yes, future code will be far more compatible than what we have now. Even the code in code in 3.6.11 will be better than what we have now, though it may not be fully 9xxx compatible. We just need a place to start so that both developers and modders can get ready for the new capabilities of the engine. We don't have have the luxury of synchronizing our efforts and then releasing this stuff all at once, like commercial game developers can do, so we just have to introduce things bit by bit until everyone catches up.
The code in 3.7 will support pre/post-processing effects (like what is used for shadows, HDR), as well as both GLSL and Cg. That code will definitely be 9xxx compatible, even supporting lesser cards to some degree. It will also support shader complexity based on detail settings and hardware capabilities (sort of like Doom3+ games do). Less complex (and therefore faster) shaders would be used on lower LODs for greater performance, and that will also correlate with detail settings as well, so that you can get maximum performance/quality, depending on your own tastes.
-
What a shame. By the time I can run normal maps on my 9800, I won't be using it anymore. Oh well.
-
Well I'm working on something for the next build that you can at least test it with. It might suck for use in-mission (since it would have, at most, half the lights as normal), but in the lab and techroom it will show everything as you would expect. I'm doing this for all of the artists obviously, so that any of them with those slightly older cards will still be able to test out their content in the game without resorting to upgrading their hardware.
-
Thanks for taking the time to explain all that Taylor. Sounds good.
-
I know this is a somewhat big necro, but could you taylor, please explain what the material system is, what it should be, and which limitations does the engine have related to it?
-
Excuse my ignorance, but what is GLSL?
-
'GLSL' is what you google for to get here (http://www.google.com/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FGLSL&ei=3-i2SL_MDpSeNerNtPwC&usg=AFQjCNHfGfI84sh5xXivSorVSGJwpKOoPA&sig2=st50lAYbpKxg7rxBnRVdSg).
-
GL Shading Language. the stuff that brought us normal maps in short, for the ignorant.
-
I know this is a somewhat big necro, but could you taylor, please explain what the material system is, what it should be, and which limitations does the engine have related to it?
I guess taylor can explain it better, but let me explain how it matters to the artists.
We're currently using something what could be called a very basic material system.
It's possible to use special shaders, but it's defined by the maps used on the ship/model.
Most figthers are using the bgsn-frag.sdr (base+glow+spec+normal) shader.
If you now want the asteroids to look different, maybe by a lower glossiness, you'd have to use a different shader, or glossy setting than on the fighters.
A "real" material system will allow you to do that.
It should also allow using one map on multiple ships, even if they have different diffuse maps. That can help to lower the memory usage in some places.
So, you can select shaders and maps with a material system.