Sign in to follow this  

shader questions

This topic is 4866 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi I was wondering if there were anything like an effect library of common effects to use--like a simple blur ps. The ones that ship with effectedit are pretty lame/limited. Also I was wondering how you might composite 2 effects? Like I have a Lighting VS and a Vertex Anim VS, and I want the animated vertices to be lit. Looking at the effects in the SDK samples, it seems like you have to manually combine 2 techniques, is it possible to sequence them somehow using the ID3DXEffect interface? Also I am curious but what would you recommend as the lowest level shader version that most cards support? Is ps_2_0 ok to make the bare minimum? I know I can query my caps, but I was wondering if there's a common wisdom on it, or a table somewhere of what cards support what shader versions. Thanks very much.

Share this post


Link to post
Share on other sites
I'm not aware of any shader effects libraries - the best I could suggest would be all the examples that come with the various shader editors out there, e.g. RenderMonkey, FX Composer etc.

To composite 2 effects like you're suggesting, no, I don't think there is any automated way. The best way I can think of is to write those two techniques into modular HLSL functions so you can just call them and have them return appropriate output.
If what you are asking is "can I use D3DX Effects to run two vertex shaders in sequence on one set of vertex data" I think the answer is unfortunately, no.

Hmm this is a tough one. There are a lot of ps_2_0 capable cards out there, but I think the amount that don't support it far outweigh this. If you're using D3DX Effects it's quite trivial to make fallback cases using the 'technique' abstraction. The minimum I target these days is ps_1_1, I also make a ps_2_0 version with improved quality. If the effect I am trying to do lends itself well to a ps_1_4 quality improvement, I might also do that to give the 8500 owners something extra.

It's worth noting that's one of the beauties of the Effects framework - you can write multiple levels of quality based on the hardware and very easily pick the best one at runtime to use.

-Mezz

Share this post


Link to post
Share on other sites
Quote:
Also I was wondering how you might composite 2 effects? Like I have a Lighting VS and a Vertex Anim VS, and I want the animated vertices to be lit. Looking at the effects in the SDK samples, it seems like you have to manually combine 2 techniques, is it possible to sequence them somehow using the ID3DXEffect interface?

AFAIK, you do one of the following:
- Combine them manually
- Use a modular approach as Mezz suggests. Put all your code into a file, include that file in your final shader, and use the functions you need.
- Use fragment linking. Check ID3DXFragmentLinker

Quote:
Also I am curious but what would you recommend as the lowest level shader version that most cards support? Is ps_2_ 0ok to make the bare minimum? I know I can query my caps, but I was wondering if there's a common wisdom on it, or a table somewhere of what cards support what shader versions.

(As far as I can remember)

nVidia:
Pre GF3 - no shader support
GF3 - vs1.1, ps1.1
GF4 - vs1.1, ps1.3
GFFX - vs/ps 2.0

ATi:
Pre Radeon 8500 - no shader support
Radeon 8500/9000/9100/9200 - vs1.1, ps1.4
Radeon 9600/9700/9800/X800 - vs/ps 2.0

Share this post


Link to post
Share on other sites
Quote:
Original post by turnpast
Couldn't you use multiple passes to apply different effects without manualy merging them?

Won't work for a lot of effects. Say you want to combine animation + lighting. You can't calculate lighting without knowing the animated position of the vertex, so you have to calculate that before doing lighting.

Share this post


Link to post
Share on other sites
We build our shaders out of about 100 available pieces using something similar to strcat, or more like sprintf.

We decided before hand where certain constants should go. We also decided what each v register would contain, and what each r register would hold. For example:

r0-r3 temp
r4 worldpos
r5 worldnormal, before lighting
r5 eyevector during/after lighting
r6 viewpos
r7 viewnormal
r8 halfvector
r9 stangent
r10 cumulative diffuse
r11 cumulative specular

Sometimes we reuse a register. For example, if we want worldpositions, we output them early (for an xz mapped lightmap for example), then in our lighting section we can reuse r4 to be use for the eyevector (viewpos normalized). We only needed to reuse 2 registers I think.

First we do a pass decided what strings to include and what constant reg offsets to use, then we do a concatenation and replacement pass on the collected data.

for example, in our first pass we might come up with:
worldxform_position_normal
outputworld
normalizenormal
transformposintoviewspace
transformnormalintoviewspace
calculatedepthandheightfog
calceyevector
calchalfangledirectional, lightreg=70
calcdirectionalwithspecular_set, lightreg=70
calchalfanglepoint, lightreg=73
calcpointwithspecular_add, lightreg=73
outputdiffusewithvertexalpha, dest="oD0"
outputspecular, dest="oD1"
outputuv, dest="oT0", src="v7"
xform_count2, dest="oT1", src="r7", xformreg=80

In the first pass we strive to include only the items that are needed. We do no fog, light, viewspace transforms, eyevector, or halfangle calculations if not needed. We ensure we do things in an order that work. We needed to do fog before we calculated the eyevector because we need world.y for height fog, and the eyevector shares a register with worldpos. We also identify optional source, destination, xformreg, and lightreg variables. We store the locations of xforms and lights so the renderer to can supply us data in the correct location.

In the second pass we look for magic tokens. %src%, %dest%, %L0%, %L1%, %X0%, %X1%, %A0%, %A1% and replace them. Ln becomes lightreg+n. Xn becomes xformreg+n An becomes [a0.x + xformreg+n]. We concatentate all the strings while replacing all the magic tokens, much like a big sprintf().

Notice, we specify destinations even when most people would think they're implied, such as for the lighting results. Why? Well, what if you want to use diffuse light as a UV for toon shading? Any output you might want for a UV, diffuse, or specular, we allow, to whichever register you'd like. They're all equal.

There are *many* possible pieces. For our world transforms alone, we have atleast 23 possible sections, and I can think of plenty of cases it doesn't cover...which is why we allow optional custom world code (for things like wind blowing trees), and a second set of custom code at the end (want some wacky UV calculation? Go for it).

We also opted to have two versions of each light code... the first light sets the light registers, while other lights add to it. We could have calculated to a temp register then moved or added, but it would have required an extra instruction per light. In addition to those two types, there are an additional two types, diffuseonly, or diffuse and specular.

For fog, we have 3 versions, for depth, height, or both.

In the end, it's a fair bit of work, but it's not rocket science. It allows us to build optimal context aware shaders (are texture transforms on? What type of transform? Which UV channels should we use? Do we need fog? How many pointlights? How many directional lights? Do we multiply by vertex color or material color?). It's the whole optimal and context aware part that FX files don't cover. Either you make a shader that does something specific, or you make a system to build shaders that do what you need them to do at the time.

Share this post


Link to post
Share on other sites

This topic is 4866 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this