forked from teamnwah/openmw-tes3coop
Add terrain shaders and normal map support
Textures with _n filename suffix are automatically recognized as terrain normal maps.
This commit is contained in:
parent
17c4dfdb62
commit
6000e48bba
8 changed files with 283 additions and 15 deletions
|
@ -228,6 +228,11 @@ namespace Resource
|
||||||
mForceShaders = force;
|
mForceShaders = force;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SceneManager::getForceShaders() const
|
||||||
|
{
|
||||||
|
return mForceShaders;
|
||||||
|
}
|
||||||
|
|
||||||
void SceneManager::recreateShaders(osg::ref_ptr<osg::Node> node)
|
void SceneManager::recreateShaders(osg::ref_ptr<osg::Node> node)
|
||||||
{
|
{
|
||||||
Shader::ShaderVisitor shaderVisitor(*mShaderManager.get(), "objects_vertex.glsl", "objects_fragment.glsl");
|
Shader::ShaderVisitor shaderVisitor(*mShaderManager.get(), "objects_vertex.glsl", "objects_fragment.glsl");
|
||||||
|
@ -243,16 +248,31 @@ namespace Resource
|
||||||
mClampLighting = clamp;
|
mClampLighting = clamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SceneManager::getClampLighting() const
|
||||||
|
{
|
||||||
|
return mClampLighting;
|
||||||
|
}
|
||||||
|
|
||||||
void SceneManager::setForcePerPixelLighting(bool force)
|
void SceneManager::setForcePerPixelLighting(bool force)
|
||||||
{
|
{
|
||||||
mForcePerPixelLighting = force;
|
mForcePerPixelLighting = force;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SceneManager::getForcePerPixelLighting() const
|
||||||
|
{
|
||||||
|
return mForcePerPixelLighting;
|
||||||
|
}
|
||||||
|
|
||||||
SceneManager::~SceneManager()
|
SceneManager::~SceneManager()
|
||||||
{
|
{
|
||||||
// this has to be defined in the .cpp file as we can't delete incomplete types
|
// this has to be defined in the .cpp file as we can't delete incomplete types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shader::ShaderManager &SceneManager::getShaderManager()
|
||||||
|
{
|
||||||
|
return *mShaderManager.get();
|
||||||
|
}
|
||||||
|
|
||||||
void SceneManager::setShaderPath(const std::string &path)
|
void SceneManager::setShaderPath(const std::string &path)
|
||||||
{
|
{
|
||||||
mShaderManager->setShaderPath(path);
|
mShaderManager->setShaderPath(path);
|
||||||
|
|
|
@ -40,17 +40,22 @@ namespace Resource
|
||||||
SceneManager(const VFS::Manager* vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager);
|
SceneManager(const VFS::Manager* vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager);
|
||||||
~SceneManager();
|
~SceneManager();
|
||||||
|
|
||||||
|
Shader::ShaderManager& getShaderManager();
|
||||||
|
|
||||||
/// Re-create shaders for this node, need to call this if texture stages or vertex color mode have changed.
|
/// Re-create shaders for this node, need to call this if texture stages or vertex color mode have changed.
|
||||||
void recreateShaders(osg::ref_ptr<osg::Node> node);
|
void recreateShaders(osg::ref_ptr<osg::Node> node);
|
||||||
|
|
||||||
/// @see ShaderVisitor::setForceShaders
|
/// @see ShaderVisitor::setForceShaders
|
||||||
void setForceShaders(bool force);
|
void setForceShaders(bool force);
|
||||||
|
bool getForceShaders() const;
|
||||||
|
|
||||||
/// @see ShaderVisitor::setClampLighting
|
/// @see ShaderVisitor::setClampLighting
|
||||||
void setClampLighting(bool clamp);
|
void setClampLighting(bool clamp);
|
||||||
|
bool getClampLighting() const;
|
||||||
|
|
||||||
/// @see ShaderVisitor::setForcePerPixelLighting
|
/// @see ShaderVisitor::setForcePerPixelLighting
|
||||||
void setForcePerPixelLighting(bool force);
|
void setForcePerPixelLighting(bool force);
|
||||||
|
bool getForcePerPixelLighting() const;
|
||||||
|
|
||||||
void setShaderPath(const std::string& path);
|
void setShaderPath(const std::string& path);
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
#include "material.hpp"
|
#include "material.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <osg/Depth>
|
#include <osg/Depth>
|
||||||
#include <osg/TexEnvCombine>
|
#include <osg/TexEnvCombine>
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
#include <osg/TexMat>
|
#include <osg/TexMat>
|
||||||
#include <osg/Material>
|
#include <osg/Material>
|
||||||
#include <osg/TexEnvCombine>
|
|
||||||
|
#include <components/shader/shadermanager.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace Terrain
|
namespace Terrain
|
||||||
{
|
{
|
||||||
|
|
||||||
FixedFunctionTechnique::FixedFunctionTechnique(const std::vector<osg::ref_ptr<osg::Texture2D> >& layers,
|
FixedFunctionTechnique::FixedFunctionTechnique(const std::vector<TextureLayer>& layers,
|
||||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize)
|
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize)
|
||||||
{
|
{
|
||||||
bool firstLayer = true;
|
bool firstLayer = true;
|
||||||
int i=0;
|
int i=0;
|
||||||
for (std::vector<osg::ref_ptr<osg::Texture2D> >::const_iterator it = layers.begin(); it != layers.end(); ++it)
|
for (std::vector<TextureLayer>::const_iterator it = layers.begin(); it != layers.end(); ++it)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
|
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
|
||||||
|
|
||||||
|
@ -53,7 +58,7 @@ namespace Terrain
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the actual layer texture multiplied by the alpha map.
|
// Add the actual layer texture multiplied by the alpha map.
|
||||||
osg::ref_ptr<osg::Texture2D> tex = *it;
|
osg::ref_ptr<osg::Texture2D> tex = it->mDiffuseMap;
|
||||||
stateset->setTextureAttributeAndModes(texunit, tex.get());
|
stateset->setTextureAttributeAndModes(texunit, tex.get());
|
||||||
|
|
||||||
osg::ref_ptr<osg::TexMat> texMat (new osg::TexMat);
|
osg::ref_ptr<osg::TexMat> texMat (new osg::TexMat);
|
||||||
|
@ -66,9 +71,85 @@ namespace Terrain
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Effect::Effect(const std::vector<osg::ref_ptr<osg::Texture2D> > &layers, const std::vector<osg::ref_ptr<osg::Texture2D> > &blendmaps,
|
ShaderTechnique::ShaderTechnique(Shader::ShaderManager& shaderManager, bool forcePerPixelLighting, bool clampLighting, const std::vector<TextureLayer>& layers,
|
||||||
|
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize)
|
||||||
|
{
|
||||||
|
bool firstLayer = true;
|
||||||
|
int i=0;
|
||||||
|
for (std::vector<TextureLayer>::const_iterator it = layers.begin(); it != layers.end(); ++it)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
|
||||||
|
|
||||||
|
if (!firstLayer)
|
||||||
|
{
|
||||||
|
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||||
|
osg::ref_ptr<osg::Depth> depth (new osg::Depth);
|
||||||
|
depth->setFunction(osg::Depth::EQUAL);
|
||||||
|
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
int texunit = 0;
|
||||||
|
|
||||||
|
stateset->setTextureAttributeAndModes(texunit, it->mDiffuseMap);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::TexMat> texMat (new osg::TexMat);
|
||||||
|
texMat->setMatrix(osg::Matrix::scale(osg::Vec3f(layerTileSize,layerTileSize,1.f)));
|
||||||
|
stateset->setTextureAttributeAndModes(texunit, texMat, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
stateset->addUniform(new osg::Uniform("diffuseMap", texunit));
|
||||||
|
|
||||||
|
if(!firstLayer)
|
||||||
|
{
|
||||||
|
++texunit;
|
||||||
|
osg::ref_ptr<osg::Texture2D> blendmap = blendmaps.at(i++);
|
||||||
|
|
||||||
|
stateset->setTextureAttributeAndModes(texunit, blendmap.get());
|
||||||
|
|
||||||
|
// This is to map corner vertices directly to the center of a blendmap texel.
|
||||||
|
osg::Matrixf texMat;
|
||||||
|
float scale = (blendmapScale/(static_cast<float>(blendmapScale)+1.f));
|
||||||
|
texMat.preMultTranslate(osg::Vec3f(0.5f, 0.5f, 0.f));
|
||||||
|
texMat.preMultScale(osg::Vec3f(scale, scale, 1.f));
|
||||||
|
texMat.preMultTranslate(osg::Vec3f(-0.5f, -0.5f, 0.f));
|
||||||
|
|
||||||
|
stateset->setTextureAttributeAndModes(texunit, new osg::TexMat(texMat));
|
||||||
|
stateset->addUniform(new osg::Uniform("blendMap", texunit));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it->mNormalMap)
|
||||||
|
{
|
||||||
|
++texunit;
|
||||||
|
stateset->setTextureAttributeAndModes(texunit, it->mNormalMap);
|
||||||
|
stateset->addUniform(new osg::Uniform("normalMap", texunit));
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::ShaderManager::DefineMap defineMap;
|
||||||
|
defineMap["forcePPL"] = forcePerPixelLighting ? "1" : "0";
|
||||||
|
defineMap["clamp"] = clampLighting ? "1" : "0";
|
||||||
|
defineMap["normalMap"] = (it->mNormalMap) ? "1" : "0";
|
||||||
|
defineMap["blendMap"] = !firstLayer ? "1" : "0";
|
||||||
|
defineMap["colorMode"] = "2";
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Shader> vertexShader = shaderManager.getShader("terrain_vertex.glsl", defineMap, osg::Shader::VERTEX);
|
||||||
|
osg::ref_ptr<osg::Shader> fragmentShader = shaderManager.getShader("terrain_fragment.glsl", defineMap, osg::Shader::FRAGMENT);
|
||||||
|
if (!vertexShader || !fragmentShader)
|
||||||
|
throw std::runtime_error("Unable to create shader");
|
||||||
|
|
||||||
|
stateset->setAttributeAndModes(shaderManager.getProgram(vertexShader, fragmentShader));
|
||||||
|
|
||||||
|
firstLayer = false;
|
||||||
|
|
||||||
|
addPass(stateset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Effect::Effect(bool useShaders, bool forcePerPixelLighting, bool clampLighting, Shader::ShaderManager& shaderManager, const std::vector<TextureLayer> &layers, const std::vector<osg::ref_ptr<osg::Texture2D> > &blendmaps,
|
||||||
int blendmapScale, float layerTileSize)
|
int blendmapScale, float layerTileSize)
|
||||||
: mLayers(layers)
|
: mShaderManager(shaderManager)
|
||||||
|
, mUseShaders(useShaders)
|
||||||
|
, mForcePerPixelLighting(forcePerPixelLighting)
|
||||||
|
, mClampLighting(clampLighting)
|
||||||
|
, mLayers(layers)
|
||||||
, mBlendmaps(blendmaps)
|
, mBlendmaps(blendmaps)
|
||||||
, mBlendmapScale(blendmapScale)
|
, mBlendmapScale(blendmapScale)
|
||||||
, mLayerTileSize(layerTileSize)
|
, mLayerTileSize(layerTileSize)
|
||||||
|
@ -82,7 +163,18 @@ namespace Terrain
|
||||||
|
|
||||||
bool Effect::define_techniques()
|
bool Effect::define_techniques()
|
||||||
{
|
{
|
||||||
addTechnique(new FixedFunctionTechnique(mLayers, mBlendmaps, mBlendmapScale, mLayerTileSize));
|
try
|
||||||
|
{
|
||||||
|
if (mUseShaders)
|
||||||
|
addTechnique(new ShaderTechnique(mShaderManager, mForcePerPixelLighting, mClampLighting, mLayers, mBlendmaps, mBlendmapScale, mLayerTileSize));
|
||||||
|
else
|
||||||
|
addTechnique(new FixedFunctionTechnique(mLayers, mBlendmaps, mBlendmapScale, mLayerTileSize));
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: " << e.what() << std::endl;
|
||||||
|
addTechnique(new FixedFunctionTechnique(mLayers, mBlendmaps, mBlendmapScale, mLayerTileSize));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,36 @@ namespace osg
|
||||||
class Texture2D;
|
class Texture2D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Shader
|
||||||
|
{
|
||||||
|
class ShaderManager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Terrain
|
namespace Terrain
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct TextureLayer
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Texture2D> mDiffuseMap;
|
||||||
|
osg::ref_ptr<osg::Texture2D> mNormalMap; // optional
|
||||||
|
};
|
||||||
|
|
||||||
class FixedFunctionTechnique : public osgFX::Technique
|
class FixedFunctionTechnique : public osgFX::Technique
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FixedFunctionTechnique(
|
FixedFunctionTechnique(
|
||||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& layers,
|
const std::vector<TextureLayer>& layers,
|
||||||
|
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void define_passes() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderTechnique : public osgFX::Technique
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShaderTechnique(Shader::ShaderManager& shaderManager, bool forcePerPixelLighting, bool clampLighting,
|
||||||
|
const std::vector<TextureLayer>& layers,
|
||||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize);
|
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -28,8 +50,8 @@ namespace Terrain
|
||||||
class Effect : public osgFX::Effect
|
class Effect : public osgFX::Effect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Effect(
|
Effect(bool useShaders, bool forcePerPixelLighting, bool clampLighting, Shader::ShaderManager& shaderManager,
|
||||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& layers,
|
const std::vector<TextureLayer>& layers,
|
||||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize);
|
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize);
|
||||||
|
|
||||||
virtual bool define_techniques();
|
virtual bool define_techniques();
|
||||||
|
@ -48,7 +70,11 @@ namespace Terrain
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<osg::ref_ptr<osg::Texture2D> > mLayers;
|
Shader::ShaderManager& mShaderManager;
|
||||||
|
bool mUseShaders;
|
||||||
|
bool mForcePerPixelLighting;
|
||||||
|
bool mClampLighting;
|
||||||
|
std::vector<TextureLayer> mLayers;
|
||||||
std::vector<osg::ref_ptr<osg::Texture2D> > mBlendmaps;
|
std::vector<osg::ref_ptr<osg::Texture2D> > mBlendmaps;
|
||||||
int mBlendmapScale;
|
int mBlendmapScale;
|
||||||
float mLayerTileSize;
|
float mLayerTileSize;
|
||||||
|
|
|
@ -148,11 +148,15 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
||||||
osg::ref_ptr<osg::Node> textureCompileDummy (new osg::Node);
|
osg::ref_ptr<osg::Node> textureCompileDummy (new osg::Node);
|
||||||
unsigned int dummyTextureCounter = 0;
|
unsigned int dummyTextureCounter = 0;
|
||||||
|
|
||||||
std::vector<osg::ref_ptr<osg::Texture2D> > layerTextures;
|
bool useShaders = mResourceSystem->getSceneManager()->getForceShaders();
|
||||||
|
if (!mResourceSystem->getSceneManager()->getClampLighting())
|
||||||
|
useShaders = true; // always use shaders when lighting is unclamped, this is to avoid lighting seams between a terrain chunk with normal maps and one without normal maps
|
||||||
|
std::vector<TextureLayer> layers;
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mTextureCacheMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mTextureCacheMutex);
|
||||||
for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it)
|
for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it)
|
||||||
{
|
{
|
||||||
|
TextureLayer textureLayer;
|
||||||
osg::ref_ptr<osg::Texture2D> texture = mTextureCache[it->mDiffuseMap];
|
osg::ref_ptr<osg::Texture2D> texture = mTextureCache[it->mDiffuseMap];
|
||||||
if (!texture)
|
if (!texture)
|
||||||
{
|
{
|
||||||
|
@ -162,8 +166,26 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
||||||
mResourceSystem->getSceneManager()->applyFilterSettings(texture);
|
mResourceSystem->getSceneManager()->applyFilterSettings(texture);
|
||||||
mTextureCache[it->mDiffuseMap] = texture;
|
mTextureCache[it->mDiffuseMap] = texture;
|
||||||
}
|
}
|
||||||
layerTextures.push_back(texture);
|
textureLayer.mDiffuseMap = texture;
|
||||||
textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, layerTextures.back());
|
textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, texture);
|
||||||
|
|
||||||
|
if (!it->mNormalMap.empty())
|
||||||
|
{
|
||||||
|
texture = mTextureCache[it->mNormalMap];
|
||||||
|
if (!texture)
|
||||||
|
{
|
||||||
|
texture = new osg::Texture2D(mResourceSystem->getImageManager()->getImage(it->mNormalMap));
|
||||||
|
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
|
||||||
|
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
|
||||||
|
mResourceSystem->getSceneManager()->applyFilterSettings(texture);
|
||||||
|
mTextureCache[it->mNormalMap] = texture;
|
||||||
|
}
|
||||||
|
textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, texture);
|
||||||
|
textureLayer.mNormalMap = texture;
|
||||||
|
useShaders = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
layers.push_back(textureLayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +207,8 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
||||||
geometry->setTexCoordArray(i, mCache.getUVBuffer());
|
geometry->setTexCoordArray(i, mCache.getUVBuffer());
|
||||||
|
|
||||||
float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize;
|
float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize;
|
||||||
osg::ref_ptr<osgFX::Effect> effect (new Terrain::Effect(layerTextures, blendmapTextures, blendmapScale, blendmapScale));
|
osg::ref_ptr<osgFX::Effect> effect (new Terrain::Effect(useShaders, mResourceSystem->getSceneManager()->getForcePerPixelLighting(), mResourceSystem->getSceneManager()->getClampLighting(),
|
||||||
|
mResourceSystem->getSceneManager()->getShaderManager(), layers, blendmapTextures, blendmapScale, blendmapScale));
|
||||||
|
|
||||||
effect->addCullCallback(new SceneUtil::LightListCallback);
|
effect->addCullCallback(new SceneUtil::LightListCallback);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ set(SHADER_FILES
|
||||||
water_nm.png
|
water_nm.png
|
||||||
objects_vertex.glsl
|
objects_vertex.glsl
|
||||||
objects_fragment.glsl
|
objects_fragment.glsl
|
||||||
|
terrain_vertex.glsl
|
||||||
|
terrain_fragment.glsl
|
||||||
lighting.glsl
|
lighting.glsl
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
64
files/shaders/terrain_fragment.glsl
Normal file
64
files/shaders/terrain_fragment.glsl
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
varying vec2 uv;
|
||||||
|
|
||||||
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
#if @normalMap
|
||||||
|
uniform sampler2D normalMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @blendMap
|
||||||
|
uniform sampler2D blendMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying float depth;
|
||||||
|
|
||||||
|
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
|
||||||
|
|
||||||
|
#if !PER_PIXEL_LIGHTING
|
||||||
|
varying vec4 lighting;
|
||||||
|
#else
|
||||||
|
varying vec3 passViewPos;
|
||||||
|
varying vec3 passViewNormal;
|
||||||
|
varying vec4 passColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "lighting.glsl"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 diffuseMapUV = (gl_TextureMatrix[0] * vec4(uv, 0.0, 1.0)).xy;
|
||||||
|
|
||||||
|
gl_FragData[0] = vec4(texture2D(diffuseMap, diffuseMapUV).xyz, 1.0);
|
||||||
|
|
||||||
|
#if @blendMap
|
||||||
|
vec2 blendMapUV = (gl_TextureMatrix[1] * vec4(uv, 0.0, 1.0)).xy;
|
||||||
|
gl_FragData[0].a *= texture2D(blendMap, blendMapUV).a;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PER_PIXEL_LIGHTING
|
||||||
|
vec3 viewNormal = passViewNormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @normalMap
|
||||||
|
vec3 normalTex = texture2D(normalMap, diffuseMapUV).xyz;
|
||||||
|
|
||||||
|
vec3 viewTangent = (gl_ModelViewMatrix * vec4(1.0, 0.0, 0.0, 0.0)).xyz;
|
||||||
|
vec3 viewBinormal = normalize(cross(viewTangent, viewNormal));
|
||||||
|
viewTangent = normalize(cross(viewNormal, viewBinormal)); // note, now we need to re-cross to derive tangent again because it wasn't orthonormal
|
||||||
|
mat3 tbn = mat3(viewTangent, viewBinormal, viewNormal);
|
||||||
|
|
||||||
|
viewNormal = normalize(tbn * (normalTex * 2.0 - 1.0));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !PER_PIXEL_LIGHTING
|
||||||
|
gl_FragData[0] *= lighting;
|
||||||
|
#else
|
||||||
|
gl_FragData[0] *= doLighting(passViewPos, normalize(viewNormal), passColor);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float fogValue = clamp((depth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
|
||||||
|
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
|
||||||
|
}
|
36
files/shaders/terrain_vertex.glsl
Normal file
36
files/shaders/terrain_vertex.glsl
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
varying vec2 uv;
|
||||||
|
varying float depth;
|
||||||
|
|
||||||
|
#define PER_PIXEL_LIGHTING (@normalMap || @forcePPL)
|
||||||
|
|
||||||
|
#if !PER_PIXEL_LIGHTING
|
||||||
|
varying vec4 lighting;
|
||||||
|
#else
|
||||||
|
varying vec3 passViewPos;
|
||||||
|
varying vec3 passViewNormal;
|
||||||
|
varying vec4 passColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "lighting.glsl"
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
depth = gl_Position.z;
|
||||||
|
|
||||||
|
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
||||||
|
gl_ClipVertex = viewPos;
|
||||||
|
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);
|
||||||
|
|
||||||
|
#if !PER_PIXEL_LIGHTING
|
||||||
|
lighting = doLighting(viewPos.xyz, viewNormal, gl_Color);
|
||||||
|
#else
|
||||||
|
passViewPos = viewPos.xyz;
|
||||||
|
passViewNormal = viewNormal;
|
||||||
|
passColor = gl_Color;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uv = gl_MultiTexCoord0.xy;
|
||||||
|
}
|
Loading…
Reference in a new issue