Ogre 的基于Texture的阴影有时会不正常(相对不正常,只是因为使用不得当)
因为默认情况下mShadowCasterRenderBackFaces为true,即渲染背面,从官方解释可看出,这么做是为了优化在渲染阴影时的效率,它是可选的。当使用基于Texture的阴影且mShadowCasterRenderBackFaces为true时就会利用背面去渲染阴影深度图。(这样做的目的应该是模型在制作时有一个背面的较为简单的网格,它专门为阴影渲染优化而做的,从而达到优化的目的)
官方解释:
virtual void Ogre::SceneManager::setShadowCasterRenderBackFaces | ( | bool | bf ) | [virtual] |
Sets whether or not shadow casters should be rendered into shadow textures using their back faces rather than their front faces.
Definition at line 2929 of file OgreSceneManager.h.
默认情况下mShadowCasterRenderBackFaces为true
SceneManager::SceneManager(const String& name) : mName(name), mRenderQueue(0), mLastRenderQueueInvocationCustom(false), mCurrentViewport(0), mSceneRoot(0), mSkyPlaneEntity(0), mSkyBoxObj(0), mSkyPlaneNode(0), mSkyDomeNode(0), mSkyBoxNode(0), mSkyPlaneEnabled(false), mSkyBoxEnabled(false), mSkyDomeEnabled(false), mFogMode(FOG_NONE), mFogColour(), mFogStart(0), mFogEnd(0), mFogDensity(0), mSpecialCaseQueueMode(SCRQM_EXCLUDE), mWorldGeometryRenderQueue(RENDER_QUEUE_WORLD_GEOMETRY_1), mLastFrameNumber(0), mResetIdentityView(false), mResetIdentityProj(false), mNormaliseNormalsOnScale(true), mFlipCullingOnNegativeScale(true), mLightsDirtyCounter(0), mMovableNameGenerator("Ogre/MO"), mShadowCasterPlainBlackPass(0), mShadowReceiverPass(0), mDisplayNodes(false), mShowBoundingBoxes(false), mActiveCompositorChain(0), mLateMaterialResolving(false), mShadowTechnique(SHADOWTYPE_NONE), mDebugShadows(false), mShadowColour(ColourValue(0.25, 0.25, 0.25)), mShadowDebugPass(0), mShadowStencilPass(0), mShadowModulativePass(0), mShadowMaterialInitDone(false), mShadowIndexBufferSize(51200), mFullScreenQuad(0), mShadowDirLightExtrudeDist(10000), mIlluminationStage(IRS_NONE), mShadowTextureConfigDirty(true), mShadowUseInfiniteFarPlane(true), mShadowCasterRenderBackFaces(true), mShadowAdditiveLightClip(false), mLightClippingInfoMapFrameNumber(999), mShadowCasterSphereQuery(0), mShadowCasterAABBQuery(0), mDefaultShadowFarDist(0), mDefaultShadowFarDistSquared(0), mShadowTextureOffset(0.6), mShadowTextureFadeStart(0.7), mShadowTextureFadeEnd(0.9), mShadowTextureSelfShadow(false), mShadowTextureCustomCasterPass(0), mShadowTextureCustomReceiverPass(0), mVisibilityMask(0xFFFFFFFF), mFindVisibleObjects(true), mSuppressRenderStateChanges(false), mSuppressShadows(false), mCameraRelativeRendering(false), mLastLightHash(0), mLastLightLimit(0), mLastLightHashGpuProgram(0), mGpuParamsDirty((uint16)GPV_ALL) { // init sky for (size_t i = 0; i < 5; ++i) { mSkyDomeEntity[i] = 0; } mShadowCasterQueryListener = OGRE_NEW ShadowCasterSceneQueryListener(this); Root *root = Root::getSingletonPtr(); if (root) _setDestinationRenderSystem(root->getRenderSystem()); // Setup default queued renderable visitor mActiveQueuedRenderableVisitor = &mDefaultQueuedRenderableVisitor; // set up default shadow camera setup mDefaultShadowCameraSetup.bind(OGRE_NEW DefaultShadowCameraSetup()); // init shadow texture config setShadowTextureCount(1); // init shadow texture count per type. mShadowTextureCountPerType[Light::LT_POINT] = 1; mShadowTextureCountPerType[Light::LT_DIRECTIONAL] = 1; mShadowTextureCountPerType[Light::LT_SPOTLIGHT] = 1; // create the auto param data source instance mAutoParamDataSource = createAutoParamDataSource(); }
当使用基于Texture的阴影且mShadowCasterRenderBackFaces为true时就会利用背面去渲染阴影深度图。
const Pass* SceneManager::_setPass(const Pass* pass, bool evenIfSuppressed, bool shadowDerivation) { ...................
// Culling mode if (isShadowTechniqueTextureBased() && mIlluminationStage == IRS_RENDER_TO_TEXTURE && mShadowCasterRenderBackFaces && pass->getCullingMode() == CULL_CLOCKWISE) { // render back faces into shadow caster, can help with depth comparison mPassCullingMode = CULL_ANTICLOCKWISE; } else { mPassCullingMode = pass->getCullingMode(); } mDestRenderSystem->_setCullingMode(mPassCullingMode);
.......................... }