Merge branch 'master' into physicsaedra2
Conflicts: apps/openmw/mwworld/player.cppactorid
commit
f2fae770d4
@ -0,0 +1,16 @@
|
||||
#include "cursorreplace.hpp"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <openengine/ogre/imagerotate.hpp>
|
||||
|
||||
#include <OgreResourceGroupManager.h>
|
||||
#include <OgreRoot.h>
|
||||
|
||||
using namespace MWGui;
|
||||
|
||||
CursorReplace::CursorReplace()
|
||||
{
|
||||
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_vresize.png", 90);
|
||||
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize1.png", -45);
|
||||
OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize2.png", 45);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
#ifndef GAME_CURSORREPLACE_H
|
||||
#define GAME_CURSORREPLACE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
/// \brief MyGUI does not support rotating cursors, so we have to do it manually
|
||||
class CursorReplace
|
||||
{
|
||||
public:
|
||||
CursorReplace();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,11 @@
|
||||
#ifndef GAME_MWMECHANICS_DRAWSTATE_H
|
||||
#define GAME_MWMECHANICS_DRAWSTATE_H
|
||||
|
||||
enum DrawState
|
||||
{
|
||||
DrawState_Weapon = 0,
|
||||
DrawState_Spell = 1,
|
||||
DrawState_Nothing = 2,
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,81 @@
|
||||
|
||||
#include "spells.hpp"
|
||||
|
||||
#include <components/esm/loadspel.hpp>
|
||||
|
||||
#include "../mwworld/environment.hpp"
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "magiceffects.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
void Spells::addSpell (const ESM::Spell *spell, MagicEffects& effects) const
|
||||
{
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter = spell->effects.list.begin();
|
||||
iter!=spell->effects.list.end(); ++iter)
|
||||
{
|
||||
EffectParam param;
|
||||
param.mMagnitude = iter->magnMax; /// \todo calculate magnitude
|
||||
effects.add (EffectKey (*iter), param);
|
||||
}
|
||||
}
|
||||
|
||||
Spells::TIterator Spells::begin() const
|
||||
{
|
||||
return mSpells.begin();
|
||||
}
|
||||
|
||||
Spells::TIterator Spells::end() const
|
||||
{
|
||||
return mSpells.end();
|
||||
}
|
||||
|
||||
void Spells::add (const std::string& spellId)
|
||||
{
|
||||
if (std::find (mSpells.begin(), mSpells.end(), spellId)!=mSpells.end())
|
||||
mSpells.push_back (spellId);
|
||||
}
|
||||
|
||||
void Spells::remove (const std::string& spellId)
|
||||
{
|
||||
TContainer::iterator iter = std::find (mSpells.begin(), mSpells.end(), spellId);
|
||||
|
||||
if (iter!=mSpells.end())
|
||||
mSpells.erase (iter);
|
||||
|
||||
if (spellId==mSelectedSpell)
|
||||
mSelectedSpell.clear();
|
||||
}
|
||||
|
||||
MagicEffects Spells::getMagicEffects (const MWWorld::Environment& environment) const
|
||||
{
|
||||
MagicEffects effects;
|
||||
|
||||
for (TIterator iter = mSpells.begin(); iter!=mSpells.end(); ++iter)
|
||||
{
|
||||
const ESM::Spell *spell = environment.mWorld->getStore().spells.find (*iter);
|
||||
|
||||
if (spell->data.type==ESM::Spell::ST_Ability || spell->data.type==ESM::Spell::ST_Blight ||
|
||||
spell->data.type==ESM::Spell::ST_Disease || spell->data.type==ESM::Spell::ST_Curse)
|
||||
addSpell (spell, effects);
|
||||
}
|
||||
|
||||
return effects;
|
||||
}
|
||||
|
||||
void Spells::clear()
|
||||
{
|
||||
mSpells.clear();
|
||||
}
|
||||
|
||||
void Spells::setSelectedSpell (const std::string& spellId)
|
||||
{
|
||||
mSelectedSpell = spellId;
|
||||
}
|
||||
|
||||
const std::string Spells::getSelectedSpell() const
|
||||
{
|
||||
return mSelectedSpell;
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
#ifndef GAME_MWMECHANICS_SPELLS_H
|
||||
#define GAME_MWMECHANICS_SPELLS_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
struct Spell;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
struct Environment;
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
class MagicEffects;
|
||||
|
||||
/// \brief Spell list
|
||||
///
|
||||
/// This class manages known spells as well as abilities, powers and permanent negative effects like
|
||||
/// diseaes.
|
||||
class Spells
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::vector<std::string> TContainer;
|
||||
typedef TContainer::const_iterator TIterator;
|
||||
|
||||
private:
|
||||
|
||||
std::vector<std::string> mSpells;
|
||||
std::string mSelectedSpell;
|
||||
|
||||
void addSpell (const ESM::Spell *, MagicEffects& effects) const;
|
||||
|
||||
public:
|
||||
|
||||
TIterator begin() const;
|
||||
|
||||
TIterator end() const;
|
||||
|
||||
void add (const std::string& spell);
|
||||
///< Adding a spell that is already listed in *this is a no-op.
|
||||
|
||||
void remove (const std::string& spell);
|
||||
///< If the spell to be removed is the selected spell, the selected spell will be changed to
|
||||
/// no spell (empty string).
|
||||
|
||||
MagicEffects getMagicEffects (const MWWorld::Environment& environment) const;
|
||||
///< Return sum of magic effects resulting from abilities, blights, deseases and curses.
|
||||
|
||||
void clear();
|
||||
///< Remove all spells of al types.
|
||||
|
||||
void setSelectedSpell (const std::string& spellId);
|
||||
///< This function does not verify, if the spell is available.
|
||||
|
||||
const std::string getSelectedSpell() const;
|
||||
///< May return an empty string.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,62 @@
|
||||
#ifndef GAME_RENDER_CONST_H
|
||||
#define GAME_RENDER_CONST_H
|
||||
|
||||
#include <OgreRenderQueue.h>
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
|
||||
// Render queue groups
|
||||
enum RenderQueueGroups
|
||||
{
|
||||
// Sky early (atmosphere, clouds, moons)
|
||||
RQG_SkiesEarly = Ogre::RENDER_QUEUE_SKIES_EARLY,
|
||||
|
||||
RQG_Main = Ogre::RENDER_QUEUE_MAIN,
|
||||
|
||||
RQG_Water = Ogre::RENDER_QUEUE_7+1,
|
||||
|
||||
RQG_Alpha = Ogre::RENDER_QUEUE_MAIN,
|
||||
|
||||
RQG_UnderWater = Ogre::RENDER_QUEUE_7+1,
|
||||
|
||||
RQG_OcclusionQuery = Ogre::RENDER_QUEUE_8,
|
||||
|
||||
// Sky late (sun & sun flare)
|
||||
RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE
|
||||
};
|
||||
|
||||
// Visibility flags
|
||||
enum VisibilityFlags
|
||||
{
|
||||
// Terrain
|
||||
RV_Terrain = 1,
|
||||
|
||||
// Statics (e.g. trees, houses)
|
||||
RV_Statics = 2,
|
||||
|
||||
// Small statics
|
||||
RV_StaticsSmall = 4,
|
||||
|
||||
// Water
|
||||
RV_Water = 8,
|
||||
|
||||
// Actors (player, npcs, creatures)
|
||||
RV_Actors = 16,
|
||||
|
||||
// Misc objects (containers, dynamic objects)
|
||||
RV_Misc = 32,
|
||||
|
||||
RV_Sky = 64,
|
||||
|
||||
// Sun glare (not visible in reflection)
|
||||
RV_Glare = 128,
|
||||
|
||||
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water,
|
||||
|
||||
/// \todo markers (normally hidden)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,308 @@
|
||||
#include "shaderhelper.hpp"
|
||||
#include "renderingmanager.hpp"
|
||||
#include "shadows.hpp"
|
||||
|
||||
#include <OgreHighLevelGpuProgramManager.h>
|
||||
#include <OgreHighLevelGpuProgram.h>
|
||||
#include <OgreGpuProgramParams.h>
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
using namespace Ogre;
|
||||
using namespace MWRender;
|
||||
|
||||
ShaderHelper::ShaderHelper(RenderingManager* rend)
|
||||
{
|
||||
mRendering = rend;
|
||||
applyShaders();
|
||||
}
|
||||
|
||||
void ShaderHelper::applyShaders()
|
||||
{
|
||||
if (!Settings::Manager::getBool("shaders", "Objects")) return;
|
||||
|
||||
bool mrt = RenderingManager::useMRT();
|
||||
bool shadows = Settings::Manager::getBool("enabled", "Shadows");
|
||||
bool split = Settings::Manager::getBool("split", "Shadows");
|
||||
|
||||
// shader for normal rendering
|
||||
createShader(mrt, shadows, split, "main");
|
||||
|
||||
// fallback shader without mrt and without shadows
|
||||
// (useful for reflection and for minimap)
|
||||
createShader(false, false, false, "main_fallback");
|
||||
}
|
||||
|
||||
void ShaderHelper::createShader(const bool mrt, const bool shadows, const bool split, const std::string& name)
|
||||
{
|
||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
||||
|
||||
const int numsplits = 3;
|
||||
|
||||
// the number of lights to support.
|
||||
// when rendering an object, OGRE automatically picks the lights that are
|
||||
// closest to the object being rendered. unfortunately this mechanism does
|
||||
// not work perfectly for objects batched together (they will all use the same
|
||||
// lights). to work around this, we are simply pushing the maximum number
|
||||
// of lights here in order to minimize disappearing lights.
|
||||
int num_lights = Settings::Manager::getInt("num lights", "Objects");
|
||||
|
||||
{
|
||||
// vertex
|
||||
HighLevelGpuProgramPtr vertex;
|
||||
if (!mgr.getByName(name+"_vp").isNull())
|
||||
mgr.remove(name+"_vp");
|
||||
|
||||
vertex = mgr.createProgram(name+"_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
"cg", GPT_VERTEX_PROGRAM);
|
||||
vertex->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1");
|
||||
vertex->setParameter("entry_point", "main_vp");
|
||||
StringUtil::StrStreamType outStream;
|
||||
outStream <<
|
||||
"void main_vp( \n"
|
||||
" float4 position : POSITION, \n"
|
||||
" float4 normal : NORMAL, \n"
|
||||
" float4 colour : COLOR, \n"
|
||||
" in float2 uv : TEXCOORD0, \n"
|
||||
" out float2 oUV : TEXCOORD0, \n"
|
||||
" out float4 oPosition : POSITION, \n"
|
||||
" out float4 oPositionObjSpace : TEXCOORD1, \n"
|
||||
" out float4 oNormal : TEXCOORD2, \n"
|
||||
" out float oDepth : TEXCOORD3, \n"
|
||||
" out float4 oVertexColour : TEXCOORD4, \n";
|
||||
if (shadows && !split) outStream <<
|
||||
" out float4 oLightSpacePos0 : TEXCOORD5, \n"
|
||||
" uniform float4x4 worldMatrix, \n"
|
||||
" uniform float4x4 texViewProjMatrix0, \n";
|
||||
else
|
||||
{
|
||||
for (int i=0; i<numsplits; ++i)
|
||||
{
|
||||
outStream <<
|
||||
" out float4 oLightSpacePos"<<i<<" : TEXCOORD"<<i+5<<", \n"
|
||||
" uniform float4x4 texViewProjMatrix"<<i<<", \n";
|
||||
}
|
||||
outStream <<
|
||||
" uniform float4x4 worldMatrix, \n";
|
||||
}
|
||||
outStream <<
|
||||
" uniform float4x4 worldViewProj \n"
|
||||
") \n"
|
||||
"{ \n"
|
||||
" oVertexColour = colour; \n"
|
||||
" oUV = uv; \n"
|
||||
" oNormal = normal; \n"
|
||||
" oPosition = mul( worldViewProj, position ); \n"
|
||||
" oDepth = oPosition.z; \n"
|
||||
" oPositionObjSpace = position; \n";
|
||||
if (shadows && !split) outStream <<
|
||||
" oLightSpacePos0 = mul(texViewProjMatrix0, mul(worldMatrix, position)); \n";
|
||||
else
|
||||
{
|
||||
outStream <<
|
||||
" float4 wPos = mul(worldMatrix, position); \n";
|
||||
for (int i=0; i<numsplits; ++i)
|
||||
{
|
||||
outStream <<
|
||||
" oLightSpacePos"<<i<<" = mul(texViewProjMatrix"<<i<<", wPos); \n";
|
||||
}
|
||||
}
|
||||
outStream <<
|
||||
"}";
|
||||
vertex->setSource(outStream.str());
|
||||
vertex->load();
|
||||
vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
||||
if (shadows)
|
||||
{
|
||||
vertex->getDefaultParameters()->setNamedAutoConstant("worldMatrix", GpuProgramParameters::ACT_WORLD_MATRIX);
|
||||
if (!split)
|
||||
vertex->getDefaultParameters()->setNamedAutoConstant("texViewProjMatrix0", GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, 0);
|
||||
else
|
||||
{
|
||||
for (int i=0; i<numsplits; ++i)
|
||||
{
|
||||
vertex->getDefaultParameters()->setNamedAutoConstant("texViewProjMatrix"+StringConverter::toString(i), GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// fragment
|
||||
HighLevelGpuProgramPtr fragment;
|
||||
if (!mgr.getByName(name+"_fp").isNull())
|
||||
mgr.remove(name+"_fp");
|
||||
|
||||
fragment = mgr.createProgram(name+"_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
"cg", GPT_FRAGMENT_PROGRAM);
|
||||
fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1");
|
||||
fragment->setParameter("entry_point", "main_fp");
|
||||
StringUtil::StrStreamType outStream;
|
||||
|
||||
if (shadows) outStream <<
|
||||
"float depthShadow(sampler2D shadowMap, float4 shadowMapPos, float2 offset) \n"
|
||||
"{ \n"
|
||||
" shadowMapPos /= shadowMapPos.w; \n"
|
||||
" float3 o = float3(offset.xy, -offset.x) * 0.3f; \n"
|
||||
" float c = (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy - o.xy).r) ? 1 : 0; // top left \n"
|
||||
" c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy + o.xy).r) ? 1 : 0; // bottom right \n"
|
||||
" c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy + o.zy).r) ? 1 : 0; // bottom left \n"
|
||||
" c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy - o.zy).r) ? 1 : 0; // top right \n"
|
||||
" return c / 4; \n"
|
||||
"} \n";
|
||||
|
||||
outStream <<
|
||||
"void main_fp( \n"
|
||||
" in float2 uv : TEXCOORD0, \n"
|
||||
" out float4 oColor : COLOR, \n"
|
||||
" uniform sampler2D texture : register(s0), \n"
|
||||
" float4 positionObjSpace : TEXCOORD1, \n"
|
||||
" float4 normal : TEXCOORD2, \n"
|
||||
" float iDepth : TEXCOORD3, \n"
|
||||
" float4 vertexColour : TEXCOORD4, \n"
|
||||
" uniform float4 fogColour, \n"
|
||||
" uniform float4 fogParams, \n";
|
||||
|
||||
if (shadows) outStream <<
|
||||
" uniform float4 shadowFar_fadeStart, \n";
|
||||
|
||||
if (shadows && !split) outStream <<
|
||||
" uniform sampler2D shadowMap : register(s1), \n"
|
||||
" float4 lightSpacePos0 : TEXCOORD5, \n"
|
||||
" uniform float4 invShadowmapSize0, \n";
|
||||
else
|
||||
{
|
||||
outStream <<
|
||||
" uniform float4 pssmSplitPoints, \n";
|
||||
for (int i=0; i<numsplits; ++i)
|
||||
{
|
||||
outStream <<
|
||||
" uniform sampler2D shadowMap"<<i<<" : register(s"<<i+1<<"), \n"
|
||||
" float4 lightSpacePos"<<i<<" : TEXCOORD"<<i+5<<", \n"
|
||||
" uniform float4 invShadowmapSize"<<i<<", \n";
|
||||
}
|
||||
}
|
||||
|
||||
if (mrt) outStream <<
|
||||
" out float4 oColor1 : COLOR1, \n"
|
||||
" uniform float far, \n";
|
||||
|
||||
for (int i=0; i<num_lights; ++i)
|
||||
{
|
||||
outStream <<
|
||||
" uniform float4 lightDiffuse"<<i<<", \n"
|
||||
" uniform float4 lightPositionObjSpace"<<i<<", \n"
|
||||
" uniform float4 lightAttenuation"<<i<<", \n";
|
||||
}
|
||||
outStream <<
|
||||
" uniform float4 lightAmbient, \n"
|
||||
" uniform float4 ambient, \n"
|
||||
" uniform float4 diffuse, \n"
|
||||
" uniform float4 emissive \n"
|
||||
") \n"
|
||||
"{ \n"
|
||||
" float4 tex = tex2D(texture, uv); \n"
|
||||
" float d; \n"
|
||||
" float attn; \n"
|
||||
" float3 lightDir; \n"
|
||||
" float3 lightColour = float3(0, 0, 0); \n";
|
||||
|
||||
for (int i=0; i<num_lights; ++i)
|
||||
{
|
||||
outStream <<
|
||||
" lightDir = lightPositionObjSpace"<<i<<".xyz - (positionObjSpace.xyz * lightPositionObjSpace"<<i<<".w); \n"
|
||||
|
||||
// pre-multiply light color with attenuation factor
|
||||
" d = length( lightDir ); \n"
|
||||
" attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
|
||||
" lightDiffuse"<<i<<" *= attn; \n";
|
||||
|
||||
if (i == 0 && shadows)
|
||||
{
|
||||
outStream <<
|
||||
" float shadow; \n";
|
||||
if (!split) outStream <<
|
||||
" shadow = depthShadow(shadowMap, lightSpacePos0, invShadowmapSize0.xy); \n";
|
||||
else
|
||||
{
|
||||
for (int j=0; j<numsplits; ++j)
|
||||
{
|
||||
std::string channel;
|
||||
if (j==0) channel = "x";
|
||||
else if (j==1) channel = "y";
|
||||
else if (j==2) channel = "z";
|
||||
|
||||
if (j==0)
|
||||
outStream << " if (iDepth <= pssmSplitPoints." << channel << ") \n";
|
||||
else if (j < numsplits - 1)
|
||||
outStream << " else if (iDepth <= pssmSplitPoints." << channel << ") \n";
|
||||
else
|
||||
outStream << " else \n";
|
||||
|
||||
outStream <<
|
||||
" { \n"
|
||||
" shadow = depthShadow(shadowMap" << j << ", lightSpacePos" << j << ", invShadowmapSize" << j << ".xy); \n"
|
||||
" } \n";
|
||||
}
|
||||
}
|
||||
outStream <<
|
||||
" float fadeRange = shadowFar_fadeStart.x - shadowFar_fadeStart.y; \n"
|
||||
" float fade = 1-((iDepth - shadowFar_fadeStart.y) / fadeRange); \n"
|
||||
" shadow = (iDepth > shadowFar_fadeStart.x) ? 1 : ((iDepth > shadowFar_fadeStart.y) ? 1-((1-shadow)*fade) : shadow); \n"
|
||||
" lightColour.xyz += shadow * lit(dot(normalize(lightDir), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
|
||||
}
|
||||
else outStream <<
|
||||
" lightColour.xyz += lit(dot(normalize(lightDir), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
|
||||
}
|
||||
|
||||
outStream <<
|
||||
" float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
|
||||
" float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n"
|
||||
" oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour.xyz, fogValue); \n"
|
||||
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n";
|
||||
|
||||
if (mrt) outStream <<
|
||||
" oColor1 = float4(iDepth / far, 0, 0, (oColor.a == 1)); \n"; // only write to MRT if alpha is 1
|
||||
|
||||
outStream <<
|
||||
"}";
|
||||
fragment->setSource(outStream.str());
|
||||
fragment->load();
|
||||
|
||||
for (int i=0; i<num_lights; ++i)
|
||||
{
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
|
||||
}
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
|
||||
|
||||
if (shadows)
|
||||
{
|
||||
fragment->getDefaultParameters()->setNamedConstant("shadowFar_fadeStart", Vector4(mRendering->getShadows()->getShadowFar(), mRendering->getShadows()->getFadeStart()*mRendering->getShadows()->getShadowFar(), 0, 0));
|
||||
for (int i=0; i < (split ? numsplits : 1); ++i)
|
||||
{
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("invShadowmapSize" + StringConverter::toString(i), GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i+1);
|
||||
}
|
||||
if (split)
|
||||
{
|
||||
Vector4 splitPoints;
|
||||
const PSSMShadowCameraSetup::SplitPointList& splitPointList = mRendering->getShadows()->getPSSMSetup()->getSplitPoints();
|
||||
// Populate from split point 1, not 0, since split 0 isn't useful (usually 0)
|
||||
for (int i = 1; i < numsplits; ++i)
|
||||
{
|
||||
splitPoints[i-1] = splitPointList[i];
|
||||
}
|
||||
fragment->getDefaultParameters()->setNamedConstant("pssmSplitPoints", splitPoints);
|
||||
}
|
||||
}
|
||||
|
||||
if (mrt)
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
#ifndef GAME_SHADERHELPER_H
|
||||
#define GAME_SHADERHELPER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class RenderingManager;
|
||||
|
||||
///
|
||||
/// \brief manages the main shader
|
||||
///
|
||||
class ShaderHelper
|
||||
{
|
||||
public:
|
||||
ShaderHelper(RenderingManager* rend);
|
||||
|
||||
void applyShaders();
|
||||
///< apply new settings
|
||||
|
||||
private:
|
||||
RenderingManager* mRendering;
|
||||
|
||||
void createShader(const bool mrt, const bool shadows, const bool split, const std::string& name);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,173 @@
|
||||
#include "shadows.hpp"
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
#include <openengine/ogre/renderer.hpp>
|
||||
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreColourValue.h>
|
||||
#include <OgreShadowCameraSetupLiSPSM.h>
|
||||
#include <OgreShadowCameraSetupPSSM.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
|
||||
#include <OgreOverlayContainer.h>
|
||||
#include <OgreOverlayManager.h>
|
||||
|
||||
#include "renderconst.hpp"
|
||||
|
||||
using namespace Ogre;
|
||||
using namespace MWRender;
|
||||
|
||||
Shadows::Shadows(OEngine::Render::OgreRenderer* rend) :
|
||||
mShadowFar(1000), mFadeStart(0.9)
|
||||
{
|
||||
mRendering = rend;
|
||||
mSceneMgr = mRendering->getScene();
|
||||
recreate();
|
||||
}
|
||||
|
||||
void Shadows::recreate()
|
||||
{
|
||||
bool enabled = Settings::Manager::getBool("enabled", "Shadows");
|
||||
|
||||
// Split shadow maps are currently disabled because the terrain cannot cope with them
|
||||
// (Too many texture units) Solution would be a multi-pass terrain material
|
||||
bool split = Settings::Manager::getBool("split", "Shadows");
|
||||
//const bool split = false;
|
||||
|
||||
if (!enabled)
|
||||
{
|
||||
mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
int texsize = Settings::Manager::getInt("texture size", "Shadows");
|
||||
mSceneMgr->setShadowTextureSize(texsize);
|
||||
|
||||
mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED);
|
||||
|
||||
// no point light shadows, i'm afraid. might revisit this with Deferred Shading
|
||||
mSceneMgr->setShadowTextureCountPerLightType(Light::LT_POINT, 0);
|
||||
|
||||
mSceneMgr->setShadowTextureCountPerLightType(Light::LT_DIRECTIONAL, split ? 3 : 1);
|
||||
mSceneMgr->setShadowTextureCount(split ? 3 : 1);
|
||||
|
||||
mSceneMgr->setShadowTextureSelfShadow(true);
|
||||
mSceneMgr->setShadowCasterRenderBackFaces(true);
|
||||
mSceneMgr->setShadowTextureCasterMaterial("depth_shadow_caster");
|
||||
mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R);
|
||||
mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000000);
|
||||
|
||||
mShadowFar = split ? Settings::Manager::getInt("split shadow distance", "Shadows") : Settings::Manager::getInt("shadow distance", "Shadows");
|
||||
mSceneMgr->setShadowFarDistance(mShadowFar);
|
||||
|
||||
mFadeStart = Settings::Manager::getFloat("fade start", "Shadows");
|
||||
|
||||
ShadowCameraSetupPtr shadowCameraSetup;
|
||||
if (split)
|
||||
{
|
||||
mPSSMSetup = new PSSMShadowCameraSetup();
|
||||
mPSSMSetup->setSplitPadding(5);
|
||||
mPSSMSetup->calculateSplitPoints(3, mRendering->getCamera()->getNearClipDistance(), mShadowFar);
|
||||
|
||||
const Real adjustFactors[3] = {64, 64, 64};
|
||||
for (int i=0; i < 3; ++i)
|
||||
{
|
||||
mPSSMSetup->setOptimalAdjustFactor(i, adjustFactors[i]);
|
||||
/*if (i==0)
|
||||
mSceneMgr->setShadowTextureConfig(i, texsize, texsize, Ogre::PF_FLOAT32_R);
|
||||
else if (i ==1)
|
||||
mSceneMgr->setShadowTextureConfig(i, texsize/2, texsize/2, Ogre::PF_FLOAT32_R);
|
||||
else if (i ==2)
|
||||
mSceneMgr->setShadowTextureConfig(i, texsize/4, texsize/4, Ogre::PF_FLOAT32_R);*/
|
||||
}
|
||||
|
||||
shadowCameraSetup = ShadowCameraSetupPtr(mPSSMSetup);
|
||||
}
|
||||
else
|
||||
{
|
||||
LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup();
|
||||
lispsmSetup->setOptimalAdjustFactor(2);
|
||||
//lispsmSetup->setCameraLightDirectionThreshold(Degree(0));
|
||||
//lispsmSetup->setUseAggressiveFocusRegion(false);
|
||||
shadowCameraSetup = ShadowCameraSetupPtr(lispsmSetup);
|
||||
}
|
||||
mSceneMgr->setShadowCameraSetup(shadowCameraSetup);
|
||||
|
||||
// Set visibility mask for the shadow render textures
|
||||
int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows")
|
||||
+ (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows")
|
||||
+ RV_Misc * Settings::Manager::getBool("misc shadows", "Shadows");
|
||||
|
||||
for (int i = 0; i < (split ? 3 : 1); ++i)
|
||||
{
|
||||
TexturePtr shadowTexture = mSceneMgr->getShadowTexture(i);
|
||||
Viewport* vp = shadowTexture->getBuffer()->getRenderTarget()->getViewport(0);
|
||||
vp->setVisibilityMask(visibilityMask);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// --------------------------- Debug overlays to display the content of shadow maps -----------------------------------
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
OverlayManager& mgr = OverlayManager::getSingleton();
|
||||
Overlay* overlay;
|
||||
|
||||
// destroy if already exists
|
||||
if (overlay = mgr.getByName("DebugOverlay"))
|
||||
mgr.destroy(overlay);
|
||||
|
||||
overlay = mgr.create("DebugOverlay");
|
||||
for (size_t i = 0; i < (split ? 3 : 1); ++i) {
|
||||
TexturePtr tex = mRendering->getScene()->getShadowTexture(i);
|
||||
|
||||
// Set up a debug panel to display the shadow
|
||||
|
||||
if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + StringConverter::toString(i)))
|
||||
MaterialManager::getSingleton().remove("Ogre/DebugTexture" + StringConverter::toString(i));
|
||||
MaterialPtr debugMat = MaterialManager::getSingleton().create(
|
||||
"Ogre/DebugTexture" + StringConverter::toString(i),
|
||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
|
||||
debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
||||
TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
|
||||
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
|
||||
|
||||
OverlayContainer* debugPanel;
|
||||
|
||||
// destroy container if exists
|
||||
try
|
||||
{
|
||||
if (debugPanel =
|
||||
static_cast<OverlayContainer*>(
|
||||
mgr.getOverlayElement("Ogre/DebugTexPanel" + StringConverter::toString(i)
|
||||
)))
|
||||
mgr.destroyOverlayElement(debugPanel);
|
||||
}
|
||||
catch (Ogre::Exception&) {}
|
||||
|
||||
debugPanel = (OverlayContainer*)
|
||||
(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
|
||||
debugPanel->_setPosition(0.8, i*0.25);
|
||||
debugPanel->_setDimensions(0.2, 0.24);
|
||||
debugPanel->setMaterialName(debugMat->getName());
|
||||
debugPanel->show();
|
||||
overlay->add2D(debugPanel);
|
||||
overlay->show();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
PSSMShadowCameraSetup* Shadows::getPSSMSetup()
|
||||
{
|
||||
return mPSSMSetup;
|
||||
}
|
||||
|
||||
float Shadows::getShadowFar() const
|
||||
{
|
||||
return mShadowFar;
|
||||
}
|
||||
|
||||
float Shadows::getFadeStart() const
|
||||
{
|
||||
return mFadeStart;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
#ifndef GAME_SHADOWS_H
|
||||
#define GAME_SHADOWS_H
|
||||
|
||||
// forward declares
|
||||
namespace Ogre
|
||||
{
|
||||
class SceneManager;
|
||||
class PSSMShadowCameraSetup;
|
||||
}
|
||||
namespace OEngine{
|
||||
namespace Render{
|
||||
class OgreRenderer;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class Shadows
|
||||
{
|
||||
public:
|
||||
Shadows(OEngine::Render::OgreRenderer* rend);
|
||||
|
||||
void recreate();
|
||||
|
||||
Ogre::PSSMShadowCameraSetup* getPSSMSetup();
|
||||
float getShadowFar() const;
|
||||
float getFadeStart() const;
|
||||
|
||||
protected:
|
||||
OEngine::Render::OgreRenderer* mRendering;
|
||||
Ogre::SceneManager* mSceneMgr;
|
||||
|
||||
Ogre::PSSMShadowCameraSetup* mPSSMSetup;
|
||||
float mShadowFar;
|
||||
float mFadeStart;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,37 @@
|
||||
#include "nifoverrides.hpp"
|
||||
|
||||
#include <OgreStringConverter.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
using namespace NifOverrides;
|
||||
|
||||
Ogre::ConfigFile Overrides::mTransparencyOverrides = Ogre::ConfigFile();
|
||||
|
||||
void Overrides::loadTransparencyOverrides (const std::string& file)
|
||||
{
|
||||
mTransparencyOverrides.load(file);
|
||||
}
|
||||
|
||||
TransparencyResult Overrides::getTransparencyOverride(const std::string& texture)
|
||||
{
|
||||
TransparencyResult result;
|
||||
result.first = false;
|
||||
|
||||
std::string tex = texture;
|
||||
boost::to_lower(tex);
|
||||
|
||||
Ogre::ConfigFile::SectionIterator seci = mTransparencyOverrides.getSectionIterator();
|
||||
while (seci.hasMoreElements())
|
||||
{
|
||||
Ogre::String sectionName = seci.peekNextKey();
|
||||
if (sectionName == tex)
|
||||
{
|
||||
result.first = true;
|
||||
result.second = Ogre::StringConverter::parseInt(mTransparencyOverrides.getSetting("alphaRejectValue", sectionName));
|
||||
break;
|
||||
}
|
||||
seci.getNext();
|
||||
}
|
||||
return result;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
#ifndef COMPONENTS_NIFOVERRIDES_H
|
||||
#define COMPONENTS_NIFOVERRIDES_H
|
||||
|
||||
#include <OgreConfigFile.h>
|
||||
|
||||
namespace NifOverrides
|
||||
{
|
||||
|
||||
typedef std::pair<bool, int> TransparencyResult;
|
||||
|
||||
/// \brief provide overrides for some model / texture properties that bethesda has chosen poorly
|
||||
class Overrides
|
||||
{
|
||||
public:
|
||||
static Ogre::ConfigFile mTransparencyOverrides;
|
||||
void loadTransparencyOverrides (const std::string& file);
|
||||
|
||||
static TransparencyResult getTransparencyOverride(const std::string& texture);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,13 +1,16 @@
|
||||
project(resources)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/caustic_0.png "${OpenMW_BINARY_DIR}/resources/water/caustic_0.png" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Example_Fresnel.cg "${OpenMW_BINARY_DIR}/resources/water/Example_Fresnel.cg" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Example_FresnelPS.asm "${OpenMW_BINARY_DIR}/resources/water/Example_FresnelPS.asm" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/GlassFP.cg "${OpenMW_BINARY_DIR}/resources/water/GlassFP.cg" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/GlassVP.cg "${OpenMW_BINARY_DIR}/resources/water/GlassVP.cg" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/underwater.cg "${OpenMW_BINARY_DIR}/resources/water/underwater.cg" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/perlinvolume.dds "${OpenMW_BINARY_DIR}/resources/water/perlinvolume.dds" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Water02.jpg "${OpenMW_BINARY_DIR}/resources/water/Water02.jpg" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.compositor "${OpenMW_BINARY_DIR}/resources/water/water.compositor" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/waves2.dds "${OpenMW_BINARY_DIR}/resources/water/waves2.dds" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Examples-Water.material "${OpenMW_BINARY_DIR}/resources/water/Examples-Water.material" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/WaterNormal1.tga "${OpenMW_BINARY_DIR}/resources/water/WaterNormal1.tga" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.material "${OpenMW_BINARY_DIR}/resources/water/water.material" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/WaterNormal2.tga "${OpenMW_BINARY_DIR}/resources/water/WaterNormal2.tga" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.cg "${OpenMW_BINARY_DIR}/resources/water/water.cg" COPYONLY)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.cg "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.cg" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.material "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.material" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.compositor "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.compositor" COPYONLY)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/shadows/depthshadowcaster.material "${OpenMW_BINARY_DIR}/resources/shadows/depthshadowcaster.material" COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/shadows/depthshadowcaster.cg "${OpenMW_BINARY_DIR}/resources/shadows/depthshadowcaster.cg" COPYONLY)
|
||||
|
@ -0,0 +1,18 @@
|
||||
void RenderScene_vs(in float4 position : POSITION
|
||||
,in float2 uv :TEXCOORD0
|
||||
,uniform float4x4 wvp
|
||||
,out float4 oPosition : POSITION
|
||||
,out float2 oUV :TEXCOORD0)
|
||||
{
|
||||
oPosition = mul(wvp, position);
|
||||
oUV = uv;
|
||||
}
|
||||
|
||||
void RenderScene_ps(in float4 position : POSITION
|
||||
,in float2 uv :TEXCOORD0
|
||||
,uniform sampler2D tex1 : TEXUNIT0
|
||||
,out float4 oColor : COLOR)
|
||||
{
|
||||
float4 scene =tex2D(tex1, uv);
|
||||
oColor= scene;
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
// Compositor that just controls output to the MRT textures
|
||||
compositor gbuffer
|
||||
{
|
||||
technique
|
||||
{
|
||||
// MRT output. Currently this is a color texture plus a depth texture
|
||||
texture mrt_output target_width target_height PF_FLOAT16_RGBA PF_FLOAT16_RGBA chain_scope depth_pool 2
|
||||
|
||||
target mrt_output
|
||||
{
|
||||
input none
|
||||
pass clear
|
||||
{
|
||||
clear
|
||||
{
|
||||
// make sure to set this to the viewport background color from outside
|
||||
colour_value 0 0 0 1
|
||||
}
|
||||
}
|
||||
pass render_scene
|
||||
{
|
||||
// Renders everything except water
|
||||
first_render_queue 0
|
||||
last_render_queue 70
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
target_output
|
||||
{
|
||||
input none
|
||||
|
||||
pass render_quad
|
||||
{
|
||||
material RenderScene
|
||||
input 0 mrt_output 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finalizer compositor to render objects that we don't want in the MRT textures (ex. water)
|
||||
// NB the water has to be rendered in a seperate compositor anyway, because it
|
||||
// accesses the MRT textures which can't be done while they are still being rendered to.
|
||||
compositor gbufferFinalizer
|
||||
{
|
||||
technique
|
||||
{
|
||||
texture no_mrt_output target_width target_height PF_R8G8B8A8 depth_pool 2 no_fsaa
|
||||
texture previousscene target_width target_height PF_R8G8B8A8
|
||||
|
||||
target previousscene
|
||||
{
|
||||
input previous
|
||||
}
|
||||
target no_mrt_output
|
||||
{
|
||||
input none
|
||||
shadows off
|
||||
pass clear
|
||||
{
|
||||
clear
|
||||
{
|
||||
buffers colour
|
||||
colour_value 0 0 0 0
|
||||
}
|
||||
}
|
||||
pass render_quad
|
||||
{
|
||||
material RenderSceneNoDepth
|
||||
input 0 previousscene
|
||||
}
|
||||
pass render_scene
|
||||
{
|
||||
first_render_queue 71
|
||||
last_render_queue 100
|
||||
}
|
||||
}
|
||||
target_output
|
||||
{
|
||||
input none
|
||||
pass clear
|
||||
{
|
||||
clear
|
||||
{
|
||||
}
|
||||
}
|
||||
pass render_quad
|
||||
{
|
||||
material RenderSceneNoDepth
|
||||
input 0 no_mrt_output
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
vertex_program RenderGBuffer_vs cg
|
||||
{
|
||||
source gbuffer.cg
|
||||
profiles vs_4_0 vs_1_1 arbvp1
|
||||
entry_point RenderScene_vs
|
||||
default_params
|
||||
{
|
||||
param_named_auto wvp worldviewproj_matrix
|
||||
}
|
||||
}
|
||||
fragment_program RenderGBuffer_ps cg
|
||||
{
|
||||
source gbuffer.cg
|
||||
entry_point RenderScene_ps
|
||||
profiles ps_4_0 ps_2_x arbfp1
|
||||
default_params
|
||||
{
|
||||
}
|
||||
}
|
||||
material RenderScene
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_program_ref RenderGBuffer_vs
|
||||
{
|
||||
}
|
||||
|
||||
fragment_program_ref RenderGBuffer_ps
|
||||
{
|
||||
}
|
||||
|
||||
texture_unit tex1
|
||||
{
|
||||
//scenebuffer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material RenderSceneNoDepth
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
depth_write off
|
||||
vertex_program_ref RenderGBuffer_vs
|
||||
{
|
||||
}
|
||||
|
||||
fragment_program_ref RenderGBuffer_ps
|
||||
{
|
||||
}
|
||||
|
||||
texture_unit tex1
|
||||
{
|
||||
//scenebuffer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 4.7 KiB |
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MyGUI type="Resource" version="1.1">
|
||||
<Resource type="ResourceSkin" name="Skin name 0" size="32 32" texture="">
|
||||
<BasisSkin type="SubSkin" offset="0 0 32 32" align="Stretch">
|
||||
<State name="normal" offset="0 0 32 32"/>
|
||||
</BasisSkin>
|
||||
</Resource>
|
||||
</MyGUI>
|
@ -0,0 +1,51 @@
|
||||
void main_vp(
|
||||
float4 position : POSITION,
|
||||
float2 uv : TEXCOORD0,
|
||||
|
||||
out float4 oPosition : POSITION,
|
||||
out float2 oDepth : TEXCOORD0,
|
||||
out float2 oUv : TEXCOORD1,
|
||||
|
||||
uniform float4x4 wvpMat)
|
||||
{
|
||||
// this is the view space position
|
||||
oPosition = mul(wvpMat, position);
|
||||
|
||||
// depth info for the fragment.
|
||||
oDepth.x = oPosition.z;
|
||||
oDepth.y = oPosition.w;
|
||||
|
||||
// clamp z to zero. seem to do the trick. :-/
|
||||
oPosition.z = max(oPosition.z, 0);
|
||||
|
||||
oUv = uv;
|
||||
}
|
||||
|
||||
void main_fp(
|
||||
float2 depth : TEXCOORD0,
|
||||
float2 uv : TEXCOORD1,
|
||||
uniform sampler2D texture1 : register(s0),
|
||||
|
||||
out float4 oColour : COLOR)
|
||||
{
|
||||
float finalDepth = depth.x / depth.y;
|
||||
|
||||
// use alpha channel of the first texture
|
||||
float alpha = tex2D(texture1, uv).a;
|
||||
|
||||
// discard if alpha is less than 0.5
|
||||
clip((alpha >= 0.5) ? 1 : -1);
|
||||
|
||||
oColour = float4(finalDepth, finalDepth, finalDepth, 1);
|
||||
}
|
||||
|
||||
void main_fp_noalpha(
|
||||
float2 depth : TEXCOORD0,
|
||||
float2 uv : TEXCOORD1,
|
||||
|
||||
out float4 oColour : COLOR)
|
||||
{
|
||||
float finalDepth = depth.x / depth.y;
|
||||
|
||||
oColour = float4(finalDepth, finalDepth, finalDepth, 1);
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
vertex_program depth_shadow_caster_vs cg
|
||||
{
|
||||
source depthshadowcaster.cg
|
||||
profiles vs_1_1 arbvp1
|
||||
entry_point main_vp
|
||||
|
||||
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
|
||||
|
||||
default_params
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
fragment_program depth_shadow_caster_ps_noalpha cg
|
||||
{
|
||||
source depthshadowcaster.cg
|
||||
profiles ps_2_0 arbfp1
|
||||
entry_point main_fp_noalpha
|
||||
|
||||
default_params
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
material depth_shadow_caster
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
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
|
||||
{
|
||||
}
|
||||
|
||||
fragment_program_ref depth_shadow_caster_ps_noalpha
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,574 @@
|
||||
# Bethesda has used wrong transparency settings for many textures
|
||||
# (who would have guessed)
|
||||
# This is very unfortunate because objects with real transparency:
|
||||
# - cannot cast shadows
|
||||
# - cannot receive advanced framebuffer effects like depth of field or ambient occlusion
|
||||
# - cannot cover lens flare effects (the lens flare will just shine through)
|
||||
|
||||
# This file lists textures that should be using alpha rejection instead of transparency
|
||||
# basically these are textures that are not translucent (i.e. at one spot on the texture, either transparent or opaque)
|
||||
|
||||
# Note: all the texture names here have to be lowercase
|
||||
|
||||
# fauna
|
||||
[textures\tx_wickwheat_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_wickwheat_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_red_lichen_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_stone_flower_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ivy_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ivy_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_saltrice_04.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_black_lichen_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_leaves_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_leaves_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_leaves_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_leaves_04.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_leaves_06.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_leaves_07.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ai_heather_01.dds]
|
||||
alphaRejectValue = 96
|
||||
|
||||
[textures\tx_goldkanet_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_goldkanet_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_plant_tails00.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_vine_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_comberry_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_willow_flower_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_cork_bulb_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_green_lichen_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_roobrush_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bittergreen_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_chokeweed_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_branches_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_branches_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_guarskin_hut_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_hackle-lo_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bc_fern_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bc_fern_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bc_leaves_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_marshmerrow_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bc_moss_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bc_moss_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bc_lilypad_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bc_lilypad_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bc_lilypad_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_fire_fern_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
# banners and flags
|
||||
[textures\tx_flag_imp_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_arena_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_comfort_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_child_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_count_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_faith_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_walk_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_imp_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_redoran_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_avs_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_serving_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_speak_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_stdeyln_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_stolms_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_thin_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_vivec_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_vivec_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_banner_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_banner_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_banner_04.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_banner_05.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_banner_06.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_banner_07.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_a_banner.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_e_banner.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_u_banner.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_z_banner.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_6th.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_6th_tall.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_gnisis_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_gnisis_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_bhm_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_04.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_05.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_06.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_07.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_08.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_08.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_09.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_10.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_11.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_12.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_tapestry_13.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_lutestrings_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_fabric_imp_altar_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_akatosh_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_apprentice_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_arkay_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_dibella_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_golem_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_julianos_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_kynareth_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_lady_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_lord_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_lover_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_mara_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_ritual_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_shadow_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_steed_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_stendarr_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_thief_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_tower_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_warrior_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_wizard_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_c_t_zenithar_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_dagoth_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bannerd_tavern_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bannerd_goods_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bannerd_danger_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bannerd_welcome_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bannerd_clothing_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bannerd_alchemy_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_hlaalu_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_redoran_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_temple_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_temple_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_book_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_ald_velothi.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_gnaar_mok.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_hla_oad.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_khull.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_pawn_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_sadrith_mora.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_tel_aruhn.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_tel_branora.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_tel_fyr.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_tel_mora.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_telvani_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_tel_vos.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_de_banner_vos.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bannerd_w_a_shop_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_banner_temple_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_mural1_00.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_mural1_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_mural4_00.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_mural4_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_mural5_00.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_telvanni_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_v_b_hlaalu_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_fabric_tapestry.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_fabric_tapestry_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_fabric_tapestry_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_fabric_tapestry_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_fabric_tapestry_04.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
# characters
|
||||
[textures\tx_netchgod00.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_argonian_f_hair02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_argonian_f_hair03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_argonian_m_hair01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_argonian_m_hair04.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_argonian_m_hair05.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_khajiit_f_hair01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_khajiit_f_hair02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_khajiit_m_hair01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_corprus_stalker12.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_a_clavicus02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_dark elf_m_hair11.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_b_n_dark elf_f_hair10.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
# misc items
|
||||
[textures\tx_sail.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_longboatsail01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_longboatsail01a.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_longboatsail01b.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_longboatsail02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_quill.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_note_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_note_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_parchment_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_parchment_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_scroll_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_scroll_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_scroll_03.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_alpha_small_edge.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_alpha_shadow_circular.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
# building materials
|
||||
[textures\tx_shack_thatch_strip.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_rug00.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_rug_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_rug_edge_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_awning_thatch_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_awning_woven_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_bridgeropes.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_rope_woven_01.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_rope_woven_02.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_ashl_tent_06.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_guar_tarp.dds]
|
||||
alphaRejectValue = 128
|
||||
|
||||
[textures\tx_velothi_glyph00.dds]
|
||||
alphaRejectValue = 128
|
@ -1,116 +0,0 @@
|
||||
// Vertex program for fresnel reflections / refractions
|
||||
void main_vp(
|
||||
float4 pos : POSITION,
|
||||
float4 normal : NORMAL,
|
||||
float2 tex : TEXCOORD0,
|
||||
|
||||
out float4 oPos : POSITION,
|
||||
out float3 noiseCoord : TEXCOORD0,
|
||||
out float4 projectionCoord : TEXCOORD1,
|
||||
out float3 oEyeDir : TEXCOORD2,
|
||||
out float3 oNormal : TEXCOORD3,
|
||||
|
||||
uniform float4x4 worldViewProjMatrix,
|
||||
uniform float3 eyePosition, // object space
|
||||
uniform float timeVal,
|
||||
uniform float scale, // the amount to scale the noise texture by
|
||||
uniform float scroll, // the amount by which to scroll the noise
|
||||
uniform float noise // the noise perturb as a factor of the time
|
||||
)
|
||||
{
|
||||
oPos = mul(worldViewProjMatrix, pos);
|
||||
// Projective texture coordinates, adjust for mapping
|
||||
float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,
|
||||
0,-0.5, 0, 0.5,
|
||||
0, 0, 0.5, 0.5,
|
||||
0, 0, 0, 1);
|
||||
projectionCoord = mul(scalemat, oPos);
|
||||
// Noise map coords
|
||||
noiseCoord.xy = (tex + (timeVal * scroll)) * scale;
|
||||
noiseCoord.z = noise * timeVal;
|
||||
|
||||
oEyeDir = normalize(pos.xyz - eyePosition);
|
||||
oNormal = normal.rgb;
|
||||
|
||||
}
|
||||
|
||||
// Fragment program for distorting a texture using a 3D noise texture
|
||||
void main_fp(
|
||||
float3 noiseCoord : TEXCOORD0,
|
||||
float4 projectionCoord : TEXCOORD1,
|
||||
float3 eyeDir : TEXCOORD2,
|
||||
float3 normal : TEXCOORD3,
|
||||
|
||||
out float4 col : COLOR,
|
||||
|
||||
uniform float4 tintColour,
|
||||
uniform float noiseScale,
|
||||
uniform float fresnelBias,
|
||||
uniform float fresnelScale,
|
||||
uniform float fresnelPower,
|
||||
uniform sampler2D waterTex : register(s0),
|
||||
uniform sampler2D noiseMap : register(s1),
|
||||
uniform sampler2D reflectMap : register(s2),
|
||||
uniform sampler2D refractMap : register(s3)
|
||||
)
|
||||
{
|
||||
// Do the tex projection manually so we can distort _after_
|
||||
float2 final = projectionCoord.xy / projectionCoord.w;
|
||||
|
||||
// Noise
|
||||
float3 noiseNormal = (tex2D(noiseMap, (noiseCoord.xy / 5)).rgb - 0.5).rbg * noiseScale;
|
||||
final += noiseNormal.xz;
|
||||
|
||||
// Fresnel
|
||||
//normal = normalize(normal + noiseNormal.xz);
|
||||
float fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower);
|
||||
|
||||
// Reflection / refraction
|
||||
float4 reflectionColour = tex2D(reflectMap, final);
|
||||
float4 refractionColour = tex2D(refractMap, final) + tintColour;
|
||||
|
||||
// Final colour
|
||||
col = lerp(refractionColour, reflectionColour, fresnel) * tex2D(waterTex, noiseNormal) / 3 ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Old version to match ATI PS 1.3 implementation
|
||||
void main_vp_old(
|
||||
float4 pos : POSITION,
|
||||
float4 normal : NORMAL,
|
||||
float2 tex : TEXCOORD0,
|
||||
|
||||
out float4 oPos : POSITION,
|
||||
out float fresnel : COLOR,
|
||||
out float3 noiseCoord : TEXCOORD0,
|
||||
out float4 projectionCoord : TEXCOORD1,
|
||||
|
||||
uniform float4x4 worldViewProjMatrix,
|
||||
uniform float3 eyePosition, // object space
|
||||
uniform float fresnelBias,
|
||||
uniform float fresnelScale,
|
||||
uniform float fresnelPower,
|
||||
uniform float timeVal,
|
||||
uniform float scale, // the amount to scale the noise texture by
|
||||
uniform float scroll, // the amount by which to scroll the noise
|
||||
uniform float noise // the noise perturb as a factor of the time
|
||||
)
|
||||
{
|
||||
oPos = mul(worldViewProjMatrix, pos);
|
||||
// Projective texture coordinates, adjust for mapping
|
||||
float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,
|
||||
0,-0.5, 0, 0.5,
|
||||
0, 0, 0.5, 0.5,
|
||||
0, 0, 0, 1);
|
||||
projectionCoord = mul(scalemat, oPos);
|
||||
// Noise map coords
|
||||
noiseCoord.xy = (tex + (timeVal * scroll)) * scale;
|
||||
noiseCoord.z = noise * timeVal;
|
||||
|
||||
// calc fresnel factor (reflection coefficient)
|
||||
float3 eyeDir = normalize(pos.xyz - eyePosition);
|
||||
fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower);
|
||||
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
ps.1.4
|
||||
// conversion from Cg generated ARB_fragment_program to ps.1.4 by NFZ
|
||||
// command line args: -profile arbfp1 -entry main_fp
|
||||
// program main_fp
|
||||
// c0 : distortionRange
|
||||
// c1 : tintColour
|
||||
// testure 0 : noiseMap
|
||||
// texture 1 : reflectMap
|
||||
// texture 2 : refractMap
|
||||
// v0.x : fresnel
|
||||
// t0.xyz : noiseCoord
|
||||
// t1.xyw : projectionCoord
|
||||
|
||||
def c2, 2, 1, 0, 0
|
||||
|
||||
// Cg: distort.x = tex3D(noiseMap, noiseCoord).x;
|
||||
// arbfp1: TEX R0.x, fragment.texcoord[0], texture[0], 3D;
|
||||
// sample noise map using noiseCoord in TEX unit 0
|
||||
|
||||
texld r0, t0.xyz
|
||||
|
||||
// get projected texture coordinates from TEX coord 1
|
||||
// will be used in phase 2
|
||||
|
||||
texcrd r1.xy, t1_dw.xyw
|
||||
mov r1.z, c2.y
|
||||
|
||||
// Cg: distort.y = tex3D(noiseMap, noiseCoord + yoffset).x;
|
||||
// arbfp1: ADD R1.xyz, fragment.texcoord[0], c1;
|
||||
// arbfp1: TEX R1.x, R1, texture[0], 3D;
|
||||
// arbfp1: MOV R0.y, R1.x;
|
||||
|
||||
// Cg: distort = (distort * 2 - 1) * distortionRange;
|
||||
// arbfp1: MAD R0.xy, R0, c0.x, -c0.y;
|
||||
// arbfp1: MUL R0.xy, R0, u0.x;
|
||||
// (distort * 2 - 1) same as 2*(distort -.5) so use _bx2
|
||||
|
||||
|
||||
// Cg: final = projectionCoord.xy / projectionCoord.w;
|
||||
// Cg: final += distort;
|
||||
// arbfp1: RCP R0.w, fragment.texcoord[1].w;
|
||||
// arbfp1: MAD R0.xy, fragment.texcoord[1], R0.w, R0;
|
||||
// final = (distort * projectionCoord.w) + projectionCoord.xy
|
||||
// for ps.1.4 have to re-arrange things a bit to perturb projected texture coordinates
|
||||
|
||||
mad r0.xyz, r0_bx2, c0.x, r1
|
||||
|
||||
phase
|
||||
|
||||
// do dependant texture reads
|
||||
// Cg: reflectionColour = tex2D(reflectMap, final);
|
||||
// arbfp1: TEX R0, R0, texture[1], 2D;
|
||||
// sampe reflectMap using dependant read : texunit 1
|
||||
|
||||
texld r1, r0.xyz
|
||||
|
||||
// Cg: refractionColour = tex2D(refractMap, final) + tintColour;
|
||||
// arbfp1: TEX R1, R0, texture[2], 2D;
|
||||
// sample refractMap : texunit 2
|
||||
|
||||
texld r2, r0.xyz
|
||||
|
||||
// adding tintColour that is in global c1
|
||||
// arbfp1: ADD R1, R1, u1;
|
||||
|
||||
add r2, r2, c1
|
||||
|
||||
// Cg: col = lerp(refractionColour, reflectionColour, fresnel);
|
||||
// arbfp1: ADD R0, R0, -R1;
|
||||
// arbfp1: MAD result.color, fragment.color.primary.x, R0, R1;
|
||||
|
||||
lrp r0, v0.x, r1, r2
|
@ -1,149 +0,0 @@
|
||||
|
||||
vertex_program Water/GlassVP cg
|
||||
{
|
||||
source GlassVP.cg
|
||||
entry_point glass_vp
|
||||
profiles vs_1_1 arbvp1
|
||||
|
||||
default_params
|
||||
{
|
||||
param_named_auto worldViewProj worldviewproj_matrix
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fragment_program Water/GlassFP cg
|
||||
{
|
||||
source GlassFP.cg
|
||||
entry_point main_ps
|
||||
profiles ps_2_0 arbfp1
|
||||
}
|
||||
|
||||
material Water/Compositor
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
depth_check off
|
||||
vertex_program_ref Water/GlassVP
|
||||
{
|
||||
param_named_auto timeVal time 0.25
|
||||
param_named scale float 0.1
|
||||
}
|
||||
|
||||
fragment_program_ref Water/GlassFP
|
||||
{
|
||||
param_named tintColour float4 0 0.35 0.35 1
|
||||
}
|
||||
|
||||
texture_unit RT
|
||||
{
|
||||
tex_coord_set 0
|
||||
tex_address_mode clamp
|
||||
filtering linear linear linear
|
||||
}
|
||||
|
||||
texture_unit
|
||||
{
|
||||
texture WaterNormal1.tga 2d
|
||||
tex_coord_set 1
|
||||
//tex_address_mode clamp
|
||||
filtering linear linear linear
|
||||
}
|
||||
texture_unit
|
||||
{
|
||||
texture caustic_0.png 2d
|
||||
tex_coord_set 2
|
||||
//tex_address_mode clamp
|
||||
filtering linear linear linear
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vertex_program Water/RefractReflectVP cg
|
||||
{
|
||||
source Example_Fresnel.cg
|
||||
entry_point main_vp
|
||||
profiles vs_1_1 arbvp1
|
||||
}
|
||||
vertex_program Water/RefractReflectVPold cg
|
||||
{
|
||||
source Example_Fresnel.cg
|
||||
entry_point main_vp_old
|
||||
profiles vs_1_1 arbvp1
|
||||
}
|
||||
|
||||
fragment_program Water/RefractReflectFP cg
|
||||
{
|
||||
source Example_Fresnel.cg
|
||||
entry_point main_fp
|
||||
// sorry, ps_1_1 and fp20 can't do this
|
||||
profiles ps_2_0 arbfp1
|
||||
}
|
||||
|
||||
fragment_program Water/RefractReflectPS asm
|
||||
{
|
||||
source Example_FresnelPS.asm
|
||||
// sorry, only for ps_1_4 :)
|
||||
syntax ps_1_4
|
||||
|
||||
}
|
||||
material Examples/Water0
|
||||
{
|
||||
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
//
|
||||
|
||||
depth_write off
|
||||
vertex_program_ref Water/RefractReflectVP
|
||||
{
|
||||
param_named_auto worldViewProjMatrix worldviewproj_matrix
|
||||
param_named_auto eyePosition camera_position_object_space
|
||||
param_named_auto timeVal time 0.15
|
||||
param_named scroll float 1
|
||||
param_named scale float 1
|
||||
param_named noise float 1
|
||||
// scroll and noisePos will need updating per frame
|
||||
}
|
||||
fragment_program_ref Water/RefractReflectFP
|
||||
{
|
||||
param_named fresnelBias float -0.1
|
||||
param_named fresnelScale float 0.8
|
||||
param_named fresnelPower float 20
|
||||
param_named tintColour float4 1 1 1 1
|
||||
param_named noiseScale float 0.05
|
||||
}
|
||||
// Water
|
||||
scene_blend alpha_blend
|
||||
texture_unit
|
||||
{
|
||||
|
||||
// Water texture
|
||||
texture Water02.jpg
|
||||
// min / mag filtering, no mip
|
||||
filtering linear linear none
|
||||
alpha_op_ex source1 src_manual src_current 0.9
|
||||
|
||||
}
|
||||
// Noise
|
||||
texture_unit
|
||||
{
|
||||
alpha_op_ex source1 src_manual src_current 0.9
|
||||
// Perlin noise volume
|
||||
texture waves2.dds
|
||||
// min / mag filtering, no mip
|
||||
filtering linear linear none
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
sampler RT : register(s0);
|
||||
sampler NormalMap : register(s1);
|
||||
sampler CausticMap : register(s2);
|
||||
|
||||
float4 main_ps(float2 iTexCoord : TEXCOORD0,
|
||||
float3 noiseCoord : TEXCOORD1,
|
||||
uniform float4 tintColour) : COLOR
|
||||
{
|
||||
float4 normal = tex2D(NormalMap, noiseCoord);
|
||||
|
||||
|
||||
return tex2D(RT, iTexCoord + normal.xy * 0.05) +
|
||||
(tex2D(CausticMap, noiseCoord) / 5) +
|
||||
tintColour ;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
void glass_vp
|
||||
(
|
||||
in float4 inPos : POSITION,
|
||||
|
||||
out float4 pos : POSITION,
|
||||
out float2 uv0 : TEXCOORD0,
|
||||
out float4 noiseCoord : TEXCOORD1,
|
||||
|
||||
uniform float4x4 worldViewProj,
|
||||
uniform float timeVal,
|
||||
uniform float scale
|
||||
)
|
||||
{
|
||||
// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
|
||||
pos = mul(worldViewProj, inPos);
|
||||
|
||||
// The input positions adjusted by texel offsets, so clean up inaccuracies
|
||||
inPos.xy = sign(inPos.xy);
|
||||
|
||||
// Convert to image-space
|
||||
uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
|
||||
noiseCoord = (pos + timeVal) * scale;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 182 KiB |
Binary file not shown.
Before Width: | Height: | Size: 192 KiB |
Binary file not shown.
After Width: | Height: | Size: 192 KiB |
@ -0,0 +1,61 @@
|
||||
void main_vp
|
||||
(
|
||||
in float4 inPos : POSITION,
|
||||
|
||||
out float4 pos : POSITION,
|
||||
out float2 uv0 : TEXCOORD0,
|
||||
out float4 noiseCoord : TEXCOORD1,
|
||||
|
||||
uniform float4x4 worldViewProj,
|
||||
uniform float timeVal,
|
||||
uniform float scale
|
||||
)
|
||||
{
|
||||
// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
|
||||
pos = mul(worldViewProj, inPos);
|
||||
|
||||
// The input positions adjusted by texel offsets, so clean up inaccuracies
|
||||
inPos.xy = sign(inPos.xy);
|
||||
|
||||
// Convert to image-space
|
||||
uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
|
||||
noiseCoord = (pos + timeVal) * scale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float4 main_fp_nomrt (float2 iTexCoord : TEXCOORD0,
|
||||
float3 noiseCoord : TEXCOORD1,
|
||||
uniform sampler2D RT : register(s0),
|
||||
uniform sampler2D NormalMap : register(s1),
|
||||
uniform sampler2D CausticMap : register(s2),
|
||||
uniform float4 tintColour) : COLOR
|
||||
{
|
||||
float4 normal = tex2D(NormalMap, noiseCoord) * 2 - 1;
|
||||
|
||||
return tex2D(RT, iTexCoord + normal.xy * 0.015) +
|
||||
(tex2D(CausticMap, noiseCoord) / 5) +
|
||||
tintColour ;
|
||||
}
|
||||
|
||||
|
||||
float4 main_fp (float2 iTexCoord : TEXCOORD0,
|
||||
float3 noiseCoord : TEXCOORD1,
|
||||
uniform float far,
|
||||
uniform sampler2D RT : register(s0),
|
||||
uniform sampler2D NormalMap : register(s1),
|
||||
uniform sampler2D CausticMap : register(s2),
|
||||
uniform sampler2D DepthMap : register(s3),
|
||||
uniform float4 tintColour) : COLOR
|
||||
{
|
||||
float4 normal = tex2D(NormalMap, noiseCoord) * 2 - 1;
|
||||
|
||||
float depth = tex2D(DepthMap, iTexCoord + normal.xy * 0.015).r * far;
|
||||
depth = saturate(depth / 2000.f);
|
||||
|
||||
float4 color = tex2D(RT, iTexCoord + normal.xy * 0.015) +
|
||||
(tex2D(CausticMap, noiseCoord) / 5) +
|
||||
tintColour;
|
||||
|
||||
return lerp(color, float4(0, 0.65, 0.65, 1), depth);
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
void main_vp
|
||||
(
|
||||
in float4 iPos : POSITION
|
||||
, in float2 iUv : TEXCOORD0
|
||||
|
||||
, out float4 oPos : POSITION
|
||||
, out float3 oScreenCoords : TEXCOORD0
|
||||
, out float2 oUv : TEXCOORD1
|
||||
, out float oDepth : TEXCOORD2
|
||||
, out float4 oEyeVector : TEXCOORD3
|
||||
|
||||
, uniform float4x4 wvpMat
|
||||
, uniform float4 camPosObjSpace
|
||||
)
|
||||
{
|
||||
oPos = mul(wvpMat, iPos);
|
||||
|
||||
oUv = iUv * 10; // uv scale
|
||||
oDepth = oPos.z;
|
||||
|
||||
float4x4 scalemat = float4x4( 0.5, 0, 0, 0.5,
|
||||
0, -0.5, 0, 0.5,
|
||||
0, 0, 0.5, 0.5,
|
||||
0, 0, 0, 1 );
|
||||
float4 texcoordProj = mul(scalemat, oPos);
|
||||
oScreenCoords = float3(texcoordProj.x, texcoordProj.y, texcoordProj.w);
|
||||
|
||||
oEyeVector = camPosObjSpace - iPos;
|
||||
}
|
||||
|
||||
void main_fp
|
||||
(
|
||||
out float4 oColor : COLOR
|
||||
|
||||
, in float3 iScreenCoords : TEXCOORD0
|
||||
, in float2 iUv : TEXCOORD1
|
||||
, in float iDepth : TEXCOORD2
|
||||
, in float4 iEyeVector : TEXCOORD3
|
||||
, uniform float renderTargetFlipping
|
||||
, uniform float4 lightPosObjSpace0
|
||||
, uniform float4 lightSpecularColour0
|
||||
|
||||
, uniform sampler2D reflectionMap : register(s0)
|
||||
, uniform sampler2D refractionMap : register(s1)
|
||||
, uniform sampler2D depthMap : register(s2)
|
||||
, uniform sampler2D normalMap : register(s3)
|
||||
, uniform float time
|
||||
, uniform float far
|
||||
, uniform float4 fogParams
|
||||
, uniform float4 fogColour
|
||||
, uniform float isUnderwater
|
||||
)
|
||||
{
|
||||
|
||||
float2 screenCoords = iScreenCoords.xy / iScreenCoords.z;
|
||||
screenCoords.y = (1-saturate(renderTargetFlipping))+renderTargetFlipping*screenCoords.y;
|
||||
|
||||
// No need for transparency since we are using a refraction map
|
||||
oColor.a = 1;
|
||||
|
||||
// Sample screen-space depth map and subtract pixel depth to get the real water depth
|
||||
float depthTex = tex2D(depthMap, screenCoords).r;
|
||||
float depth1 = depthTex * far - iDepth;
|
||||
depth1 = saturate(depth1 / 500.f);
|
||||
|
||||
// Simple wave effect. to be replaced by something better
|
||||
float2 uv1 = iUv + time * float2(0.5, 0);
|
||||
float2 uv2 = iUv + time * float2(0, 0.5);
|
||||
float2 uv3 = iUv + time * float2(-0.5, 0);
|
||||
float2 uv4 = iUv + time * float2(0, -0.5);
|
||||
float4 normal = tex2D(normalMap, uv1) + tex2D(normalMap, uv2) + tex2D(normalMap, uv3) + tex2D(normalMap, uv4);
|
||||
normal = normal / 4.f;
|
||||
normal = 2*normal - 1;
|
||||
|
||||
float2 screenCoords_reflect = screenCoords + normal.yx * 0.05;
|
||||
float2 screenCoords_refract = screenCoords + normal.yx * 0.05 * depth1;
|
||||
|
||||
// Sample depth again with the refracted coordinates
|
||||
depthTex = tex2D(depthMap, screenCoords_refract).r;
|
||||
float depth2 = (depthTex * far - iDepth) / 500.f;
|
||||
depth2 = (depthTex == 0 ? 1 : depth2);
|
||||
// if depth2 is less than 0, this means we would refract something which is above water,
|
||||
// which we don't want to - so in that case, don't refract
|
||||
if (depth2 < 0.25) // delta due to inaccuracies
|
||||
{
|
||||
screenCoords_refract = screenCoords;
|
||||
depth2 = depth1;
|
||||
}
|
||||
depth2 = saturate(depth2);
|
||||
|
||||
float4 reflection = tex2D(reflectionMap, screenCoords_reflect);
|
||||
float4 refraction = tex2D(refractionMap, screenCoords_refract);
|
||||
|
||||
// tangent to object space
|
||||
normal.xyz = normal.xzy;
|
||||
|
||||
iEyeVector.xyz = normalize(iEyeVector.xyz);
|
||||
|
||||
// fresnel
|
||||
float facing = 1.0 - max(abs(dot(iEyeVector.xyz, normal.xyz)), 0);
|
||||
float reflectionFactor = saturate(0.35 + 0.65 * pow(facing, 2));
|
||||
|
||||
// specular
|
||||
float3 lightDir = normalize(lightPosObjSpace0.xyz); // assumes that light 0 is a directional light
|
||||
float3 halfVector = normalize(iEyeVector + lightDir);
|
||||
float specular = pow(max(dot(normal.xyz, halfVector.xyz), 0), 64);
|
||||
|
||||
float opacity = depth2 * saturate(reflectionFactor + specular);
|
||||
opacity *= (1-isUnderwater);
|
||||
|
||||
reflection.xyz += lightSpecularColour0.xyz * specular;
|
||||
|
||||
oColor.xyz = lerp(refraction.xyz, reflection.xyz, opacity);
|
||||
|
||||
oColor.xyz += isUnderwater * float3(0, 0.35, 0.35); // underwater tint color
|
||||
oColor.xyz = lerp(oColor.xyz, float3(0, 0.65, 0.65), saturate(isUnderwater * (iDepth / 2000.f))); // underwater fog
|
||||
|
||||
// add fog
|
||||
//float fogValue = saturate((iDepth - fogParams.y) * fogParams.w);
|
||||
//oColor.xyz = lerp(oColor.xyz, fogColour, fogValue);
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
vertex_program UnderwaterEffectVP cg
|
||||
{
|
||||
source underwater.cg
|
||||
entry_point main_vp
|
||||
profiles vs_1_1 arbvp1
|
||||
|
||||
default_params
|
||||
{
|
||||
param_named_auto worldViewProj worldviewproj_matrix
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fragment_program UnderwaterEffectFP_NoMRT cg
|
||||
{
|
||||
source underwater.cg
|
||||
entry_point main_fp_nomrt
|
||||
profiles ps_2_0 arbfp1
|
||||
}
|
||||
|
||||
fragment_program UnderwaterEffectFP cg
|
||||
{
|
||||
source underwater.cg
|
||||
entry_point main_fp
|
||||
profiles ps_2_0 arbfp1
|
||||
}
|
||||
|
||||
vertex_program Water_VP cg
|
||||
{
|
||||
source water.cg
|
||||
entry_point main_vp
|
||||
profiles vs_2_x arbvp1
|
||||
|
||||
default_params
|
||||
{
|
||||
param_named_auto wvpMat worldviewproj_matrix
|
||||
}
|
||||
}
|
||||
|
||||
fragment_program Water_FP cg
|
||||
{
|
||||
source water.cg
|
||||
entry_point main_fp
|
||||
profiles ps_2_x arbfp1
|
||||
}
|
||||
|
||||
material Water
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
cull_hardware none
|
||||
|
||||
vertex_program_ref Water_VP
|
||||
{
|
||||
param_named_auto camPosObjSpace camera_position_object_space
|
||||
}
|
||||
fragment_program_ref Water_FP
|
||||
{
|
||||
param_named_auto time time 0.1
|
||||
//param_named_auto fogColour fog_colour
|
||||
//param_named_auto fogParams fog_params
|
||||
param_named_auto renderTargetFlipping render_target_flipping
|
||||
param_named_auto far far_clip_distance
|
||||
param_named_auto lightPosObjSpace0 light_position_object_space 0
|
||||
param_named_auto lightSpecularColour0 light_specular_colour 0
|
||||
param_named isUnderwater float 0
|
||||
}
|
||||
|
||||
texture_unit reflectionMap
|
||||
{
|
||||
texture WaterReflection
|
||||
tex_address_mode clamp
|
||||
}
|
||||
|
||||
texture_unit refractionMap
|
||||
{
|
||||
tex_address_mode clamp
|
||||
}
|
||||
|
||||
texture_unit depthMap
|
||||
{
|
||||
tex_address_mode clamp
|
||||
}
|
||||
|
||||
texture_unit normalMap
|
||||
{
|
||||
texture WaterNormal2.tga
|
||||
}
|
||||
}
|
||||
}
|
||||
technique
|
||||
{
|
||||
scheme Fallback
|
||||
pass
|
||||
{
|
||||
cull_hardware none
|
||||
scene_blend alpha_blend
|
||||
depth_write off
|
||||
diffuse 0 0 0 1
|
||||
emissive 0.6 0.7 1.0
|
||||
ambient 0 0 0
|
||||
texture_unit
|
||||
{
|
||||
// texture names set via code
|
||||
scale 0.1 0.1
|
||||
alpha_op_ex source1 src_manual src_current 0.7
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material Water/CompositorNoMRT
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
depth_check off
|
||||
vertex_program_ref UnderwaterEffectVP
|
||||
{
|
||||
param_named_auto timeVal time 0.25
|
||||
param_named scale float 0.1
|
||||
}
|
||||
|
||||
fragment_program_ref UnderwaterEffectFP_NoMRT
|
||||
{
|
||||
param_named tintColour float4 0 0.35 0.35 1
|
||||
}
|
||||
|
||||
texture_unit RT
|
||||
{
|
||||
tex_coord_set 0
|
||||
tex_address_mode clamp
|
||||
filtering linear linear linear
|
||||
}
|
||||
|
||||
texture_unit
|
||||
{
|
||||
texture WaterNormal2.tga 2d
|
||||
tex_coord_set 1
|
||||
//tex_address_mode clamp
|
||||
filtering linear linear linear
|
||||
}
|
||||
texture_unit
|
||||
{
|
||||
texture caustic_0.png 2d
|
||||
tex_coord_set 2
|
||||
//tex_address_mode clamp
|
||||
filtering linear linear linear
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
material Water/Compositor
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
depth_check off
|
||||
vertex_program_ref UnderwaterEffectVP
|
||||
{
|
||||
param_named_auto timeVal time 0.25
|
||||
param_named scale float 0.1
|
||||
}
|
||||
|
||||
fragment_program_ref UnderwaterEffectFP
|
||||
{
|
||||
param_named tintColour float4 0 0.35 0.35 1
|
||||
param_named_auto far far_clip_distance
|
||||
}
|
||||
|
||||
texture_unit RT
|
||||
{
|
||||
tex_coord_set 0
|
||||
tex_address_mode clamp
|
||||
}
|
||||
|
||||
texture_unit
|
||||
{
|
||||
texture WaterNormal2.tga 2d
|
||||
tex_coord_set 2
|
||||
}
|
||||
texture_unit
|
||||
{
|
||||
texture caustic_0.png 2d
|
||||
tex_coord_set 3
|
||||
}
|
||||
|
||||
texture_unit DepthMap
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
@ -0,0 +1,74 @@
|
||||
#include "imagerotate.hpp"
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreSceneManager.h>
|
||||
#include <OgreImage.h>
|
||||
#include <OgreTexture.h>
|
||||
#include <OgreRenderTarget.h>
|
||||
#include <OgreCamera.h>
|
||||
#include <OgreTextureUnitState.h>
|
||||
#include <OgreHardwarePixelBuffer.h>
|
||||
|
||||
using namespace Ogre;
|
||||
using namespace OEngine::Render;
|
||||
|
||||
void ImageRotate::rotate(const std::string& sourceImage, const std::string& destImage, const float angle)
|
||||
{
|
||||
Root* root = Ogre::Root::getSingletonPtr();
|
||||
|
||||
SceneManager* sceneMgr = root->createSceneManager(ST_GENERIC);
|
||||
Camera* camera = sceneMgr->createCamera("ImageRotateCamera");
|
||||
|
||||
MaterialPtr material = MaterialManager::getSingleton().create("ImageRotateMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
||||
material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
|
||||
TextureUnitState* tus = material->getTechnique(0)->getPass(0)->createTextureUnitState(sourceImage);
|
||||
Degree deg(angle);
|
||||
tus->setTextureRotate(Radian(deg.valueRadians()));
|
||||
tus->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
|
||||
tus->setTextureBorderColour(ColourValue(0, 0, 0, 0));
|
||||
|
||||
Rectangle2D* rect = new Rectangle2D(true);
|
||||
rect->setCorners(-1.0, 1.0, 1.0, -1.0);
|
||||
rect->setMaterial("ImageRotateMaterial");
|
||||
// Render the background before everything else
|
||||
rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);
|
||||
|
||||
// Use infinite AAB to always stay visible
|
||||
AxisAlignedBox aabInf;
|
||||
aabInf.setInfinite();
|
||||
rect->setBoundingBox(aabInf);
|
||||
|
||||
// Attach background to the scene
|
||||
SceneNode* node = sceneMgr->getRootSceneNode()->createChildSceneNode();
|
||||
node->attachObject(rect);
|
||||
|
||||
// retrieve image width and height
|
||||
TexturePtr sourceTexture = TextureManager::getSingleton().getByName(sourceImage);
|
||||
unsigned int width = sourceTexture->getWidth();
|
||||
unsigned int height = sourceTexture->getHeight();
|
||||
|
||||
TexturePtr destTexture = TextureManager::getSingleton().createManual(
|
||||
destImage,
|
||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
TEX_TYPE_2D,
|
||||
width, height,
|
||||
0,
|
||||
PF_A8R8G8B8,
|
||||
TU_RENDERTARGET);
|
||||
|
||||
RenderTarget* rtt = destTexture->getBuffer()->getRenderTarget();
|
||||
rtt->setAutoUpdated(false);
|
||||
Viewport* vp = rtt->addViewport(camera);
|
||||
vp->setOverlaysEnabled(false);
|
||||
vp->setShadowsEnabled(false);
|
||||
vp->setBackgroundColour(ColourValue(0,0,0,0));
|
||||
vp->setClearEveryFrame(true, FBT_DEPTH);
|
||||
|
||||
rtt->update();
|
||||
|
||||
// remove all the junk we've created
|
||||
MaterialManager::getSingleton().remove("ImageRotateMaterial");
|
||||
root->destroySceneManager(sceneMgr);
|
||||
delete rect;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
#ifndef OENGINE_OGRE_IMAGEROTATE_HPP
|
||||
#define OENGINE_OGRE_IMAGEROTATE_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace OEngine
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
|
||||
/// Rotate an image by certain degrees and save as file, uses the GPU
|
||||
/// Make sure Ogre Root is initialised before calling
|
||||
class ImageRotate
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param source image (file name - has to exist in an resource group)
|
||||
* @param name of the destination texture to save to (in memory)
|
||||
* @param angle in degrees to turn
|
||||
*/
|
||||
static void rotate(const std::string& sourceImage, const std::string& destImage, const float angle);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue