Camera relative sky rendering. Now we no longer need to keep sky position in sync with camera.

pull/16/head
scrawl 12 years ago
parent 68f249e8f4
commit 8845c0cee1

@ -1,5 +1,4 @@
#include "occlusionquery.hpp"
#include "renderconst.hpp"
#include <OgreRenderSystem.h>
#include <OgreRoot.h>
@ -7,8 +6,11 @@
#include <OgreHardwareOcclusionQuery.h>
#include <OgreEntity.h>
#include <OgreSubEntity.h>
#include <OgreMeshManager.h>
#include <OgreMaterialManager.h>
#include "renderconst.hpp"
using namespace MWRender;
using namespace Ogre;
@ -16,7 +18,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mActiveQuery(0),
mDoQuery(0), mSunVisibility(0),
mWasVisible(false),
mBBNode(0), mActive(false)
mActive(false)
{
mRendering = renderer;
mSunNode = sunNode;
@ -40,39 +42,24 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
return;
}
MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");
MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels");
matQueryArea->setDepthWriteEnabled(false);
matQueryArea->setColourWriteEnabled(false);
matQueryArea->setDepthCheckEnabled(false); // Not occluded by objects
MaterialPtr matQueryVisible = matBase->clone("QueryVisiblePixels");
matQueryVisible->setDepthWriteEnabled(false);
matQueryVisible->setColourWriteEnabled(false); // Uncomment this to visualize the occlusion query
matQueryVisible->setDepthCheckEnabled(true); // Occluded by objects
matQueryVisible->setCullingMode(CULL_NONE);
matQueryVisible->setManualCullingMode(MANUAL_CULL_NONE);
if (sunNode)
mBBNode = mSunNode->getParentSceneNode()->createChildSceneNode();
mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
mBBQueryTotal = mRendering->getScene()->createBillboardSet(1);
static Ogre::MeshPtr plane = MeshManager::getSingleton().createPlane("occlusionbillboard",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y);
plane->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE);
mBBQueryTotal = mRendering->getScene()->createEntity(plane);
mBBQueryTotal->setCastShadows(false);
mBBQueryTotal->setDefaultDimensions(150, 150);
mBBQueryTotal->createBillboard(Vector3::ZERO);
mBBQueryTotal->setMaterialName("QueryTotalPixels");
mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery);
mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryTotal->setMaterialName("QueryTotalPixels");
mBBNodeReal->attachObject(mBBQueryTotal);
mBBQueryVisible = mRendering->getScene()->createBillboardSet(1);
mBBQueryVisible = mRendering->getScene()->createEntity(plane);
mBBQueryVisible->setCastShadows(false);
mBBQueryVisible->setDefaultDimensions(150, 150);
mBBQueryVisible->createBillboard(Vector3::ZERO);
mBBQueryVisible->setMaterialName("QueryVisiblePixels");
mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery);
mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryVisible->setMaterialName("QueryVisiblePixels");
mBBNodeReal->attachObject(mBBQueryVisible);
mRendering->getScene()->addRenderObjectListener(this);
@ -116,12 +103,12 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass
// Open a new occlusion query
if (mDoQuery == true)
{
if (rend == mBBQueryTotal)
if (rend == mBBQueryTotal->getSubEntity(0))
{
mActiveQuery = mSunTotalAreaQuery;
mWasVisible = true;
}
else if (rend == mBBQueryVisible)
else if (rend == mBBQueryVisible->getSubEntity(0))
{
mActiveQuery = mSunVisibleAreaQuery;
}
@ -170,12 +157,11 @@ void OcclusionQuery::update(float duration)
if (dist==0) dist = 10000000;
dist -= 1000; // bias
dist /= 1000.f;
if (mBBNode)
if (mSunNode)
{
mBBNode->setPosition(mSunNode->getPosition() * dist);
mBBNode->setScale(dist, dist, dist);
mBBNodeReal->setPosition(mBBNode->_getDerivedPosition());
mBBNodeReal->setScale(mBBNode->getScale());
mBBNodeReal->setPosition(mSunNode->getPosition() * dist);
mBBNodeReal->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-mBBNodeReal->getPosition().normalisedCopy()));
mBBNodeReal->setScale(150.f*dist, 150.f*dist, 150.f*dist);
}
// Stop occlusion queries until we get their information
@ -209,6 +195,4 @@ void OcclusionQuery::update(float duration)
void OcclusionQuery::setSunNode(Ogre::SceneNode* node)
{
mSunNode = node;
if (!mBBNode)
mBBNode = node->getParentSceneNode()->createChildSceneNode();
}

@ -49,11 +49,10 @@ namespace MWRender
Ogre::HardwareOcclusionQuery* mSunVisibleAreaQuery;
Ogre::HardwareOcclusionQuery* mActiveQuery;
Ogre::BillboardSet* mBBQueryVisible;
Ogre::BillboardSet* mBBQueryTotal;
Ogre::Entity* mBBQueryVisible;
Ogre::Entity* mBBQueryTotal;
Ogre::SceneNode* mSunNode;
Ogre::SceneNode* mBBNode;
Ogre::SceneNode* mBBNodeReal;
float mSunVisibility;

@ -12,6 +12,8 @@
#include <OgreEntity.h>
#include <OgreSubEntity.h>
#include <OgreMeshManager.h>
#include <boost/lexical_cast.hpp>
#include <components/nifogre/ogrenifloader.hpp>
@ -41,25 +43,25 @@ BillboardObject::BillboardObject( const String& textureName,
static unsigned int bodyCount=0;
/// \todo These billboards are not 100% correct, might want to revisit them later
mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1);
mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON);
mBBSet->setCommonDirection( -position.normalisedCopy() );
mBBSet->setVisibilityFlags(RV_Sky);
mMaterial = sh::Factory::getInstance().createMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount), material);
mMaterial->setProperty("texture", sh::makeProperty(new sh::StringValue(textureName)));
static Ogre::MeshPtr plane = MeshManager::getSingleton().createPlane("billboard",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y);
plane->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE);
mEntity = sceneMgr->createEntity(plane);
mEntity->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
mEntity->setVisibilityFlags(RV_Sky);
mEntity->setCastShadows(false);
mNode = rootNode->createChildSceneNode();
mNode->setPosition(finalPosition);
mNode->attachObject(mBBSet);
mBBSet->createBillboard(0,0,0);
mBBSet->setCastShadows(false);
mMaterial = sh::Factory::getInstance().createMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount), material);
mMaterial->setProperty("texture", sh::makeProperty<sh::StringValue>(new sh::StringValue(textureName)));
mNode->attachObject(mEntity);
mNode->setScale(Ogre::Vector3(550.f*initialSize));
mNode->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-position.normalisedCopy()));
sh::Factory::getInstance().getMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount))->setListener(this);
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
bodyCount++;
}
@ -79,12 +81,12 @@ void BillboardObject::createdConfiguration (sh::MaterialInstance* m, const std::
void BillboardObject::setVisible(const bool visible)
{
mBBSet->setVisible(visible);
mEntity->setVisible(visible);
}
void BillboardObject::setSize(const float size)
{
mNode->setScale(size, size, size);
mNode->setScale(550.f*size, 550.f*size, 550.f*size);
}
void BillboardObject::setVisibility(const float visibility)
@ -103,21 +105,18 @@ void BillboardObject::setPosition(const Vector3& pPosition)
{
Vector3 normalised = pPosition.normalisedCopy();
Vector3 finalPosition = normalised * 1000.f;
mBBSet->setCommonDirection( -normalised );
mNode->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-normalised));
mNode->setPosition(finalPosition);
}
Vector3 BillboardObject::getPosition() const
{
Vector3 p = mNode->_getDerivedPosition() - mNode->getParentSceneNode()->_getDerivedPosition();
return p;
return mNode->getPosition();
}
void BillboardObject::setVisibilityFlags(int flags)
{
mBBSet->setVisibilityFlags(flags);
mEntity->setVisibilityFlags(flags);
}
void BillboardObject::setColour(const ColourValue& pColour)
@ -134,7 +133,7 @@ void BillboardObject::setColour(const ColourValue& pColour)
void BillboardObject::setRenderQueue(unsigned int id)
{
mBBSet->setRenderQueueGroup(id);
mEntity->setRenderQueueGroup(id);
}
SceneNode* BillboardObject::getNode()
@ -218,7 +217,6 @@ SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera)
, mSceneMgr(NULL)
, mAtmosphereDay(NULL)
, mAtmosphereNight(NULL)
, mCloudFragmentShader()
, mClouds()
, mNextClouds()
, mCloudBlendFactor(0.0f)
@ -283,8 +281,7 @@ void SkyManager::create()
mSunGlare->setRenderQueue(RQG_SkiesLate);
mSunGlare->setVisibilityFlags(RV_NoReflection);
Ogre::AxisAlignedBox aabInf;
aabInf.setInfinite ();
Ogre::AxisAlignedBox aabInf = Ogre::AxisAlignedBox::BOX_INFINITE;
// Stars
mAtmosphereNight = mRootNode->createChildSceneNode();
@ -372,8 +369,6 @@ void SkyManager::update(float duration)
{
if (!mEnabled) return;
const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback();
mCamera->getParentSceneNode ()->needUpdate ();
mRootNode->setPosition(mCamera->getDerivedPosition());
// UV Scroll the clouds
mCloudAnimationTimer += duration * mCloudSpeed;
@ -407,8 +402,7 @@ void SkyManager::update(float duration)
Vector3 cam = mCamera->getRealDirection();
const Degree angle = sun.angleBetween( cam );
float val = 1- (angle.valueDegrees() / 180.f);
val = (val*val*val*val)*2;
val = (val*val*val*val)*6;
mSunGlare->setSize(val * mGlareFade);
}
@ -537,7 +531,7 @@ void SkyManager::setGlare(const float glare)
Vector3 SkyManager::getRealSunPos()
{
if (!mCreated) return Vector3(0,0,0);
return mSun->getNode()->_getDerivedPosition();
return mSun->getNode()->getPosition() + mCamera->getRealPosition();
}
void SkyManager::sunEnable()
@ -644,22 +638,6 @@ Ogre::SceneNode* SkyManager::getSunNode()
return mSun->getNode();
}
void SkyManager::setSkyPosition(const Ogre::Vector3& position)
{
mRootNode->setPosition(position);
}
void SkyManager::resetSkyPosition()
{
mCamera->getParentSceneNode ()->needUpdate ();
mRootNode->setPosition(mCamera->getDerivedPosition());
}
void SkyManager::scaleSky(float scale)
{
mRootNode->setScale(scale, scale, scale);
}
void SkyManager::setGlareEnabled (bool enabled)
{
if (!mCreated)

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_SKY_H
#define _GAME_RENDER_SKY_H
#ifndef GAME_RENDER_SKY_H
#define GAME_RENDER_SKY_H
#include <vector>
@ -61,7 +61,7 @@ namespace MWRender
Ogre::ColourValue mColour;
Ogre::SceneNode* mNode;
sh::MaterialInstance* mMaterial;
Ogre::BillboardSet* mBBSet;
Ogre::Entity* mEntity;
};
@ -117,9 +117,6 @@ namespace MWRender
void update(float duration);
void create();
///< no need to call this, automatically done on first enable()
void enable();
void disable();
@ -173,11 +170,10 @@ namespace MWRender
void setGlareEnabled(bool enabled);
Ogre::Vector3 getRealSunPos();
void setSkyPosition(const Ogre::Vector3& position);
void resetSkyPosition();
void scaleSky(float scale);
private:
void create();
///< no need to call this, automatically done on first enable()
bool mCreated;
bool mMoonRed;
@ -200,8 +196,6 @@ namespace MWRender
Ogre::SceneNode* mAtmosphereDay;
Ogre::SceneNode* mAtmosphereNight;
Ogre::HighLevelGpuProgramPtr mCloudFragmentShader;
// remember some settings so we don't have to apply them again if they didnt change
Ogre::String mClouds;
Ogre::String mNextClouds;
@ -227,4 +221,4 @@ namespace MWRender
};
}
#endif // _GAME_RENDER_SKY_H
#endif // GAME_RENDER_SKY_H

@ -136,9 +136,6 @@ void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
mCamera->setFOVy(mParentCamera->getFOVy());
mRenderActive = true;
Vector3 pos = mParentCamera->getRealPosition();
pos.y = (mWaterPlane).d*2 - pos.y;
mSky->setSkyPosition(pos);
mCamera->enableReflection(mWaterPlane);
// for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane.
@ -153,7 +150,6 @@ void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
void PlaneReflection::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{
mSky->resetSkyPosition();
mCamera->disableReflection();
mCamera->disableCustomNearClipPlane();
mRenderActive = false;

@ -721,7 +721,6 @@ namespace sh
// delete any outdated shaders based on this shader set
if (removeCache (it->first))
removeBinaryCache = true;
mShadersLastModified[sourceRelative] = lastModified;
}
}
else
@ -730,11 +729,13 @@ namespace sh
// in both cases we can safely delete
if (removeCache (it->first))
removeBinaryCache = true;
mShadersLastModified[sourceRelative] = lastModified;
}
mShaderSets.insert(std::make_pair(it->first, newSet));
}
// new is now current
mShadersLastModified = mShadersLastModifiedNew;
return removeBinaryCache;
}

@ -3,13 +3,24 @@
#ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
shUniform(float4x4, view) @shAutoConstant(view, view_matrix)
shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix)
shOutput(float, alphaFade)
SH_START_PROGRAM
{
shOutputPosition = shMatrixMult(wvp, shInputPosition);
float4x4 viewFixed = view;
#if !SH_GLSL
viewFixed[0][3] = 0;
viewFixed[1][3] = 0;
viewFixed[2][3] = 0;
#else
viewFixed[3][0] = 0;
viewFixed[3][1] = 0;
viewFixed[3][2] = 0;
#endif
shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shInputPosition));
alphaFade = shInputPosition.z < 150.0 ? 0.0 : 1.0;
}

@ -3,15 +3,26 @@
#ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
shUniform(float4x4, view) @shAutoConstant(view, view_matrix)
shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix)
shVertexInput(float2, uv0)
shOutput(float2, UV)
shOutput(float, alphaFade)
SH_START_PROGRAM
{
shOutputPosition = shMatrixMult(wvp, shInputPosition);
UV = uv0;
float4x4 viewFixed = view;
#if !SH_GLSL
viewFixed[0][3] = 0;
viewFixed[1][3] = 0;
viewFixed[2][3] = 0;
#else
viewFixed[3][0] = 0;
viewFixed[3][1] = 0;
viewFixed[3][2] = 0;
#endif
shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shInputPosition));
UV = uv0;
alphaFade = (shInputPosition.z <= 200.f) ? ((shInputPosition.z <= 100.f) ? 0.0 : 0.25) : 1.0;
}

@ -3,14 +3,26 @@
#ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
shUniform(float4x4, world) @shAutoConstant(world, world_matrix)
shUniform(float4x4, view) @shAutoConstant(view, view_matrix)
shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix)
shVertexInput(float2, uv0)
shOutput(float2, UV)
SH_START_PROGRAM
{
shOutputPosition = shMatrixMult(wvp, shInputPosition);
UV = uv0;
float4x4 viewFixed = view;
#if !SH_GLSL
viewFixed[0][3] = 0;
viewFixed[1][3] = 0;
viewFixed[2][3] = 0;
#else
viewFixed[3][0] = 0;
viewFixed[3][1] = 0;
viewFixed[3][2] = 0;
#endif
shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shMatrixMult(world, shInputPosition)));
UV = uv0;
}
#else

@ -1,3 +1,34 @@
material QueryTotalPixels
{
allow_fixed_function false
pass
{
vertex_program sun_vertex
fragment_program sun_fragment
cull_hardware none
polygon_mode_overrideable off
depth_check off
depth_write off
colour_write off
}
}
material QueryVisiblePixels
{
allow_fixed_function false
pass
{
vertex_program sun_vertex
fragment_program sun_fragment
cull_hardware none
cull_software none
polygon_mode_overrideable off
depth_check on
depth_write off
colour_write off
}
}
material openmw_moon
{
allow_fixed_function false
@ -5,6 +36,7 @@ material openmw_moon
{
vertex_program moon_vertex
fragment_program moon_fragment
cull_hardware none
polygon_mode_overrideable off
depth_write off
@ -92,6 +124,7 @@ material openmw_sun
{
vertex_program sun_vertex
fragment_program sun_fragment
cull_hardware none
polygon_mode_overrideable off

@ -3,7 +3,8 @@
#ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
shUniform(float4x4, view) @shAutoConstant(view, view_matrix)
shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix)
shVertexInput(float2, uv0)
shOutput(float2, UV)
@ -11,7 +12,17 @@
SH_START_PROGRAM
{
shOutputPosition = shMatrixMult(wvp, shInputPosition);
float4x4 viewFixed = view;
#if !SH_GLSL
viewFixed[0][3] = 0;
viewFixed[1][3] = 0;
viewFixed[2][3] = 0;
#else
viewFixed[3][0] = 0;
viewFixed[3][1] = 0;
viewFixed[3][2] = 0;
#endif
shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shInputPosition));
UV = uv0;
fade = (shInputPosition.z > 50) ? 1 : 0;

@ -3,14 +3,26 @@
#ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
shUniform(float4x4, world) @shAutoConstant(world, world_matrix)
shUniform(float4x4, view) @shAutoConstant(view, view_matrix)
shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix)
shVertexInput(float2, uv0)
shOutput(float2, UV)
SH_START_PROGRAM
{
shOutputPosition = shMatrixMult(wvp, shInputPosition);
UV = uv0;
float4x4 viewFixed = view;
#if !SH_GLSL
viewFixed[0][3] = 0;
viewFixed[1][3] = 0;
viewFixed[2][3] = 0;
#else
viewFixed[3][0] = 0;
viewFixed[3][1] = 0;
viewFixed[3][2] = 0;
#endif
shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shMatrixMult(world, shInputPosition)));
UV = uv0;
}
#else

Loading…
Cancel
Save