Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

KevinCoyle

Per-Pixel Lighting with Pixel shaders

This topic is 5157 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

First off I want to appologize for the long post, hopefully it won't turn people off to helping me out. In my engine, I'm currently using vertex lighting, I am not happy with it for several reasons. I have to tessellate my scene geometry to be lit decently, seams between seperate objects are obvious and it looks generally outdated. Here is a current screenshot of how the engine looks, the aspects I'm disatisfied with are apparent in the image. http://www.babylonius.com/invasion/scene3.jpg I'm looking into per-pixel lighting methods. I've researched light-mapping but it looks very complicated to generate the lightmaps, store them and map them onto the scene geometry, and they're limited to static lighting for the most part. I've also looked into pixel shaders for per-pixel lighting, this seems like the best bet because it will allow me to have smooth lighting with specular highlights and bump mapping too. I've run through a few tutorials (online and in my "Managed Directx 9 Kick Start" book), and I'm beginning to understand it but there are still several things I'm confused about. Most of the tutorials I've looked at deal with applying light and an effect to one object, like directional lighting on the earth with bumpmapping on it, or a teapot with specular highlights. One book I have explains per-pixel lighting a bit but it's a little outdated, it mentions that per-pixel lighting isn't really practical because you run out of texture stage states with more then 1 or 2 lights in your scene, which I know can't be true cause Doom3 and Far cry use per-pixel lighting. It also uses the old asm-like shader language and I prefer HLSL. So essentially what I'm looking to understand is how to setup a scene with multiple lights and effects. Those tutorials I looked at used 1 pixel shader with a directional light and some kind of surface effect, like specular highlighting, or bump mapping. But what if I wanted a scene with many lights with some objects bump mapped, others shiny, and others with just regular diffuse lighting. say I wanted 8 lights, would I create a pixel shader with those 8 light calculations in it? then create another pixel shader for 8 lights with bumpmapping for those objects an yet another pixel shader with 8 likes for specular objects? Or something else? I'm probably way-off since it still doesn't make sense to me how to use pixel shaders in a complex scene. Any help on this subject will be greatly appreciated, as well as any links to good tutorials on per-pixel lighting with HLSL. thanks, hope the post wasn't too long-winded for everyone but I wanted to make sure I explained my confusion. [edited by - KevinCoyle on May 6, 2004 12:46:48 AM]

Share this post


Link to post
Share on other sites
Advertisement
I wish I could answer your question. I don''t know much about per pixel lighting. Here''s a link that I think could help you:

http://esprit.campus.luth.se/~humus/

He has many demos with source on his site some of which use per pixel lighting. Perhaps you can look at the source and gain insight?

~Wave

Share this post


Link to post
Share on other sites
I''ll try to reply with what I know, which isnt much.

lightmaps: Nowadays shaders gives us developers a lot of power, but I still think that old tricks die hard If there is a situation in your engine where lightmaps will yeld decent results with inexpensive processing, then go ahead and research it/ implement it.

Also, there isnt an "old asm-like shader language", not yet, because shading is so recent. HLSL gets compiled into asm. Taking a few minutes to look at asm files you''ll be able to read them and make out what they''re doing.

Now, regarding per-pixel lighting, you have to setup your vertex shader so that it passes the data forward to a pixel shader. The shading then gets interpolated at pixel-level instead of at the vertex-level.

Things that where calculated in the vertex shader, like:
D = dot(normal, lightPosvector);

...now get calculated in the pixel shader.

Regarding multiple lights per scene, I think that if you''re using the most recent shader capabilities, you''ll be able to do loops, especially in nVidia hardware, as they implemented more features into their Shaders earlier.

With loops you can loop a certain part of the shader n times for each light.

With "if_thens" you can process the shader for multiple situations, ex:
// Surface Parameters are passed in Kp[0]
// If surface is bumpmaped then Kp[0] is 3
if(Kp[0]==3)
{
// Do bumpmap calculations
};

So, with "if_thens" you can insert as many types of surfaces you want on the same pixel shader file, size permiting.

The "static" version of this means that you will have to have at least 1 shader file per number of lights per scene, ex:
difuse_1Light.Cg
difuse_2Lights.Cg
(...)

Regarding making "if_then" shaders static, you''ll have to query the object''s properties first. If it will be rendered using bumpmap effects, then you get the apropriate shader for it, and enable it, then flush the geometry to the graphics board.

So, try to radix-sort your objects per effect too, so that you don''t have too many state changes on the shaders...

So, the vertex shader might be the same for all your effects, but your pixel shader files will change per effect I think.

I hope I cleared up some of your doubts

Salsa cooked it, your eyes eat it!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD][My DevDiary]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"our stupidity allways comes back to bite us in the ass... in a white-shark sort of way..." - Prozak

Share this post


Link to post
Share on other sites
Thanks for the replys guys. You've definatly helped clear some things up for me. I've been messing around with per-pixel lighting some more and now have a per-pixel directional diffuse light shader on my scene model and a per-pixel directional specular shader on the bars and a teapot I put in there just for testing. here are some screens

http://www.babylonius.com/invasion/scene5.jpg

http://www.babylonius.com/invasion/scene4.jpg

What I'd like to achieve next is a per-pixel point light shader. I've found some informaton on that but it's almost always coupled with bump-mapping of some sort, I'd like to just focus on simplier lighting and work with bump-mapping later down the road. Anyone know any tutorials on creating a per-pixel point light? HLSL c# is preferable but asm c++ will be just fine too. thanks

[edited by - KevinCoyle on May 7, 2004 3:30:52 PM]

[edited by - KevinCoyle on May 7, 2004 3:31:17 PM]

Share this post


Link to post
Share on other sites
I''ve implemented a system where I have 0-4 lights in a scene, with 1 light being a per pixel light. The results, using a FX 5700 and ps_2_0 are interesting. If I fill up the backbuffer entirely with lighted pixels, my FR drops to about 90, it was 78ish before I used cube maps for normalization. This is definatly a fill rate bound operation. I''m going to remain neutral until I get more in my scene. (Working on a method to get shadow maps working with point lights =/)

You mention tesselation problems with vert lighting, but I am not sure that''s as much of a deal nowadays, I render scenes with 60k+ polys no problem, on an average vid card. What kind of poly counts/FR are you getting with those screenshots? The lighting does look a little tesselated, but it''s my opinion that sometimes it''s better to increase vert counts as opposed to pixel lighting, especially if you are planning on doing other per pixel operations such as bump mapping.

I think the days of 300 poly models are long gone, and vert lighting looks pretty good on decent poly count models. My terrain is a little tesselated, but I use lightmaps for terrain, which I recalculate every 10 frames or so. I am working with outdoor terrain tho, so I can see where that would be a problem for your indoor scenes.

Anyways, I''m interested in your results, so please keep us imformed =)

-Shawn

Share this post


Link to post
Share on other sites
Wow guys, really cool discussion here.

I had a quick question. I haven''t used any shaders yet, but I am looking to learn.

Using the dot product from the light source is it possible to make everything darker by default, so the light stands out more?

Cheers, thanks in advance for your responses.

Share this post


Link to post
Share on other sites
quote:
say I wanted 8 lights, would I create a pixel shader with those 8 light calculations in it? then create another pixel shader for 8 lights with bumpmapping for those objects an yet another pixel shader with 8 likes for specular objects? Or something else? I''m probably way-off since it still doesn''t make sense to me how to use pixel shaders in a complex scene. Any help on this subject will be greatly appreciated, as well as any links to good tutorials on per-pixel lighting with HLSL.

That''s a hairy topic. You can handle complex scenes in two ways:
1) Use hand-written shaders. For every possibly technique permutation, write a set of shaders. This is hairy, and gets out of control fast.
2) Use a shader generation system.
Using HLSL, you can have a function that just implements the diffuse reflection model, i.e. It takes a normal, a surface color, a light color, and a light vector, and performs a clamped dot product between the two vectors, then modulates it (multiplies it) by the surface color, then by the light color.
Insert all such common functions into some "header" shader file.

Then, your generator can spit out shaders on demand. Say you have a scene with 8 lights. The generator generates a shader with 8 calls to the diffuse-reflection function.

That''s a very simplified overview. It''s much more complex than that. You''d do yourself a favor by going to the Graphics programming and Theory forum, and search for "Material Shader Implementation", "Shader system questions" and similar. Yann L. (a graphics guru) has explained such systems in much much better detail than I did (though he used a different technique).

quote:
lightmaps: Nowadays shaders gives us developers a lot of power, but I still think that old tricks die hard If there is a situation in your engine where lightmaps will yeld decent results with inexpensive processing, then go ahead and research it/ implement it.

Lightmaps are good for storing global illumination calculation results, mostly radiosity (as in Max payne). Lately, Peter Pike Sloan (MS Research) introduced a new technique, Precomputed Radiance Self-trasfer, that allows doing partial global illumination in realtime, without lightmap textures, with partially dynamic lights (lights that can rotate, but not translate).

Muhammad Haggag,
Optimize
Bitwise account: MHaggag -

Share this post


Link to post
Share on other sites
Do standard "per pixel" lighting models drop the intensity of the light with distance? Or do they just calculate things like specular light, bumps etc. on the per pixel level?

Share this post


Link to post
Share on other sites
pixel shaders can be used to create lighting effects that falloff over distance, in fact, that''s what I''m going to be experimenting with next. At the moment I''m only taking the lights direction into account.

I''ve managed to get bump-mapping in my pixel-shader experiment engine. Here is a screenshot. I realize the highlights make the bricks look almost plastic or polished, this was done on purpose to make the effect obvious so I could tell if it was really working or not.

http://www.babylonius.com/invasion/scene6.jpg

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!