mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 11:15:33 +00:00
Merge remote branch 'scrawl/graphics'
Conflicts: apps/openmw/mwrender/renderingmanager.cpp
This commit is contained in:
commit
7938566004
13 changed files with 207 additions and 87 deletions
|
@ -16,6 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
|
|||
add_openmw_dir (mwrender
|
||||
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
|
||||
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows shaderhelper
|
||||
compositors
|
||||
)
|
||||
|
||||
add_openmw_dir (mwinput
|
||||
|
|
49
apps/openmw/mwrender/compositors.cpp
Normal file
49
apps/openmw/mwrender/compositors.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include "compositors.hpp"
|
||||
|
||||
#include <OgreViewport.h>
|
||||
#include <OgreCompositorManager.h>
|
||||
|
||||
using namespace MWRender;
|
||||
|
||||
Compositors::Compositors(Ogre::Viewport* vp) :
|
||||
mViewport(vp)
|
||||
, mEnabled(true)
|
||||
{
|
||||
}
|
||||
|
||||
Compositors::~Compositors()
|
||||
{
|
||||
Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport);
|
||||
}
|
||||
|
||||
void Compositors::setEnabled (const bool enabled)
|
||||
{
|
||||
for (CompositorMap::iterator it=mCompositors.begin();
|
||||
it != mCompositors.end(); ++it)
|
||||
{
|
||||
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, it->first, enabled && it->second.first);
|
||||
}
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
void Compositors::addCompositor (const std::string& name, const int priority)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
for (CompositorMap::iterator it=mCompositors.begin();
|
||||
it != mCompositors.end(); ++it)
|
||||
{
|
||||
if (it->second.second > priority)
|
||||
break;
|
||||
++id;
|
||||
}
|
||||
Ogre::CompositorManager::getSingleton().addCompositor (mViewport, name, id);
|
||||
|
||||
mCompositors[name] = std::make_pair(false, priority);
|
||||
}
|
||||
|
||||
void Compositors::setCompositorEnabled (const std::string& name, const bool enabled)
|
||||
{
|
||||
mCompositors[name].first = enabled;
|
||||
Ogre::CompositorManager::getSingleton().setCompositorEnabled (mViewport, name, enabled && mEnabled);
|
||||
}
|
53
apps/openmw/mwrender/compositors.hpp
Normal file
53
apps/openmw/mwrender/compositors.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef GAME_MWRENDER_COMPOSITORS_H
|
||||
#define GAME_MWRENDER_COMPOSITORS_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
class Viewport;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
typedef std::map < std::string, std::pair<bool, int> > CompositorMap;
|
||||
|
||||
/// \brief Manages a set of compositors for one viewport
|
||||
class Compositors
|
||||
{
|
||||
public:
|
||||
Compositors(Ogre::Viewport* vp);
|
||||
virtual ~Compositors();
|
||||
|
||||
/**
|
||||
* enable or disable all compositors globally
|
||||
*/
|
||||
void setEnabled (const bool enabled);
|
||||
|
||||
bool toggle() { setEnabled(!mEnabled); return mEnabled; }
|
||||
|
||||
/**
|
||||
* enable or disable a specific compositor
|
||||
* @note enable has no effect if all compositors are globally disabled
|
||||
*/
|
||||
void setCompositorEnabled (const std::string& name, const bool enabled);
|
||||
|
||||
/**
|
||||
* @param name of compositor
|
||||
* @param priority, lower number will be first in the chain
|
||||
*/
|
||||
void addCompositor (const std::string& name, const int priority);
|
||||
|
||||
protected:
|
||||
/// maps compositor name to its "enabled" state
|
||||
CompositorMap mCompositors;
|
||||
|
||||
bool mEnabled;
|
||||
|
||||
Ogre::Viewport* mViewport;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,6 +19,7 @@
|
|||
#include "shaderhelper.hpp"
|
||||
#include "localmap.hpp"
|
||||
#include "water.hpp"
|
||||
#include "compositors.hpp"
|
||||
|
||||
using namespace MWRender;
|
||||
using namespace Ogre;
|
||||
|
@ -30,6 +31,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
|||
{
|
||||
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
|
||||
|
||||
mCompositors = new Compositors(mRendering.getViewport());
|
||||
|
||||
mWater = 0;
|
||||
|
||||
//The fog type must be set before any terrain objects are created as if the
|
||||
|
@ -68,15 +71,15 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
|||
// note that the order is important here
|
||||
if (useMRT())
|
||||
{
|
||||
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbuffer");
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true);
|
||||
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "Underwater");
|
||||
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "gbufferFinalizer");
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true);
|
||||
mCompositors->addCompositor("gbuffer", 0);
|
||||
mCompositors->setCompositorEnabled("gbuffer", true);
|
||||
mCompositors->addCompositor("Underwater", 1);
|
||||
mCompositors->addCompositor("gbufferFinalizer", 2);
|
||||
mCompositors->setCompositorEnabled("gbufferFinalizer", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CompositorManager::getSingleton().addCompositor(mRendering.getViewport(), "UnderwaterNoMRT");
|
||||
mCompositors->addCompositor("UnderwaterNoMRT", 0);
|
||||
}
|
||||
|
||||
// Turn the entire scene (represented by the 'root' node) -90
|
||||
|
@ -121,6 +124,7 @@ RenderingManager::~RenderingManager ()
|
|||
delete mTerrainManager;
|
||||
delete mLocalMap;
|
||||
delete mOcclusionQuery;
|
||||
delete mCompositors;
|
||||
}
|
||||
|
||||
MWRender::SkyManager* RenderingManager::getSkyManager()
|
||||
|
@ -235,7 +239,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){
|
|||
&& !MWBase::Environment::get().getWorld()->getStore().lands.search(store->cell->data.gridX,store->cell->data.gridY) )) // always use water, if the cell does not have land.
|
||||
{
|
||||
if(mWater == 0)
|
||||
mWater = new MWRender::Water(mRendering.getCamera(), mSkyManager, store->cell);
|
||||
mWater = new MWRender::Water(mRendering.getCamera(), this, store->cell);
|
||||
else
|
||||
mWater->changeCell(store->cell);
|
||||
mWater->setActive(true);
|
||||
|
@ -295,35 +299,29 @@ void RenderingManager::skySetMoonColour (bool red){
|
|||
|
||||
bool RenderingManager::toggleRenderMode(int mode)
|
||||
{
|
||||
if (mode != MWWorld::World::Render_Wireframe)
|
||||
if (mode == MWWorld::World::Render_CollisionDebug || mode == MWWorld::World::Render_Pathgrid)
|
||||
return mDebugging->toggleRenderMode(mode);
|
||||
else // if (mode == MWWorld::World::Render_Wireframe)
|
||||
else if (mode == MWWorld::World::Render_Wireframe)
|
||||
{
|
||||
if (mRendering.getCamera()->getPolygonMode() == PM_SOLID)
|
||||
{
|
||||
// disable compositors
|
||||
if (useMRT())
|
||||
{
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", false);
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", false);
|
||||
}
|
||||
mCompositors->setEnabled(false);
|
||||
|
||||
mRendering.getCamera()->setPolygonMode(PM_WIREFRAME);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// re-enable compositors
|
||||
if (useMRT())
|
||||
{
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbuffer", true);
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mRendering.getViewport(), "gbufferFinalizer", true);
|
||||
}
|
||||
mCompositors->setEnabled(true);
|
||||
|
||||
mRendering.getCamera()->setPolygonMode(PM_SOLID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else //if (mode == MWWorld::World::Render_Compositors)
|
||||
{
|
||||
return mCompositors->toggle();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
|
||||
|
@ -529,13 +527,13 @@ Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds)
|
|||
|
||||
float min_x = 1.0f, max_x = 0.0f, min_y = 1.0f, max_y = 0.0f;
|
||||
|
||||
// expand the screen-space bounding-box so that it completely encloses
|
||||
// expand the screen-space bounding-box so that it completely encloses
|
||||
// the object's AABB
|
||||
for (int i=0; i<8; i++)
|
||||
{
|
||||
Ogre::Vector3 corner = corners[i];
|
||||
|
||||
// multiply the AABB corner vertex by the view matrix to
|
||||
// multiply the AABB corner vertex by the view matrix to
|
||||
// get a camera-space vertex
|
||||
corner = mat * corner;
|
||||
|
||||
|
@ -544,20 +542,25 @@ Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds)
|
|||
float x = corner.x / corner.z + 0.5;
|
||||
float y = corner.y / corner.z + 0.5;
|
||||
|
||||
if (x < min_x)
|
||||
if (x < min_x)
|
||||
min_x = x;
|
||||
|
||||
if (x > max_x)
|
||||
if (x > max_x)
|
||||
max_x = x;
|
||||
|
||||
if (y < min_y)
|
||||
if (y < min_y)
|
||||
min_y = y;
|
||||
|
||||
if (y > max_y)
|
||||
if (y > max_y)
|
||||
max_y = y;
|
||||
}
|
||||
|
||||
return Vector4(min_x, min_y, max_x, max_y);
|
||||
}
|
||||
|
||||
Compositors* RenderingManager::getCompositors()
|
||||
{
|
||||
return mCompositors;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace MWRender
|
|||
class ShaderHelper;
|
||||
class LocalMap;
|
||||
class Water;
|
||||
class Compositors;
|
||||
|
||||
class RenderingManager: private RenderingInterface {
|
||||
|
||||
|
@ -67,6 +68,7 @@ class RenderingManager: private RenderingInterface {
|
|||
/// to internal details of the rendering system anymore
|
||||
|
||||
SkyManager* getSkyManager();
|
||||
Compositors* getCompositors();
|
||||
|
||||
void toggleLight();
|
||||
bool toggleRenderMode(int mode);
|
||||
|
@ -196,6 +198,8 @@ class RenderingManager: private RenderingInterface {
|
|||
MWRender::Shadows* mShadows;
|
||||
|
||||
MWRender::ShaderHelper* mShaderHelper;
|
||||
|
||||
MWRender::Compositors* mCompositors;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ void ShaderHelper::createShader(const bool mrt, const bool shadows, const bool s
|
|||
outStream <<
|
||||
" float3 lightingFinal = lightColour.xyz * diffuse.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
|
||||
" float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n"
|
||||
" oColor.xyz = lerp(lightingFinal * tex.xyz * vertexColour.xyz, fogColour.xyz, fogValue); \n"
|
||||
" oColor.xyz = saturate(lerp(lightingFinal * tex.xyz * vertexColour.xyz, fogColour.xyz, fogValue)); \n" // saturate output to prevent negative output colors - TODO: replace this once there is HDR-rendering
|
||||
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n";
|
||||
|
||||
if (mrt) outStream <<
|
||||
|
|
|
@ -113,6 +113,7 @@ void BillboardObject::init(const String& textureName,
|
|||
p->setSelfIllumination(1.0,1.0,1.0);
|
||||
p->setDiffuse(0.0,0.0,0.0,1.0);
|
||||
p->setAmbient(0.0,0.0,0.0);
|
||||
p->setPolygonModeOverrideable(false);
|
||||
p->createTextureUnitState(textureName);
|
||||
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
|
||||
|
||||
|
@ -520,6 +521,7 @@ void SkyManager::create()
|
|||
mp->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
||||
mp->getTechnique(0)->getPass(0)->setVertexProgram(stars_vp->getName());
|
||||
mp->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName());
|
||||
mp->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
|
||||
mStarsMaterials[i] = mp;
|
||||
}
|
||||
|
||||
|
@ -535,6 +537,7 @@ void SkyManager::create()
|
|||
mAtmosphereDay = mRootNode->createChildSceneNode();
|
||||
mAtmosphereDay->attachObject(atmosphere_ent);
|
||||
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
|
||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
|
||||
|
||||
// Atmosphere shader
|
||||
HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
|
@ -598,6 +601,7 @@ void SkyManager::create()
|
|||
SceneNode* clouds_node = mRootNode->createChildSceneNode();
|
||||
clouds_node->attachObject(clouds_ent);
|
||||
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
|
||||
mCloudMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
|
||||
clouds_ent->setCastShadows(false);
|
||||
|
||||
// Clouds vertex shader
|
||||
|
|
|
@ -2,24 +2,20 @@
|
|||
#include <components/settings/settings.hpp>
|
||||
#include "sky.hpp"
|
||||
#include "renderingmanager.hpp"
|
||||
#include "compositors.hpp"
|
||||
|
||||
using namespace Ogre;
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
|
||||
Water::Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell) :
|
||||
Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) :
|
||||
mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()),
|
||||
mIsUnderwater(false), mVisibilityFlags(0),
|
||||
mReflectionTarget(0), mActive(1), mToggled(1),
|
||||
mReflectionRenderActive(false)
|
||||
mReflectionRenderActive(false), mRendering(rend)
|
||||
{
|
||||
mSky = sky;
|
||||
|
||||
try
|
||||
{
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false);
|
||||
} catch(...) {}
|
||||
mSky = rend->getSkyManager();
|
||||
|
||||
mTop = cell->water;
|
||||
|
||||
|
@ -147,8 +143,6 @@ Water::~Water()
|
|||
mWaterNode->detachObject(mWater);
|
||||
mSceneManager->destroyEntity(mWater);
|
||||
mSceneManager->destroySceneNode(mWaterNode);
|
||||
|
||||
CompositorManager::getSingleton().removeCompositorChain(mViewport);
|
||||
}
|
||||
|
||||
void Water::changeCell(const ESM::Cell* cell)
|
||||
|
@ -178,13 +172,13 @@ void Water::checkUnderwater(float y)
|
|||
{
|
||||
if (!mActive)
|
||||
{
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false);
|
||||
mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID)
|
||||
{
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, false);
|
||||
mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false);
|
||||
|
||||
// tell the shader we are not underwater
|
||||
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);
|
||||
|
@ -199,7 +193,7 @@ void Water::checkUnderwater(float y)
|
|||
if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID)
|
||||
{
|
||||
if (mUnderwaterEffect)
|
||||
CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCompositorName, true);
|
||||
mRendering->getCompositors()->setCompositorEnabled(mCompositorName, true);
|
||||
|
||||
// tell the shader we are underwater
|
||||
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
namespace MWRender {
|
||||
|
||||
class SkyManager;
|
||||
class RenderingManager;
|
||||
|
||||
/// Water rendering
|
||||
class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener
|
||||
|
@ -40,6 +41,7 @@ namespace MWRender {
|
|||
|
||||
void updateVisible();
|
||||
|
||||
RenderingManager* mRendering;
|
||||
SkyManager* mSky;
|
||||
|
||||
std::string mCompositorName;
|
||||
|
@ -55,7 +57,7 @@ namespace MWRender {
|
|||
int mVisibilityFlags;
|
||||
|
||||
public:
|
||||
Water (Ogre::Camera *camera, SkyManager* sky, const ESM::Cell* cell);
|
||||
Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell);
|
||||
~Water();
|
||||
|
||||
void setActive(bool active);
|
||||
|
|
|
@ -146,4 +146,4 @@ op 0x200014f: ForceGreeting
|
|||
op 0x2000150: ForceGreeting, explicit reference
|
||||
op 0x2000151: ToggleFullHelp
|
||||
op 0x2000152: Goodbye
|
||||
opcodes 0x2000153-0x3ffffff unused
|
||||
opcodes 0x2000154-0x3ffffff unused
|
||||
|
|
|
@ -66,7 +66,8 @@ namespace MWWorld
|
|||
{
|
||||
Render_CollisionDebug,
|
||||
Render_Wireframe,
|
||||
Render_Pathgrid
|
||||
Render_Pathgrid,
|
||||
Render_Compositors
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -326,6 +326,8 @@ void NIFLoader::createMaterial(const String &name,
|
|||
{
|
||||
material->getTechnique(0)->getPass(0)->setVertexProgram("main_vp");
|
||||
material->getTechnique(0)->getPass(0)->setFragmentProgram("main_fp");
|
||||
|
||||
material->getTechnique(0)->getPass(0)->setFog(true); // force-disable fixed function fog, it is calculated in shader
|
||||
}
|
||||
|
||||
// Create a fallback technique without shadows and without mrt
|
||||
|
@ -338,6 +340,7 @@ void NIFLoader::createMaterial(const String &name,
|
|||
{
|
||||
pass2->setVertexProgram("main_fallback_vp");
|
||||
pass2->setFragmentProgram("main_fallback_fp");
|
||||
pass2->setFog(true); // force-disable fixed function fog, it is calculated in shader
|
||||
}
|
||||
|
||||
// Add material bells and whistles
|
||||
|
|
|
@ -1,67 +1,73 @@
|
|||
vertex_program depth_shadow_caster_vs cg
|
||||
{
|
||||
source depthshadowcaster.cg
|
||||
profiles vs_1_1 arbvp1
|
||||
entry_point main_vp
|
||||
source depthshadowcaster.cg
|
||||
profiles vs_1_1 arbvp1
|
||||
entry_point main_vp
|
||||
|
||||
default_params
|
||||
{
|
||||
param_named_auto wvpMat worldviewproj_matrix
|
||||
}
|
||||
default_params
|
||||
{
|
||||
param_named_auto wvpMat worldviewproj_matrix
|
||||
}
|
||||
}
|
||||
|
||||
fragment_program depth_shadow_caster_ps cg
|
||||
{
|
||||
source depthshadowcaster.cg
|
||||
profiles ps_2_0 arbfp1
|
||||
entry_point main_fp
|
||||
source depthshadowcaster.cg
|
||||
profiles ps_2_0 arbfp1
|
||||
entry_point main_fp
|
||||
|
||||
default_params
|
||||
{
|
||||
}
|
||||
default_params
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
fragment_program depth_shadow_caster_ps_noalpha cg
|
||||
{
|
||||
source depthshadowcaster.cg
|
||||
profiles ps_2_0 arbfp1
|
||||
entry_point main_fp_noalpha
|
||||
source depthshadowcaster.cg
|
||||
profiles ps_2_0 arbfp1
|
||||
entry_point main_fp_noalpha
|
||||
|
||||
default_params
|
||||
{
|
||||
}
|
||||
default_params
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
material depth_shadow_caster
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_program_ref depth_shadow_caster_vs
|
||||
{
|
||||
}
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
// force-disable fog (relevant for DirectX profiles below SM3 that always apply fixed function fog)
|
||||
fog_override true
|
||||
|
||||
fragment_program_ref depth_shadow_caster_ps
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
vertex_program_ref depth_shadow_caster_vs
|
||||
{
|
||||
}
|
||||
|
||||
fragment_program_ref depth_shadow_caster_ps
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material depth_shadow_caster_noalpha
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_program_ref depth_shadow_caster_vs
|
||||
{
|
||||
}
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
// force-disable fog (relevant for DirectX profiles below SM3 that always apply fixed function fog)
|
||||
fog_override true
|
||||
|
||||
fragment_program_ref depth_shadow_caster_ps_noalpha
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
vertex_program_ref depth_shadow_caster_vs
|
||||
{
|
||||
}
|
||||
|
||||
fragment_program_ref depth_shadow_caster_ps_noalpha
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue