Factorise grass material

This commit is contained in:
Vincent Lejeune 2014-07-13 18:48:14 +02:00
parent adba84969e
commit 7b9fc60f9c
10 changed files with 70 additions and 185 deletions

View File

@ -1,7 +1,23 @@
uniform vec3 windDir;
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 TransposeInverseModelView;
#ifdef UBO_DISABLED
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 InverseViewMatrix;
uniform mat4 InverseProjectionMatrix;
#else
layout (std140) uniform MatrixesData
{
mat4 ViewMatrix;
mat4 ProjectionMatrix;
mat4 InverseViewMatrix;
mat4 InverseProjectionMatrix;
mat4 ShadowViewProjMatrixes[4];
vec2 screen;
};
#endif
uniform vec3 windDir;
uniform mat4 ModelMatrix;
uniform mat4 InverseModelMatrix;
#if __VERSION__ >= 330
layout(location = 0) in vec3 Position;
@ -20,7 +36,9 @@ out vec2 uv;
void main()
{
uv = Texcoord;
nor = (TransposeInverseModelView * vec4(Normal, 1.)).xyz;
gl_Position = ModelViewProjectionMatrix * vec4(Position + windDir * Color.r, 1.);
uv = Texcoord;
mat4 ModelViewProjectionMatrix = ProjectionMatrix * ViewMatrix * ModelMatrix;
mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix);
nor = (TransposeInverseModelView * vec4(Normal, 1.)).xyz;
gl_Position = ModelViewProjectionMatrix * vec4(Position + windDir * Color.r, 1.);
}

View File

@ -572,6 +572,7 @@ void IrrDriver::renderSolidFirstPass()
ListDefault2TCoordG::Arguments.clear();
ListAlphaRefG::Arguments.clear();
ListNormalG::Arguments.clear();
ListGrassG::Arguments.clear();
m_scene_manager->drawAll(scene::ESNRP_SOLID);
if (!UserConfigParams::m_dynamic_lights)
@ -583,6 +584,7 @@ void IrrDriver::renderSolidFirstPass()
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS>(MeshShader::ObjectPass1ShaderInstance, { MeshShader::ObjectPass1ShaderInstance->TU_tex }, ListDefault2TCoordG::Arguments);
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD>(MeshShader::ObjectRefPass1ShaderInstance, { MeshShader::ObjectRefPass1ShaderInstance->TU_tex }, ListAlphaRefG::Arguments);
renderMeshes1stPass<MeshShader::NormalMapShader, video::EVT_TANGENTS>(MeshShader::NormalMapShaderInstance, { MeshShader::NormalMapShaderInstance->TU_glossy, MeshShader::NormalMapShaderInstance->TU_normalmap }, ListNormalG::Arguments);
renderMeshes1stPass<MeshShader::GrassPass1Shader, video::EVT_STANDARD>(MeshShader::GrassPass1ShaderInstance, { MeshShader::GrassPass1ShaderInstance->TU_tex }, ListGrassG::Arguments);
}
}
@ -652,6 +654,7 @@ void IrrDriver::renderSolidSecondPass()
ListUnlitSM::Arguments.clear();
ListDetailSM::Arguments.clear();
ListSplattingSM::Arguments.clear();
ListGrassSM::Arguments.clear();
setTexture(0, m_rtts->getRenderTarget(RTT_TMP1), GL_NEAREST, GL_NEAREST);
setTexture(1, m_rtts->getRenderTarget(RTT_TMP2), GL_NEAREST, GL_NEAREST);
setTexture(2, m_rtts->getRenderTarget(RTT_HALF1_R), GL_LINEAR, GL_LINEAR);
@ -668,6 +671,7 @@ void IrrDriver::renderSolidSecondPass()
renderMeshes2ndPass<MeshShader::ObjectUnlitShader, video::EVT_STANDARD>(MeshShader::ObjectUnlitShaderInstance, { MeshShader::ObjectUnlitShaderInstance->TU_tex }, ListUnlitSM::Arguments);
renderMeshes2ndPass<MeshShader::DetailledObjectPass2Shader, video::EVT_2TCOORDS>(MeshShader::DetailledObjectPass2ShaderInstance, { MeshShader::DetailledObjectPass2ShaderInstance->TU_Albedo, MeshShader::DetailledObjectPass2ShaderInstance->TU_detail }, ListDetailSM::Arguments);
renderMeshes2ndPass<MeshShader::SplattingShader, video::EVT_2TCOORDS>(MeshShader::SplattingShaderInstance, { 8, MeshShader::SplattingShaderInstance->TU_tex_layout, MeshShader::SplattingShaderInstance->TU_tex_detail0, MeshShader::SplattingShaderInstance->TU_tex_detail1, MeshShader::SplattingShaderInstance->TU_tex_detail2, MeshShader::SplattingShaderInstance->TU_tex_detail3 }, ListSplattingSM::Arguments);
renderMeshes2ndPass<MeshShader::GrassPass2Shader, video::EVT_STANDARD>(MeshShader::GrassPass2ShaderInstance, { MeshShader::GrassPass2ShaderInstance->TU_Albedo }, ListGrassSM::Arguments);
}
}

View File

@ -340,8 +340,8 @@ void Shaders::loadShaders()
MeshShader::ObjectUnlitShaderInstance = new MeshShader::ObjectUnlitShader();
MeshShader::SphereMapShaderInstance = new MeshShader::SphereMapShader();
MeshShader::SplattingShaderInstance = new MeshShader::SplattingShader();
MeshShader::GrassPass1Shader::init();
MeshShader::GrassPass2Shader::init();
MeshShader::GrassPass1ShaderInstance = new MeshShader::GrassPass1Shader();
MeshShader::GrassPass2ShaderInstance = new MeshShader::GrassPass2Shader();
MeshShader::BubbleShader::init();
MeshShader::TransparentShaderInstance = new MeshShader::TransparentShader();
MeshShader::TransparentFogShaderInstance = new MeshShader::TransparentFogShader();
@ -517,31 +517,18 @@ namespace MeshShader
}
ObjectRefPass1Shader *ObjectRefPass1ShaderInstance;
GLuint GrassPass1Shader::Program;
GLuint GrassPass1Shader::uniform_MVP;
GLuint GrassPass1Shader::uniform_TIMV;
GLuint GrassPass1Shader::uniform_tex;
GLuint GrassPass1Shader::uniform_windDir;
void GrassPass1Shader::init()
GrassPass1Shader::GrassPass1Shader()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/grass_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str());
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_windDir = glGetUniformLocation(Program, "windDir");
AssignUniforms(Program, uniforms, { "ModelMatrix", "InverseModelMatrix", "windDir" });
TU_tex = 0;
AssignTextureUnit(Program, { { TU_tex, "tex" } });
}
void GrassPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex)
{
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer());
glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z);
glUniform1i(uniform_tex, TU_tex);
}
GrassPass1Shader *GrassPass1ShaderInstance;
NormalMapShader::NormalMapShader()
{
@ -784,34 +771,19 @@ namespace MeshShader
ObjectRefPass2Shader *ObjectRefPass2ShaderInstance;
GLuint GrassPass2Shader::Program;
GLuint GrassPass2Shader::uniform_MVP;
GLuint GrassPass2Shader::uniform_ambient;
GLuint GrassPass2Shader::uniform_windDir;
GLuint GrassPass2Shader::TU_Albedo;
void GrassPass2Shader::init()
GrassPass2Shader::GrassPass2Shader()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/grass_pass.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/grass_pass2.frag").c_str());
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
uniform_ambient = glGetUniformLocation(Program, "ambient");
uniform_windDir = glGetUniformLocation(Program, "windDir");
AssignUniforms(Program, uniforms, { "ModelMatrix", "windDir", "ambient" });
TU_Albedo = 3;
AssignTextureUnit(Program, { { 0, "DiffuseMap" }, { 1, "SpecularMap" }, { 2, "SSAO" }, { TU_Albedo, "Albedo" } });
}
void GrassPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix,
const core::vector3df &windDirection)
{
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight();
glUniform3f(uniform_ambient, s.r, s.g, s.b);
glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z);
}
GrassPass2Shader *GrassPass2ShaderInstance;
GLuint InstancedGrassPass2Shader::Program;
GLuint InstancedGrassPass2Shader::uniform_VP;

View File

@ -76,6 +76,13 @@ struct UniformHelper
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const core::vector3df &v, Args... arg)
{
glUniform3fWraper(uniforms[N], v.X, v.Y, v.Z);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, float f, Args... arg)
{
@ -124,16 +131,16 @@ public:
extern ObjectRefPass1Shader *ObjectRefPass1ShaderInstance;
class GrassPass1Shader
class GrassPass1Shader : public ShaderHelper<core::matrix4, core::matrix4, core::vector3df>
{
public:
static GLuint Program;
static GLuint uniform_MVP, uniform_TIMV, uniform_tex, uniform_windDir;
GLuint TU_tex;
static void init();
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex);
GrassPass1Shader();
};
extern GrassPass1Shader *GrassPass1ShaderInstance;
class NormalMapShader : public ShaderHelper<core::matrix4, core::matrix4>
{
public:
@ -235,17 +242,16 @@ public:
extern ObjectRefPass2Shader *ObjectRefPass2ShaderInstance;
class GrassPass2Shader
class GrassPass2Shader : public ShaderHelper<core::matrix4, core::vector3df, video::SColorf>
{
public:
static GLuint Program;
static GLuint uniform_MVP, uniform_ambient, uniform_windDir;
static GLuint TU_Albedo;
GLuint TU_Albedo;
static void init();
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection);
GrassPass2Shader();
};
extern GrassPass2Shader *GrassPass2ShaderInstance;
class InstancedGrassPass2Shader
{
public:

View File

@ -140,7 +140,6 @@ void STKAnimatedMesh::render()
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
TransposeInverseModelView = computeTIMV(AbsoluteTransformation);
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);

View File

@ -15,7 +15,7 @@ protected:
PtrVector<GLMesh, REF> ShadedMesh[SM_COUNT];
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
core::matrix4 ModelViewProjectionMatrix;
void cleanGLMeshes();
public:
STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent,

View File

@ -240,15 +240,6 @@ core::matrix4 computeMVP(const core::matrix4 &ModelMatrix)
return ModelViewProjectionMatrix;
}
core::matrix4 computeTIMV(const core::matrix4 &ModelMatrix)
{
core::matrix4 TransposeInverseModelView = irr_driver->getViewMatrix();
TransposeInverseModelView *= ModelMatrix;
TransposeInverseModelView.makeInverse();
TransposeInverseModelView = TransposeInverseModelView.getTransposed();
return TransposeInverseModelView;
}
core::vector3df getWind()
{
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
@ -258,48 +249,6 @@ core::vector3df getWind()
return m_speed * vector3df(1., 0., 0.) * cos(time);
}
void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
assert(mesh.VAOType == video::EVT_STANDARD);
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::GrassPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, windDir, 0);
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
}
void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, core::vector3df windDir)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
assert(mesh.VAOType == video::EVT_STANDARD);
if (!mesh.textures[0])
const_cast<GLMesh &>(mesh).textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::GrassPass2Shader::TU_Albedo, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
if (irr_driver->getLightViz())
{
GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA};
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
else
{
GLint swizzleMask[] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
MeshShader::GrassPass2Shader::setUniforms(ModelViewProjectionMatrix, windDir);
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex);
}
void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix)
{
irr_driver->IncreaseObjectCount();
@ -368,6 +317,7 @@ std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > ListDefaultStan
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > ListDefault2TCoordG::Arguments;
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, core::matrix4> > ListAlphaRefG::Arguments;
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > ListNormalG::Arguments;
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, core::vector3df> > ListGrassG::Arguments;
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, video::SColorf> > ListDefaultStandardSM::Arguments;
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, video::SColorf> > ListDefaultTangentSM::Arguments;
@ -380,3 +330,4 @@ std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > ListBlendTransp
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > ListAdditiveTransparent::Arguments;
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf> > ListBlendTransparentFog::Arguments;
std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf> > ListAdditiveTransparentFog::Arguments;
std::vector<std::tuple<GLMesh *, core::matrix4, core::vector3df, video::SColorf> > ListGrassSM::Arguments;

View File

@ -65,7 +65,6 @@ GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type);
void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat);
void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat);
core::matrix4 computeMVP(const core::matrix4 &ModelViewProjectionMatrix);
core::matrix4 computeTIMV(const core::matrix4 &TransposeInverseModelView);
bool isObject(video::E_MATERIAL_TYPE type);
core::vector3df getWind();
@ -95,30 +94,12 @@ public:
static std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4> > Arguments;
};
template<enum GeometricMaterial T>
class GroupedFPSM
class ListGrassG
{
public:
static std::vector<GLMesh *> MeshSet;
static std::vector<core::matrix4> MVPSet, TIMVSet;
static void reset()
{
MeshSet.clear();
MVPSet.clear();
TIMVSet.clear();
}
static std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, core::vector3df> > Arguments;
};
template<enum GeometricMaterial T>
std::vector<GLMesh *> GroupedFPSM<T>::MeshSet;
template<enum GeometricMaterial T>
std::vector<core::matrix4> GroupedFPSM<T>::MVPSet;
template<enum GeometricMaterial T>
std::vector<core::matrix4> GroupedFPSM<T>::TIMVSet;
template<typename Shader, typename...uniforms>
void draw(const GLMesh *mesh, uniforms... Args)
{
@ -131,6 +112,7 @@ void draw(const GLMesh *mesh, uniforms... Args)
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex);
}
template<typename T, typename...uniforms>
void draw(const T *Shader, const GLMesh *mesh, uniforms... Args)
{
@ -143,8 +125,6 @@ void draw(const T *Shader, const GLMesh *mesh, uniforms... Args)
glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex);
}
void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir);
// Pass 2 shader (ie shaders that outputs final color)
class ListDefaultStandardSM
{
@ -188,6 +168,12 @@ public:
static std::vector<std::tuple<GLMesh *, core::matrix4, video::SColorf> > Arguments;
};
class ListGrassSM
{
public:
static std::vector<std::tuple<GLMesh *, core::matrix4, core::vector3df, video::SColorf> > Arguments;
};
class ListBlendTransparent
{
public:
@ -212,49 +198,6 @@ public:
static std::vector<std::tuple<GLMesh *, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf> > Arguments;
};
template<enum ShadedMaterial T>
class GroupedSM
{
public:
static std::vector<GLMesh *> MeshSet;
static std::vector<core::matrix4> MVPSet, TIMVSet;
static void reset()
{
MeshSet.clear();
MVPSet.clear();
TIMVSet.clear();
}
};
template<enum ShadedMaterial T>
std::vector<GLMesh *> GroupedSM<T>::MeshSet;
template<enum ShadedMaterial T>
std::vector<core::matrix4> GroupedSM<T>::MVPSet;
template<enum ShadedMaterial T>
std::vector<core::matrix4> GroupedSM<T>::TIMVSet;
void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, core::vector3df windDir);
template<enum TransparentMaterial T>
class TransparentMeshes
{
public:
static std::vector<GLMesh *> MeshSet;
static std::vector<core::matrix4> MVPSet;
static void reset()
{
MeshSet.clear();
MVPSet.clear();
}
};
template<enum TransparentMaterial T>
std::vector<GLMesh *> TransparentMeshes<T>::MeshSet;
template<enum TransparentMaterial T>
std::vector<core::matrix4> TransparentMeshes<T>::MVPSet;
// Forward pass (for transparents meshes)
void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);

View File

@ -250,8 +250,6 @@ void STKMeshSceneNode::render()
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
TransposeInverseModelView = computeTIMV(AbsoluteTransformation);
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
@ -294,12 +292,9 @@ void STKMeshSceneNode::render()
for_in(mesh, GeometricMesh[FPSM_NORMAL_MAP])
ListNormalG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel));
if (!GeometricMesh[FPSM_GRASS].empty())
glUseProgram(MeshShader::GrassPass1Shader::Program);
windDir = getWind();
glBindVertexArray(getVAO(video::EVT_STANDARD));
for_in(mesh, GeometricMesh[FPSM_GRASS])
drawGrassPass1(*mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir);
ListGrassG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel, windDir));
return;
}
@ -357,11 +352,8 @@ void STKMeshSceneNode::render()
for_in(mesh, ShadedMesh[SM_DETAILS])
ListDetailSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, irr_driver->getSceneManager()->getAmbientLight()));
if (!ShadedMesh[SM_GRASS].empty())
glUseProgram(MeshShader::GrassPass2Shader::Program);
glBindVertexArray(getVAO(video::EVT_STANDARD));
for_in(mesh, ShadedMesh[SM_GRASS])
drawGrassPass2(*mesh, ModelViewProjectionMatrix, windDir);
ListGrassSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, windDir, irr_driver->getSceneManager()->getAmbientLight()));
return;
}

View File

@ -11,7 +11,7 @@ protected:
PtrVector<GLMesh, REF> ShadedMesh[SM_COUNT];
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView;
core::matrix4 ModelViewProjectionMatrix;
core::vector3df windDir;
core::vector2df caustic_dir, caustic_dir2;