I don’t know enough about Cg yet to be able to pick apart the specular shaders, so I don’t know what the common way of handling a specular map is. My theory is that you’d just take the specular lighting calculation and use a “lightmap” on it. There aren’t any examples of this technique that I can find, however.
specularity only exists with lights and real lights (pixel lights) don’t exist in fixed function. fixed function interpolates basing on polygons which is commonly insufficient for any kind of real specularity.
But you can naturally treat it as some kind of lightmap.
That isn’t really cheap but you can use the specularity map to brighten a lightmap through an additive pass.
Question is how much you gain from that or if it even makes any difference because good lightmaps should already have these informations baked in by default.
You can’t bake in information that is variable in-game. I’m not talking about using a lightmap in the standard sense, where it just acts as another light. But it would work similarly (that is, it just darkens/colorizes what is already there) - if you only take the result of the specular calculation, and then multiply in some color, I would think you’d end up with something like this. Unless somebody tells me otherwise, I’m going to try making such a shader today.
(And yes, I know it won’t look like much of anything if I just have 4 vertices like in that example.)
I guess I don’t understand.
Lightmaps are static, they can’t be dynamic as they are used to lighten the otherwise massive costs of the lighting that ffp hardware just is not able to cope with.
But perhaps you mean the variable on the specular end.
Thats naturally possible if you alter it for some reason.
Doing such a shader is definitely possible. There are different approaches to it from blending to overwriting data etc.
I think you only need to build the passes in the correct order (lightmap + specular first then the lm-spec + diffuse) to have it working.
used similar approaches back in DX7 for “texture lights” by switching textures on the higher textures stages in and out.
You can certainly have a specular map in fixed function lighting. Just remember that it can only modulate the strength, not the exponent of the specular calculation. A shader that did this would need two passes because the lighting calculation needs to be split into ambient/diffuse, and then the specular. The passes can be done in any order, because they would be summed. The diffuse pass would be your regular diffuse pass, withou defining a specular colour. The specular pass would have a white specular colour, but not define anything else. The result of this lighting calculation would then be multiplied by the specular map (which could be any colour!) and the final result would be added to the destination. The specular pass should only require one texture operation.
Thanks, Daniel. That was the approach I took, so I’m glad to hear I was on the right track. As I mentioned in the grayscale bumpmap thread, my girlfriend is supposed to make a bump, specular, and self-illumination map this week. We’d never worked with either before yesterday (except normal maps, which aren’t covered in the class yet
), but I think I get the gist of things. However, as the name of the shader suggests, I think the “bump map” portion is kind of stupid.
You think there is any way to combine these things with a 2-texture card?
Shader "Full-Color Glow Specular + Lame 'Bumpmap'" {
Properties
{
_Shininess ("Shininess", Range (0,1) ) = .7
_Bumpiness ("Bumpiness", Range (0,1) ) = .3
_MainTex ("Texture (RGB)", 2D) = ""
_MaskedGlow ("Self Illumination with Mask", 2D) = ""
_SpecularBump ("Specular Map (RGB) + Bumpmap (A)", 2D) = ""
}
SubShader
{
Lighting On
Blend AppSrcAdd AppDstAdd
// Diffuse
Pass
{
Material
{
Diffuse (1,1,1)
}
// Subtract the inverted heightmap.
SetTexture [_SpecularBump]
{
combine primary - one - texture alpha
}
// Add bumps.
SetTexture [_]
{
constantcolor (0,0,0, [_Bumpiness])
combine previous lerp (constant) primary
}
// 'Light' the texture.
SetTexture [_MainTex]
{
combine texture * previous
}
// Blend in self-illumination texture.
SetTexture [_MaskedGlow]
{
combine texture lerp (texture) previous
}
}
// Specular
Pass
{
Material
{
Specular (1,1,1)
Shininess [_Shininess]
}
// subtract the inverted heightmap
SetTexture [_SpecularBump]
{
combine primary - one - texture alpha
}
// Add bumps.
SetTexture [_]
{
constantcolor (0,0,0, [_Bumpiness])
combine previous lerp (constant) primary
}
// Colorize the grey-white specular highlights.
SetTexture [_SpecularBump]
{
combine texture * previous
}
}
}
}
I don’t think you can get what you want from the iPhone. You’d have to do something like remove the Bumpiness property, and just bake that into your bump texture.
Unless I’m wrong (did only do small things yet with it), those shaders won’t work anyway because your passes use more textures than you have per pass, at least if you intend to target pre 3GS hardware.
What do you mean by “your passes use more textures than you have per pass”?
The pre-3GS iphones only have a 2 texture unity graphic chip, which basically means that any texture after the second one in a pass is ignored. Above passes are 3 and 5 texture passes unless I missunderstood how combiners work, which means either invalid or 3GS only.
Ok, I thought you were talking about some other limitation. Jessy already asked whether the shader could be modified to work on a 2 texture card, which means the iPhone these days.
Unfortunately, where Jessy’s version uses 4, then 3 texture units, was only able to reduce it to 2, 1, 1, 3. The specular pass can’t be made smaller due to the operations required for the bump map scaling. If the bumpiness property were baked into the texture, the shader could be done in passes with 2, 1, 2 operations.