could you elabourate? Do you understand the issue of combining passes without modulating the existing lights in the destination color buffer? All terms, both specular and diffuse must be modulated by shadows & attenuation, so you can’t get by with modulating just some of the results in one pass and adding another.
rendertotexture buys you color modulation across passes without trampling over your destination color buffer.[/b]
Any problems?
Do you see any “modulating the existing lights in the destination color” below?
(I hope “destColor += destAlpha * srcColor” is valid operation)
Note: destination color contains results of previous passes
First pass:
destination ALPHA <= range attenuation
Second pass:
(stencil test is ON!)
destColor += destAlpha * dffuseLightingResult(decall, lightNormal, normal bump map, projectedLightTexture)
Third pass:
(stencil test is ON!)
destColor += destAlpha * specularLightingResult(gloss, halfVector, normal bump map, projectedLightTexture)
well… if we only do stencil shadows and light-color-maps (your projected ones)… i’ll suggest this way:
clear to ambient color (doom3:black)
for every light {
fill stencil with shadow-volumes
make sure you only draw into unshadowed region
add diffuse of this light (with the 4 textures i mentoied above)
add specular of this light (with the 4 textures i mentoied above)
}
done.
that way works. it has only one problem: you have lost the power of doing free shaders on the geometry (means the stuff q3 had, animated computer screens, rotating textures over other textures etc…)
to do that, render those shaders into a texture first, and bind this instead of the colormap you normally use for diffuse shading.
Interesting. You can certainly multiply range attenuation with a shadow / light map in the first pass.
The terms for specular and diffuse cannot globally modulate so that does put the kybosh on throwing much else in there.
For monochrome surface color again you could apply that in the alpha in the first pass which is perhaps the pass difference between monochrome and color come in. Much depends on what you can model for the surface material. All independent lighting component textures have to be applied in the second pass. I see that you almost have to separate diffuse and specular in independent passes after that because you the only remaining + in the rest of equation is between those two major terms.
Originally posted by peterpan:
[b] Once again: where is attenuation map?
Possibly we can include attenuation into projective light texture (I guess) by using 3D 9instead of 2D) texturing, but it’s waste of texture memory.[/b]
hm well… put this into the normalisationcubemap. by extending it to a procedural(texture3d,rgb=normalized(texcoord),alpha=dst_att(texcoord))
about this… i can’t tell how it really looks, cause i dont have a gf3, but i know from some others that they like it… and it works reasonably fast, and well… a 64x64x64 tex should be enough, they told me… they don’t see much difference for the rest (else we can renormalize in the combiners, thats easy… )
Whether diffuse is monochrome or not determines if you can place any additional terms in the first pass. But if you did you’d be stuck with the same modulation of specular subsequently. So a diffuse map would also be a gloss map if you did this.
Feel free to assign textures to diffuse and specular calculations to determin passes with & without the diffuse texture color multiplied in destination alpha.
[This message has been edited by dorbie (edited 06-04-2002).]
into tex0alpha you can store glossiness as well… for the specular pass afterwards…
in this case tex0 is texture2drgba
tex1 is projectedtexture/cubemaprgb
tex2 is 3dtexturergba
tex3 is texture2drgba
that SHOULD work… (you have to z-sort ) so split between transparent geometry and not transparent geometry, as always… (but specular does not care on transparency => tipp (OKAY if you take fresnel…))
Carmack said something about three passes on GF3 (per object?). I don’t know it’s “stencil, specular, diffuse” or it’s (stencil not counted) “specular, diffuse, something else(alpha buffer?)”. I remember, he said something about two normalizations, 7 texture acceses, 6 texture modules. If so, I don’t know for what is sixth texture exists (if we have no separate attenuation map texture).
So, here is list of textures:
Decal, Gloss, NormalBump, ProjectedLight, 3DNormalizationWithAttenuation, MAGICAL_SIXTH_TEXTURE.
Hm… Vote for destination alpha buffer pass!
dave, Carmack will say (after reading your message) in an interview “I have an idea. Now I have FIVE textures instead of SIX” .
or dorbies message whats wrong with my code (as you and he are the only ones currently reading i guess)
i dont find any bugs anymore in this myself, but i often forget different things…
btw, dorbie, this is your page? www.dorbie.com
i guess yes. well i’ve seen that page and now i at least know what you’ve done so far. clears up some things (just, who you are/what you’ve done )
well then, go for normalisation in the combiners… means 2 normalisationcubemaps, the light/shadowmap and the normalmap/glossmap for the specular. well… all we need puh…
Originally posted by davepermen: can’t wait for his call…
i dont find any bugs anymore in this myself, but i often forget different things…
I don’t find too, yet :).
I don’t check any specular/transparency issues, so may be they are completely wrong :).
About attenuation on specular… I think ypu MUST to attenuate specular. Otherwise your scene must be completely redrawn for each light, to include specular term for any light in any place on any surface.
So, I prefer to use attenuation on specular.
dave, I think many persons read this thread, but too few of them want to share their knowledge :(.
I only called it that because that’s what it is. I’m not trying to coin a new phrase, think of it as a descriptive variable. It is inevitably that because those are the terms it modulates. I was being pedantic because if I hadn’t called it that someone would have pointed it out that it also modulates specular.
The point is really that it is stored in destination alpha. The specular pass is optional but if you have one it would be modulated by the other terms.
Peterpan,
stencil doesn’t strictly count as a pass. It is a significant overhead overhead but it’s separate geometry.
Perhaps what’s getting counted is the pre stencil depth buffer fill, that does count as a pass and covers the full scene, but it’s a one time cost, reguardless of number of lights. Unlike an illumination pass you don’t cull the depth pass to a light sources beam tree.
prenormalizing is always resulting in errors on interpolation, mainly because the direction will get wrong in the middle of the triangle => the specular dot shifts around on geometry…
bether normalizing both and doing a rc-normalization afterwards, thats quite easy to implement and works well (and well, i have enough textures )
else you could think of some function of (to_light - to_point), possibly we could extract the needed value from this one (i bet thats another 3d-texture wich could be solved as 1d if we could first calc the length^2 of the vec and lookup this, as for attentuation and normaliztion… damn gf3/4 textureshader design…)
Dave, at the time I pointed you to my profile for the URL. I thought you’d looked. The bumplogo and UAV stuff is the most relevant, but it’s about 4 years old now.
Strictly speaking specular needs attenuation to be correct. Visualize the solid angle the light makes with the surface which varies for all terms, or visualize the power over area of the light from a point source. Either one will lead you to conclude you need attenuation. It’s incident light that attenuates, reflected light is a function of incident light.
Anyway one thing remains to be explained. What’s the theory behind simultaneously applying an attenuation map in texture2?
[This message has been edited by dorbie (edited 06-04-2002).]
i wanted to go to your profile but i missed it then, and forgot it afterwards, i’m sorry
well… on a gf2 you need 4 textures for accurate simple diffuse bumpmapped lighting:
1 is normalmap
2 is normalizationcubemap for to_light
3 is 2d x-y part of attentuationfunc
4 is 1d z part of attentuationfunc
if you have a gf3 you can store the normalized to_light vec in a texture3d as well, where you look up to_light and get normalized_to_light in rgb.
in alpha you can store there the attentuation_func(to_light)… so you can put 4 textures into one… quite handy, not? (i would prefer if you could normalize the vec and get the length^2 as well, and look this up in a 1dfunction)
if you think about it… n.normalized(l)att(l^2) can be rewritten as n.l(att(l^2)/sqrt(l^2)) and f = att(l^2)/sqrt(l^2) can be a 1dfunc… so a 1d texturelookup of to_light^2 and a pass_through of to_light would be enough as well (much less memory and more accurate looking)
but gf3/4 dont support this… so we stick with a 3dtex wich does the job, as l/sqrt(l^2)*att(l^2) is only a 3dfunc in fact…
Originally posted by davepermen:
[b]…
so a 1d texturelookup of to_light^2 and a pass_through of to_light would be enough as well (much less memory and more accurate looking)
but gf3/4 dont support this… so we stick with a 3dtex wich does the job, as l/sqrt(l^2)*att(l^2) is only a 3dfunc in fact…[/b]
My friend tested cube normalization map few days ago. He said 32x32 (or 64x64? can’t remember exactly) texture size (per cube’s side) is not enough even for average quality results. He tested it with bumpmapping. Results were very frustrating. He increased resolution of the map to 256x256 and obtained a good quality image. This cubemap (RGB) occupies ~1 Mb of memory (right?).
So, due to these test results, I think a 64x64 3d(!) texture for normalization (and attenuation) is not enough (at least for Doom3). Possibly I need to test it to see results by myself.
Increasing resolution of this 3d texture is not very bright idea due to memory limit. Hm… 128x128x128 is 8Mb uncompressed RGBA (it’s too big, for me) and its quality is not better than with 64x64 cubemap’s.