OGRE 3D 軟體工程與哲學

My OGRE 3D working journal vol.6

The sample demonstrates how the ocean surface looks like.

# the sample uses an UI description: “media/materials/scripts/Ocean.controls”.
Sample_Ocean::loadMaterialControlsFile is a nice parser that we can somehow reference.

# Take a look at one of the materials used for ocean: “Ocean2_Cg”, which is in “media/materials/scripts/Ocean.material”, where there is a cubic texture “morning.jpg”, in “media/packs/cubemapsJS.zip”. The shaders used in the material:
– displace vertex
– produce tangent to world matrix
– produce normal map sampling index
– sample normal map
– use the above result to compute the reflection vector, and sample the cubic texture.
– use shallow/deep water colors and perspective angles to generate the water color.
– use Fresnel factor to blend the above resulting water color and the reflection color (cubic texture sampling result)

# The sample is also a nice sample of an editor.

# mSceneMgr->createParticleSystem(“Fireworks”, “Examples/Fireworks”) creates an Ogre::ParticleSystem, which is attached to a scene node. “Examples/Fireworks” is in “media/particle/emitted_emitter.particle”.

# The sample also uses other particle template:

# OGRE particle script manual:

# create 2 entities “sibenik” and “cornell”, w/ mesh “sibenik.mesh” and “cornell.mesh” individually.
For both entities, setMaterialName(“SSAO/GBuffer”), where the material is in “media/materials/scripts/SSAO/GBuffer.material”.

# add and enable compositor “SSAO/GBuffer”, which is in “media/materials/scripts/SSAO/SSAO.compositor”.
CompositorManager::getSingleton().addCompositor(mViewport, “SSAO/GBuffer”));
CompositorManager::getSingleton().setCompositorEnabled(mViewport, “SSAO/GBuffer”, true);

# add other compositors but disable them. The compositors include:

# add post filters (they are also compositors) and disable them. The post filters include:

# enable “SSAO/HemisphereMC” and “SSAO/Post/NoFilter”.
“SSAO/HemisphereMC” is in “media/materials/scripts/SSAO/SSAO.compositor”.
“SSAO/Post/NoFilter” is in “media/materials/scripts/SSAO/SSAOPost.compositor”.

# The SSAO effect in the CPU client side is pretty simple. I didn’t trace into the shaders deeply, but the flow should be that all the entities render the attributes (position, normal, etc) to a render target (G-buffer), and the actual shading is done as a post effect.

# SSAO references:

Demonstrates how OGRE SDK manipulates material, shader, and render state.
# create entity “MainEntity”, w/ mesh “ShaderSystem.mesh”, show bounding box.

# create entity “ExportedMaterialEntity”, w/ mesh “ShaderSystem.mesh”, material “Panels_RTSS_Export” (material assignment failed).

# create entity “LayeredBlendingMaterialEntity”, w/ mesh “ShaderSystem.mesh”, material “RTSS/LayeredBlending”, which is in “media/RTShaderLib/materials/RTShaderSystem.material”.

# create entity “PerPixelEntity”, w/ mesh “knot.mesh”, material “RTSS/PerPixel_SinglePass”.

# create entity “NormalMapEntity”, w/ mesh “knot.mesh”, material “RTSS/NormalMapping_SinglePass”.

# create texture atlas, see createTextureAtlasObject

# updateSystemShaders programmably creates/sets shader/material/render_state.

As the sample description says, “A demonstration of ogre’s various shadowing techniques.”

# The OGRE shadow manual:

# enum ShadowTechnique (only list the working ones, see the comment in code)

# create entity “athene”, w/ mesh “athene.mesh”, material “Ogre/DepthShadowmap/Receiver/Athene”, which is in “media/materials/scripts/DepthShadowmap.material”.

# create N column entities, w/ mesh “column.mesh”, material “”Examples/Rockwall”.

# create entity “plane”, w/ plane mesh, material “Examples/Rockwall”. 

# Basically rendering shadows in OGRE is simple. But if you want to program the shadow effects, it takes efforts. For example, here are the shader references in material “Ogre/DepthShadowmap/Receiver/Athene”: 
vertex_program_ref Ogre/DepthShadowmap/NormalMapReceiverVP
shadow_receiver_vertex_program_ref Ogre/DepthShadowmap/NormalMapReceiverVP
fragment_program_ref Ogre/DepthShadowmap/NormalMapReceiverFP
shadow_receiver_fragment_program_ref Ogre/DepthShadowmap/NormalMapReceiverFP
(all the above refers to: “DepthShadowmap.hlsl”)

A lovely sample w/ 6 animated ragdolls on a plane.
# Sample_SkeletalAnimation::tweakSneakAnim demonstractes how to edit/modify the animation tracks.
# the model mesh is “jaiqua.mesh”, w/ material “jaiqua”, in “media/materials/scripts/Examples.material”.
# the 6 ragdolls have the same animation asset but w/ diff animation speed, orientation, and position.

A nice sample w/ a fighter aircraft (but I prefer its head looking into the screen). SkyBox technique has been widely used in the OGRE samples.
# the core function call: mSceneMgr->setSkyBox(true, “Examples/SpaceSkyBox”, 5000);
the material is in “media/materials/scripts/Examples.material”. If we look into the material, a SkyBox is actually a cubic map mapping to a super large cube in the scene.
# the sample also demonstrates the usage of OGRE ParticleSystem & ParticleEmitter.

# the core function call: mSceneMgr->setSkyDome(true, “Examples/CloudySky”, …);
where the material is in “media/materials/scripts/Examples.material”, which contains only a simple jpg.

Instead of the SkyPlane, I think the flying monster model is pretty cool.
# the core function call: mSceneMgr->setSkyPlane(true, Plane(0, -1, 0, 5000), “Examples/SpaceSkyPlane”, 10000, 3);
where the material is in “media/materials/scripts/Examples.material”, which contains only a simple jpg.
# the flying monster is actually a dragon, w/ mesh “dragon.mesh”.

A smoking OGRE head goes around the scene.
# core function call: mSceneMgr->createParticleSystem(“Smoke”, “Examples/Smoke”);
The template is in “media/particle/smoke.particle”, and the template uses material “Examples/Smoke” and an image “smokecolors.png”. The material is in “media/materials/scripts/smoke.material”, which contains “smoke.png”. It’s obvious “smoke.png” is for sprite, while “smokecolors.png” is to modulate the smoke color.

# uses material “Examples/SphereMappedRustySteel”, which is in “media/materials/scripts/Examples.material”. The material blends the environment map “spheremap.png” with the original texture “RustySteel.jpg”.

A nice sample w/ interesting GUI to concave the terrain. I was trying to concave the terrain beneath the house, but the house didn’t collapse and was floating in the air.

# the reference link (kind of step by step explanation)

# how to modify the terrain, see Sample_Terrain::doTerrainModify

# until now, no idea about how terrain is generated/rendered (I mean, for example, starting from Direct3D). Leave this as future work.

# use the material “Examples/TextureArray”, which is in “media/materials/scripts/Examples-Advanced.material”. The material uses fragment_program_ref Examples/TextureArrayPSasm (assembly language shader)
# texture array is a technique that shader (especially pixel shader) can see multiple textures. In OGRE there seems to be no such “TextureArray” class. Instead, it uses general texture generation:
TextureManager::getSingleton().createManual (with input mipmap_num = the texture array size). 

A demonstration of special texture effects. There are 4 materials used in this sample (in “media/materials/scripts/Examples.material”)
“Examples/OgreDance”,  // anim_texture 
“Examples/OgreParade”, // scroll_anim
“Examples/OgreSpin”,   // rotate_anim
“Examples/OgreWobble”  // wave_xform

The sample uses “Examples/WaterStream”, in “media/materials/scripts/Examples.material”, where “scene_blend add” is the point.

As the sample comment says: “Generate 3D julia sets and render them as volume texture”.
# create texture “DynaTex”, w/ texture type TEX_TYPE_3D (Volume Texture).

# create VolumeRenderable w/ input texture name “DynaTex”.

# create ThingRenderable, w/ material “Examples/VTDarkStuff”, which is in “media/materials/scripts/Examples-DynTex.material”.

# each frame the sample calls ThingRenderable::addTime, which updates the local vertex buffer in ThingRenderable.

# Sample_VolumeTex::generate updates the texture buffer of “DynaTex”.

# VolumeRenderable::initialise creates/fills in the vertex/index buffers, sets render operations, 
creates/sets material/technique/pass/texture_unit, texture_unit is assigned the name “DynaTex”.

# The class diagram of this sample:

Water simulation w/ ripples. 
# creates WaterMesh, defined in this sample. The WaterMesh constructor creates a mesh w/ name “WaterMesh” and creates/sets the vertex/index buffers.

# creates entity “WaterEntity”, w/ mesh “WaterMesh”.

# each frame calls WaterMesh::updateMesh to update the vertex buffer (including update normal). The algorithm link provided in this sample doesn’t exist.

# How does the water know the position of the ogre head and therefore generate ripples?
Each frame Sample_Water::animateHead is called, and in it WaterMesh::push is called. WaterMesh::push pushes 4 vertices around an indicated position (x,y) downward.

# There are some materials for water rendering in this sample. Temporarily skip them and leave for future work.