Vertex programs w/multiple colored lightmaps

I’m probably being stupid and missing something obvious, but I’d like someone to confirm it for me. I’ve written a vertex program that does a fairly standard ‘toon/cel shading’ operation (l dot n = lookup in 1D shade texture). It works fine for multiple lights if I want to do 2 passes per light (1 pass lightmap, 1 pass diffuse texture).

Now I want to optimize a little, and minimize the number of passes depending on the number of texture units that a card has (2 on my card). I should be able to do 2 colored lightmaps in one pass, but I can’t figure out how to get the light color information for the second light into the VP.

The current method I’m using just moves the current color into o[COL0]. How do I get 2 colored lightmaps in one pass using the VP? o[COL1] doesn’t work how I would like, or I would just make the 2nd light color a program parameter.

Any ideas?

You could specify additional colors as texture coordinates. Since you are calculating texture coordinates for your 1D shade lookup, you could use the texcoords from that texture ( you are not using it already, are you ? ).

Hmm, just re-read your post. Are you saying you want to output more that one color ?

I use a 1D grayscale texture that goes from black to white (in 3 levels, to simulate toon shading). When I draw using a single light, it will mod by the current output color (COL0), giving me a colored lightmap. I want to be able to render 2 (differently) colored lightmaps in one pass via multitexturing. I can draw 2 lightmaps in one pass easily, but they’re both modulated by the same (current) color.

This isn’t a vertex program issue. This is a fragment issue.

What you are getting is, presumably, the following equation:

c0 * t0 * t1.

Where c0 is the color from COL0, and t0 and t1 are your textures.

I’m not sure I understand what it is you want as the output. Is it this?

c0 * t0 *c1 * t1

If so, you’ll need to use Register combiners to set this up.

BTW, what to these vertex colors mean, anyway?

I’m working on NPR too and managed multiple lights for cel shading.
I suggest you to first think of the way you want your lights to interact. If you are using only two lights you can easily do your lighting calculation with color0 and tex0 for first light and add the result with color1 and tex1 for your second light.
But if you want to manage some more lights you’ll have to think a better way to do this.
I manage up to 6 or 7 lights (which looks quite ugly for cel shading btw…) in a vertex program with only one texture unit.
If you’re interested i can send you the lighting model i’ve used, but i have to ask my boss first to see if isn’t confidential…

Hope this helps.
Joel.

Joel, that would be great - I’d love to see what you’re doing.

My problem isn’t really related to the cel shading itself, it’s a more general VP question. As Korval said, I basically want a (c0 * t0 * c1 * t1) output. I’m just not sure how to make c1 part of my output. I tried using a constant register to hold the second light color (to be blended for the current pass), and MOVing that value into o[COL1], but that doesn’t work properly. I’m sure it’s just me misunderstanding the use of COL1 within a VP.

Originally posted by nsg:
[b]Joel, that would be great - I’d love to see what you’re doing.

My problem isn’t really related to the cel shading itself, it’s a more general VP question. As Korval said, I basically want a (c0 * t0 * c1 * t1) output. I’m just not sure how to make c1 part of my output. I tried using a constant register to hold the second light color (to be blended for the current pass), and MOVing that value into o[COL1], but that doesn’t work properly. I’m sure it’s just me misunderstanding the use of COL1 within a VP.[/b]

At first i don’t think it’s c0 * t0 * c1 * t1 you should compute but rather c0 * t0 + c1 * t1. To do that you’d rather use register combiners. you compute c0 and c1 in the VP and compute you texture coordinate from the lights. Then you make the computation itself in the register combiners.
As I’m home now and won’t see my boss before monday, i’ll just give you the main idea of my method.
The thing is that you will use the same texture for both lights (i guess). So you can add the texture coordinate you are generating for the two (or more) lights and you will get the same result, without considering the colors, as you would by adding the two results from the two lights. In fact it will have some slight differences but they are IMO good.
Lte’s say you have a 3 tone texture with 50 150 and 255 for values. if you add the two cel shading from the lights you can get at some points 50 + 150. So you’ll get a value (200) that you shouldn’t have cause it is not in your texture. If you add the tex coord you are sure to have only the intensities you put in the texture.
Now for the colors i suggest you to add the color of the i’th light illuminating the object when your N.Li is positive. So you get c0*c1 where both lights are illuminating 0 where no lights hit the object and c0 or c1 only.
That’s the main idea. After you can see how you calculate c0 and c1 (basically it can be light diffuse color * object diffuse color).

Sorry i can’t give you the exact equation i use… but you should get good things from this.

Let me know if you want details on some part.
Joel.