[ < ] | [ Up ] | [ > ] | [Top] | [Contents] | [Index] | [ ? ] |
As many technical papers (and game marketing) will tell you, rendering realistic lighting like this requires multiple passes. Being a friendly sort of engine, Ogre frees you from most of the hard work though, and will let you use the exact same material definitions whether you use this lighting technique or not (for the most part, see Pass Classification and Vertex Programs). In order to do this technique, Ogre automatically categorises the 3.1.2 Passes you define in your materials into 3 types:
In practice, 3.1.2 Passes rarely fall nicely into just one of these categories. For each Technique, Ogre compiles a list of 'Illumination Passes', which are derived from the user defined passes, but can be split, to ensure that the divisions between illumination pass categories can be maintained. For example, if we take a very simple material definition:
material TestIllumination { technique { pass { ambient 0.5 0.2 0.2 diffuse 1 0 0 specular 1 0.8 0.8 15 texture_unit { texture grass.png } } } } |
Ogre will split this into 3 illumination passes, which will be the equivalent of this:
material TestIlluminationSplitIllumination { technique { // Ambient pass pass { ambient 0.5 0.2 0.2 diffuse 0 0 0 specular 0 0 0 } // Diffuse / specular pass pass { scene_blend add iteration once_per_light diffuse 1 0 0 specular 1 0.8 0.8 15 } // Decal pass pass { scene_blend modulate lighting off texture_unit { texture grass.png } } } } |
In practice this is very easy. Even though your vertex program could be doing a lot of complex, highly customised processing, it can still be classified into one of the 3 types listed above. All you need to do to tell Ogre what you're doing is to use the pass attributes ambient, diffuse, specular and self_illumination, just as if you were not using a vertex program. Sure, these attributes do nothing (as far as rendering is concerned) when you're using vertex programs, but it's the easiest way to indicate to Ogre which light components you're using in your vertex program. Ogre will then classify and potentially split your programmable pass based on this information - it will leave the vertex program as-is (so that any split passes will respect any vertex modification that is being done).
Note that when classifying a diffuse/specular programmable pass, Ogre checks to see whether you have indicated the pass can be run once per light (iteration once_per_light). If so, the pass is left intact, including it's vertex and fragment programs. However, if this attribute is not included in the pass, Ogre tries to split off the per-light part, and in doing so it will disable the fragment program, since in the absence of the 'iteration once_per_light' attribute it can only assume that the fragment program is performing decal work and hence must not be used per light.
So clearly, when you use additive light masking as a shadow technique, you need to make sure that programmable passes you use are properly set up so that they can be classified correctly. However, also note that the changes you have to make to ensure the classification is correct does not affect the way the material renders when you choose not to use additive lighting, so the principle that you should be able to use the same material definitions for all lighting scenarios still holds. Here is an example of a programmable material which will be classified correctly by the illumination pass classifier:
// Per-pixel normal mapping Any number of lights, diffuse and specular material Examples/BumpMapping/MultiLightSpecular { technique { // Base ambient pass pass { // ambient only, not needed for rendering, but as information // to lighting pass categorisation routine ambient 1 1 1 diffuse 0 0 0 specular 0 0 0 0 // Really basic vertex program vertex_program_ref Ogre/BasicVertexPrograms/AmbientOneTexture { param_named_auto worldViewProj worldviewproj_matrix param_named_auto ambient ambient_light_colour } } // Now do the lighting pass // NB we don't do decal texture here because this is repeated per light pass { // set ambient off, not needed for rendering, but as information // to lighting pass categorisation routine ambient 0 0 0 // do this for each light iteration once_per_light scene_blend add // Vertex program reference vertex_program_ref Examples/BumpMapVPSpecular { param_named_auto lightPosition light_position_object_space 0 param_named_auto eyePosition camera_position_object_space param_named_auto worldViewProj worldviewproj_matrix } // Fragment program fragment_program_ref Examples/BumpMapFPSpecular { param_named_auto lightDiffuse light_diffuse_colour 0 param_named_auto lightSpecular light_specular_colour 0 } // Base bump map texture_unit { texture NMBumpsOut.png colour_op replace } // Normalisation cube map texture_unit { cubic_texture nm.png combinedUVW tex_coord_set 1 tex_address_mode clamp } // Normalisation cube map #2 texture_unit { cubic_texture nm.png combinedUVW tex_coord_set 1 tex_address_mode clamp } } // Decal pass pass { lighting off // Really basic vertex program vertex_program_ref Ogre/BasicVertexPrograms/AmbientOneTexture { param_named_auto worldViewProj worldviewproj_matrix param_named ambient float4 1 1 1 1 } scene_blend dest_colour zero texture_unit { texture RustedMetal.jpg } } } } |
At present only one shadow technique supports additive light masking: 7.1 Stencil Shadows through the use of SHADOWTYPE_STENCIL_ADDITIVE.
[ < ] | [ Up ] | [ > ] | [Top] | [Contents] | [Index] | [ ? ] |