mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 08:53:52 +00:00
Merge branch 'nifnifnifnifnif' into 'master'
Add in incomplete BSShader[PP/No]LightingProperty work before it rots away See merge request OpenMW/openmw!681
This commit is contained in:
commit
a86b6ff6e2
15 changed files with 509 additions and 15 deletions
|
@ -133,6 +133,8 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
|
||||||
factory["BSShaderTextureSet"] = {&construct <BSShaderTextureSet> , RC_BSShaderTextureSet };
|
factory["BSShaderTextureSet"] = {&construct <BSShaderTextureSet> , RC_BSShaderTextureSet };
|
||||||
factory["BSLODTriShape"] = {&construct <BSLODTriShape> , RC_BSLODTriShape };
|
factory["BSLODTriShape"] = {&construct <BSLODTriShape> , RC_BSLODTriShape };
|
||||||
factory["BSShaderProperty"] = {&construct <BSShaderProperty> , RC_BSShaderProperty };
|
factory["BSShaderProperty"] = {&construct <BSShaderProperty> , RC_BSShaderProperty };
|
||||||
|
factory["BSShaderPPLightingProperty"] = {&construct <BSShaderPPLightingProperty> , RC_BSShaderPPLightingProperty };
|
||||||
|
factory["BSShaderNoLightingProperty"] = {&construct <BSShaderNoLightingProperty> , RC_BSShaderNoLightingProperty };
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,34 @@ void BSShaderLightingProperty::read(NIFStream *nif)
|
||||||
clamp = nif->getUInt();
|
clamp = nif->getUInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BSShaderPPLightingProperty::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
BSShaderLightingProperty::read(nif);
|
||||||
|
textureSet.read(nif);
|
||||||
|
if (nif->getBethVersion() <= 14)
|
||||||
|
return;
|
||||||
|
refraction.strength = nif->getFloat();
|
||||||
|
refraction.period = nif->getInt();
|
||||||
|
if (nif->getBethVersion() <= 24)
|
||||||
|
return;
|
||||||
|
parallax.passes = nif->getFloat();
|
||||||
|
parallax.scale = nif->getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSShaderPPLightingProperty::post(NIFFile *nif)
|
||||||
|
{
|
||||||
|
BSShaderLightingProperty::post(nif);
|
||||||
|
textureSet.post(nif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BSShaderNoLightingProperty::read(NIFStream *nif)
|
||||||
|
{
|
||||||
|
BSShaderLightingProperty::read(nif);
|
||||||
|
filename = nif->getSizedString();
|
||||||
|
if (nif->getBethVersion() >= 27)
|
||||||
|
falloffParams = nif->getVector4();
|
||||||
|
}
|
||||||
|
|
||||||
void NiFogProperty::read(NIFStream *nif)
|
void NiFogProperty::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
Property::read(nif);
|
Property::read(nif);
|
||||||
|
@ -137,8 +165,8 @@ void S_MaterialProperty::read(NIFStream *nif)
|
||||||
emissive = nif->getVector3();
|
emissive = nif->getVector3();
|
||||||
glossiness = nif->getFloat();
|
glossiness = nif->getFloat();
|
||||||
alpha = nif->getFloat();
|
alpha = nif->getFloat();
|
||||||
if (nif->getBethVersion() > 21)
|
if (nif->getBethVersion() >= 22)
|
||||||
emissive *= nif->getFloat();
|
emissiveMult = nif->getFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_VertexColorProperty::read(NIFStream *nif)
|
void S_VertexColorProperty::read(NIFStream *nif)
|
||||||
|
|
|
@ -118,6 +118,18 @@ struct NiShadeProperty : public Property
|
||||||
|
|
||||||
struct BSShaderProperty : public NiShadeProperty
|
struct BSShaderProperty : public NiShadeProperty
|
||||||
{
|
{
|
||||||
|
enum BSShaderType
|
||||||
|
{
|
||||||
|
SHADER_TALL_GRASS = 0,
|
||||||
|
SHADER_DEFAULT = 1,
|
||||||
|
SHADER_SKY = 10,
|
||||||
|
SHADER_SKIN = 14,
|
||||||
|
SHADER_WATER = 17,
|
||||||
|
SHADER_LIGHTING30 = 29,
|
||||||
|
SHADER_TILE = 32,
|
||||||
|
SHADER_NOLIGHTING = 33
|
||||||
|
};
|
||||||
|
|
||||||
unsigned int type{0u}, flags1{0u}, flags2{0u};
|
unsigned int type{0u}, flags1{0u}, flags2{0u};
|
||||||
float envMapIntensity{0.f};
|
float envMapIntensity{0.f};
|
||||||
void read(NIFStream *nif) override;
|
void read(NIFStream *nif) override;
|
||||||
|
@ -129,6 +141,34 @@ struct BSShaderLightingProperty : public BSShaderProperty
|
||||||
void read(NIFStream *nif) override;
|
void read(NIFStream *nif) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BSShaderPPLightingProperty : public BSShaderLightingProperty
|
||||||
|
{
|
||||||
|
BSShaderTextureSetPtr textureSet;
|
||||||
|
struct RefractionSettings
|
||||||
|
{
|
||||||
|
float strength{0.f};
|
||||||
|
int period{0};
|
||||||
|
};
|
||||||
|
struct ParallaxSettings
|
||||||
|
{
|
||||||
|
float passes{0.f};
|
||||||
|
float scale{0.f};
|
||||||
|
};
|
||||||
|
RefractionSettings refraction;
|
||||||
|
ParallaxSettings parallax;
|
||||||
|
|
||||||
|
void read(NIFStream *nif) override;
|
||||||
|
void post(NIFFile *nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BSShaderNoLightingProperty : public BSShaderLightingProperty
|
||||||
|
{
|
||||||
|
std::string filename;
|
||||||
|
osg::Vec4f falloffParams;
|
||||||
|
|
||||||
|
void read(NIFStream *nif) override;
|
||||||
|
};
|
||||||
|
|
||||||
struct NiDitherProperty : public Property
|
struct NiDitherProperty : public Property
|
||||||
{
|
{
|
||||||
unsigned short flags;
|
unsigned short flags;
|
||||||
|
@ -193,7 +233,7 @@ struct S_MaterialProperty
|
||||||
// The vector components are R,G,B
|
// The vector components are R,G,B
|
||||||
osg::Vec3f ambient{1.f,1.f,1.f}, diffuse{1.f,1.f,1.f};
|
osg::Vec3f ambient{1.f,1.f,1.f}, diffuse{1.f,1.f,1.f};
|
||||||
osg::Vec3f specular, emissive;
|
osg::Vec3f specular, emissive;
|
||||||
float glossiness{0.f}, alpha{0.f};
|
float glossiness{0.f}, alpha{0.f}, emissiveMult{1.f};
|
||||||
|
|
||||||
void read(NIFStream *nif);
|
void read(NIFStream *nif);
|
||||||
};
|
};
|
||||||
|
|
|
@ -122,7 +122,9 @@ enum RecordType
|
||||||
RC_NiColorInterpolator,
|
RC_NiColorInterpolator,
|
||||||
RC_BSShaderTextureSet,
|
RC_BSShaderTextureSet,
|
||||||
RC_BSLODTriShape,
|
RC_BSLODTriShape,
|
||||||
RC_BSShaderProperty
|
RC_BSShaderProperty,
|
||||||
|
RC_BSShaderPPLightingProperty,
|
||||||
|
RC_BSShaderNoLightingProperty
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for all records
|
/// Base class for all records
|
||||||
|
|
|
@ -1672,6 +1672,85 @@ namespace NifOsg
|
||||||
handleTextureControllers(texprop, composite, imageManager, stateset, animflags);
|
handleTextureControllers(texprop, composite, imageManager, stateset, animflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleTextureSet(const Nif::BSShaderTextureSet* textureSet, unsigned int clamp, const std::string& nodeName, osg::StateSet* stateset, Resource::ImageManager* imageManager, std::vector<unsigned int>& boundTextures)
|
||||||
|
{
|
||||||
|
if (!boundTextures.empty())
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < boundTextures.size(); ++i)
|
||||||
|
stateset->setTextureMode(i, GL_TEXTURE_2D, osg::StateAttribute::OFF);
|
||||||
|
boundTextures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned int uvSet = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < textureSet->textures.size(); ++i)
|
||||||
|
{
|
||||||
|
if (textureSet->textures[i].empty())
|
||||||
|
continue;
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case Nif::BSShaderTextureSet::TextureType_Base:
|
||||||
|
case Nif::BSShaderTextureSet::TextureType_Normal:
|
||||||
|
case Nif::BSShaderTextureSet::TextureType_Glow:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Log(Debug::Info) << "Unhandled texture stage " << i << " on shape \"" << nodeName << "\" in " << mFilename;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string filename = Misc::ResourceHelpers::correctTexturePath(textureSet->textures[i], imageManager->getVFS());
|
||||||
|
osg::ref_ptr<osg::Image> image = imageManager->getImage(filename);
|
||||||
|
osg::ref_ptr<osg::Texture2D> texture2d = new osg::Texture2D(image);
|
||||||
|
if (image)
|
||||||
|
texture2d->setTextureSize(image->s(), image->t());
|
||||||
|
bool wrapT = clamp & 0x1;
|
||||||
|
bool wrapS = (clamp >> 1) & 0x1;
|
||||||
|
texture2d->setWrap(osg::Texture::WRAP_S, wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE);
|
||||||
|
texture2d->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE);
|
||||||
|
unsigned int texUnit = boundTextures.size();
|
||||||
|
stateset->setTextureAttributeAndModes(texUnit, texture2d, osg::StateAttribute::ON);
|
||||||
|
// BSShaderTextureSet presence means there's no need for FFP support for the affected node
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case Nif::BSShaderTextureSet::TextureType_Base:
|
||||||
|
texture2d->setName("diffuseMap");
|
||||||
|
break;
|
||||||
|
case Nif::BSShaderTextureSet::TextureType_Normal:
|
||||||
|
texture2d->setName("normalMap");
|
||||||
|
break;
|
||||||
|
case Nif::BSShaderTextureSet::TextureType_Glow:
|
||||||
|
texture2d->setName("emissiveMap");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
boundTextures.emplace_back(uvSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& getNVShaderPrefix(unsigned int type) const
|
||||||
|
{
|
||||||
|
static const std::map<unsigned int, std::string> mapping =
|
||||||
|
{
|
||||||
|
{Nif::BSShaderProperty::SHADER_TALL_GRASS, std::string()},
|
||||||
|
{Nif::BSShaderProperty::SHADER_DEFAULT, "nv_default"},
|
||||||
|
{Nif::BSShaderProperty::SHADER_SKY, std::string()},
|
||||||
|
{Nif::BSShaderProperty::SHADER_SKIN, std::string()},
|
||||||
|
{Nif::BSShaderProperty::SHADER_WATER, std::string()},
|
||||||
|
{Nif::BSShaderProperty::SHADER_LIGHTING30, std::string()},
|
||||||
|
{Nif::BSShaderProperty::SHADER_TILE, std::string()},
|
||||||
|
{Nif::BSShaderProperty::SHADER_NOLIGHTING, "nv_nolighting"},
|
||||||
|
};
|
||||||
|
auto prefix = mapping.find(type);
|
||||||
|
if (prefix == mapping.end())
|
||||||
|
Log(Debug::Warning) << "Unknown shader type " << type << " in " << mFilename;
|
||||||
|
else if (prefix->second.empty())
|
||||||
|
Log(Debug::Warning) << "Unhandled shader type " << type << " in " << mFilename;
|
||||||
|
else
|
||||||
|
return prefix->second;
|
||||||
|
|
||||||
|
return mapping.at(Nif::BSShaderProperty::SHADER_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
void handleProperty(const Nif::Property *property,
|
void handleProperty(const Nif::Property *property,
|
||||||
osg::Node *node, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector<unsigned int>& boundTextures, int animflags)
|
osg::Node *node, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector<unsigned int>& boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
|
@ -1757,6 +1836,63 @@ namespace NifOsg
|
||||||
handleTextureProperty(texprop, node->getName(), stateset, composite, imageManager, boundTextures, animflags);
|
handleTextureProperty(texprop, node->getName(), stateset, composite, imageManager, boundTextures, animflags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Nif::RC_BSShaderPPLightingProperty:
|
||||||
|
{
|
||||||
|
auto texprop = static_cast<const Nif::BSShaderPPLightingProperty*>(property);
|
||||||
|
bool shaderRequired = true;
|
||||||
|
node->setUserValue("shaderPrefix", getNVShaderPrefix(texprop->type));
|
||||||
|
node->setUserValue("shaderRequired", shaderRequired);
|
||||||
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
||||||
|
if (!texprop->textureSet.empty())
|
||||||
|
{
|
||||||
|
auto textureSet = texprop->textureSet.getPtr();
|
||||||
|
handleTextureSet(textureSet, texprop->clamp, node->getName(), stateset, imageManager, boundTextures);
|
||||||
|
}
|
||||||
|
handleTextureControllers(texprop, composite, imageManager, stateset, animflags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Nif::RC_BSShaderNoLightingProperty:
|
||||||
|
{
|
||||||
|
auto texprop = static_cast<const Nif::BSShaderNoLightingProperty*>(property);
|
||||||
|
bool shaderRequired = true;
|
||||||
|
node->setUserValue("shaderPrefix", getNVShaderPrefix(texprop->type));
|
||||||
|
node->setUserValue("shaderRequired", shaderRequired);
|
||||||
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
||||||
|
if (!texprop->filename.empty())
|
||||||
|
{
|
||||||
|
if (!boundTextures.empty())
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < boundTextures.size(); ++i)
|
||||||
|
stateset->setTextureMode(i, GL_TEXTURE_2D, osg::StateAttribute::OFF);
|
||||||
|
boundTextures.clear();
|
||||||
|
}
|
||||||
|
std::string filename = Misc::ResourceHelpers::correctTexturePath(texprop->filename, imageManager->getVFS());
|
||||||
|
osg::ref_ptr<osg::Image> image = imageManager->getImage(filename);
|
||||||
|
osg::ref_ptr<osg::Texture2D> texture2d = new osg::Texture2D(image);
|
||||||
|
texture2d->setName("diffuseMap");
|
||||||
|
if (image)
|
||||||
|
texture2d->setTextureSize(image->s(), image->t());
|
||||||
|
bool wrapT = texprop->clamp & 0x1;
|
||||||
|
bool wrapS = (texprop->clamp >> 1) & 0x1;
|
||||||
|
texture2d->setWrap(osg::Texture::WRAP_S, wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE);
|
||||||
|
texture2d->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP_TO_EDGE);
|
||||||
|
const unsigned int texUnit = 0;
|
||||||
|
const unsigned int uvSet = 0;
|
||||||
|
stateset->setTextureAttributeAndModes(texUnit, texture2d, osg::StateAttribute::ON);
|
||||||
|
boundTextures.push_back(uvSet);
|
||||||
|
}
|
||||||
|
if (mBethVersion >= 27)
|
||||||
|
{
|
||||||
|
stateset->addUniform(new osg::Uniform("useFalloff", true));
|
||||||
|
stateset->addUniform(new osg::Uniform("falloffParams", texprop->falloffParams));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stateset->addUniform(new osg::Uniform("useFalloff", false));
|
||||||
|
}
|
||||||
|
handleTextureControllers(texprop, composite, imageManager, stateset, animflags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
// unused by mw
|
// unused by mw
|
||||||
case Nif::RC_NiShadeProperty:
|
case Nif::RC_NiShadeProperty:
|
||||||
case Nif::RC_NiDitherProperty:
|
case Nif::RC_NiDitherProperty:
|
||||||
|
@ -1809,6 +1945,7 @@ namespace NifOsg
|
||||||
bool hasMatCtrl = false;
|
bool hasMatCtrl = false;
|
||||||
|
|
||||||
int lightmode = 1;
|
int lightmode = 1;
|
||||||
|
float emissiveMult = 1.f;
|
||||||
|
|
||||||
for (const Nif::Property* property : properties)
|
for (const Nif::Property* property : properties)
|
||||||
{
|
{
|
||||||
|
@ -1828,6 +1965,7 @@ namespace NifOsg
|
||||||
mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.diffuse, matprop->data.alpha));
|
mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.diffuse, matprop->data.alpha));
|
||||||
mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.ambient, 1.f));
|
mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.ambient, 1.f));
|
||||||
mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.emissive, 1.f));
|
mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.emissive, 1.f));
|
||||||
|
emissiveMult = matprop->data.emissiveMult;
|
||||||
|
|
||||||
mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.specular, 1.f));
|
mat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(matprop->data.specular, 1.f));
|
||||||
mat->setShininess(osg::Material::FRONT_AND_BACK, matprop->data.glossiness);
|
mat->setShininess(osg::Material::FRONT_AND_BACK, matprop->data.glossiness);
|
||||||
|
@ -1948,6 +2086,7 @@ namespace NifOsg
|
||||||
mat = shareAttribute(mat);
|
mat = shareAttribute(mat);
|
||||||
|
|
||||||
stateset->setAttributeAndModes(mat, osg::StateAttribute::ON);
|
stateset->setAttributeAndModes(mat, osg::StateAttribute::ON);
|
||||||
|
stateset->addUniform(new osg::Uniform("emissiveMult", emissiveMult));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -774,7 +774,7 @@ namespace Resource
|
||||||
|
|
||||||
Shader::ShaderVisitor *SceneManager::createShaderVisitor(const std::string& shaderPrefix, bool translucentFramebuffer)
|
Shader::ShaderVisitor *SceneManager::createShaderVisitor(const std::string& shaderPrefix, bool translucentFramebuffer)
|
||||||
{
|
{
|
||||||
Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, shaderPrefix+"_vertex.glsl", shaderPrefix+"_fragment.glsl");
|
Shader::ShaderVisitor* shaderVisitor = new Shader::ShaderVisitor(*mShaderManager.get(), *mImageManager, shaderPrefix);
|
||||||
shaderVisitor->setForceShaders(mForceShaders);
|
shaderVisitor->setForceShaders(mForceShaders);
|
||||||
shaderVisitor->setAutoUseNormalMaps(mAutoUseNormalMaps);
|
shaderVisitor->setAutoUseNormalMaps(mAutoUseNormalMaps);
|
||||||
shaderVisitor->setNormalMapPattern(mNormalMapPattern);
|
shaderVisitor->setNormalMapPattern(mNormalMapPattern);
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace Shader
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderVisitor::ShaderVisitor(ShaderManager& shaderManager, Resource::ImageManager& imageManager, const std::string &defaultVsTemplate, const std::string &defaultFsTemplate)
|
ShaderVisitor::ShaderVisitor(ShaderManager& shaderManager, Resource::ImageManager& imageManager, const std::string &defaultShaderPrefix)
|
||||||
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
|
||||||
, mForceShaders(false)
|
, mForceShaders(false)
|
||||||
, mAllowedToModifyStateSets(true)
|
, mAllowedToModifyStateSets(true)
|
||||||
|
@ -52,8 +52,7 @@ namespace Shader
|
||||||
, mTranslucentFramebuffer(false)
|
, mTranslucentFramebuffer(false)
|
||||||
, mShaderManager(shaderManager)
|
, mShaderManager(shaderManager)
|
||||||
, mImageManager(imageManager)
|
, mImageManager(imageManager)
|
||||||
, mDefaultVsTemplate(defaultVsTemplate)
|
, mDefaultShaderPrefix(defaultShaderPrefix)
|
||||||
, mDefaultFsTemplate(defaultFsTemplate)
|
|
||||||
{
|
{
|
||||||
mRequirements.emplace_back();
|
mRequirements.emplace_back();
|
||||||
}
|
}
|
||||||
|
@ -129,6 +128,10 @@ namespace Shader
|
||||||
if (mAllowedToModifyStateSets)
|
if (mAllowedToModifyStateSets)
|
||||||
writableStateSet = node.getStateSet();
|
writableStateSet = node.getStateSet();
|
||||||
const osg::StateSet::TextureAttributeList& texAttributes = stateset->getTextureAttributeList();
|
const osg::StateSet::TextureAttributeList& texAttributes = stateset->getTextureAttributeList();
|
||||||
|
bool shaderRequired = false;
|
||||||
|
if (node.getUserValue("shaderRequired", shaderRequired) && shaderRequired)
|
||||||
|
mRequirements.back().mShaderRequired = true;
|
||||||
|
|
||||||
if (!texAttributes.empty())
|
if (!texAttributes.empty())
|
||||||
{
|
{
|
||||||
const osg::Texture* diffuseMap = nullptr;
|
const osg::Texture* diffuseMap = nullptr;
|
||||||
|
@ -440,8 +443,12 @@ namespace Shader
|
||||||
|
|
||||||
defineMap["translucentFramebuffer"] = mTranslucentFramebuffer ? "1" : "0";
|
defineMap["translucentFramebuffer"] = mTranslucentFramebuffer ? "1" : "0";
|
||||||
|
|
||||||
osg::ref_ptr<osg::Shader> vertexShader (mShaderManager.getShader(mDefaultVsTemplate, defineMap, osg::Shader::VERTEX));
|
std::string shaderPrefix;
|
||||||
osg::ref_ptr<osg::Shader> fragmentShader (mShaderManager.getShader(mDefaultFsTemplate, defineMap, osg::Shader::FRAGMENT));
|
if (!node.getUserValue("shaderPrefix", shaderPrefix))
|
||||||
|
shaderPrefix = mDefaultShaderPrefix;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Shader> vertexShader (mShaderManager.getShader(shaderPrefix + "_vertex.glsl", defineMap, osg::Shader::VERTEX));
|
||||||
|
osg::ref_ptr<osg::Shader> fragmentShader (mShaderManager.getShader(shaderPrefix + "_fragment.glsl", defineMap, osg::Shader::FRAGMENT));
|
||||||
|
|
||||||
if (vertexShader && fragmentShader)
|
if (vertexShader && fragmentShader)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Shader
|
||||||
class ShaderVisitor : public osg::NodeVisitor
|
class ShaderVisitor : public osg::NodeVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShaderVisitor(ShaderManager& shaderManager, Resource::ImageManager& imageManager, const std::string& defaultVsTemplate, const std::string& defaultFsTemplate);
|
ShaderVisitor(ShaderManager& shaderManager, Resource::ImageManager& imageManager, const std::string& defaultShaderPrefix);
|
||||||
|
|
||||||
/// By default, only bump mapped objects will have a shader added to them.
|
/// By default, only bump mapped objects will have a shader added to them.
|
||||||
/// Setting force = true will cause all objects to render using shaders, regardless of having a bump map.
|
/// Setting force = true will cause all objects to render using shaders, regardless of having a bump map.
|
||||||
|
@ -104,8 +104,7 @@ namespace Shader
|
||||||
};
|
};
|
||||||
std::vector<ShaderRequirements> mRequirements;
|
std::vector<ShaderRequirements> mRequirements;
|
||||||
|
|
||||||
std::string mDefaultVsTemplate;
|
std::string mDefaultShaderPrefix;
|
||||||
std::string mDefaultFsTemplate;
|
|
||||||
|
|
||||||
void createProgram(const ShaderRequirements& reqs);
|
void createProgram(const ShaderRequirements& reqs);
|
||||||
void ensureFFP(osg::Node& node);
|
void ensureFFP(osg::Node& node);
|
||||||
|
|
|
@ -26,6 +26,10 @@ set(SHADER_FILES
|
||||||
shadowcasting_vertex.glsl
|
shadowcasting_vertex.glsl
|
||||||
shadowcasting_fragment.glsl
|
shadowcasting_fragment.glsl
|
||||||
vertexcolors.glsl
|
vertexcolors.glsl
|
||||||
|
nv_default_vertex.glsl
|
||||||
|
nv_default_fragment.glsl
|
||||||
|
nv_nolighting_vertex.glsl
|
||||||
|
nv_nolighting_fragment.glsl
|
||||||
)
|
)
|
||||||
|
|
||||||
copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_SHADERS_ROOT} ${DDIRRELATIVE} "${SHADER_FILES}")
|
copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_SHADERS_ROOT} ${DDIRRELATIVE} "${SHADER_FILES}")
|
||||||
|
|
106
files/shaders/nv_default_fragment.glsl
Normal file
106
files/shaders/nv_default_fragment.glsl
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
#if @useGPUShader4
|
||||||
|
#extension GL_EXT_gpu_shader4: require
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @diffuseMap
|
||||||
|
uniform sampler2D diffuseMap;
|
||||||
|
varying vec2 diffuseMapUV;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @emissiveMap
|
||||||
|
uniform sampler2D emissiveMap;
|
||||||
|
varying vec2 emissiveMapUV;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @normalMap
|
||||||
|
uniform sampler2D normalMap;
|
||||||
|
varying vec2 normalMapUV;
|
||||||
|
varying vec4 passTangent;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform bool noAlpha;
|
||||||
|
|
||||||
|
varying float euclideanDepth;
|
||||||
|
varying float linearDepth;
|
||||||
|
|
||||||
|
#define PER_PIXEL_LIGHTING 1
|
||||||
|
|
||||||
|
varying vec3 passViewPos;
|
||||||
|
varying vec3 passNormal;
|
||||||
|
|
||||||
|
#include "vertexcolors.glsl"
|
||||||
|
#include "shadows_fragment.glsl"
|
||||||
|
#include "lighting.glsl"
|
||||||
|
#include "alpha.glsl"
|
||||||
|
|
||||||
|
uniform float emissiveMult;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
#if @diffuseMap
|
||||||
|
gl_FragData[0] = texture2D(diffuseMap, diffuseMapUV);
|
||||||
|
gl_FragData[0].a *= coveragePreservingAlphaScale(diffuseMap, adjustedDiffuseUV);
|
||||||
|
#else
|
||||||
|
gl_FragData[0] = vec4(1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 diffuseColor = getDiffuseColor();
|
||||||
|
gl_FragData[0].a *= diffuseColor.a;
|
||||||
|
alphaTest();
|
||||||
|
|
||||||
|
#if @normalMap
|
||||||
|
vec4 normalTex = texture2D(normalMap, normalMapUV);
|
||||||
|
// Must flip Y for DirectX format normal maps
|
||||||
|
normalTex.y = 1.0 - normalTex.y;
|
||||||
|
|
||||||
|
vec3 normalizedNormal = normalize(passNormal);
|
||||||
|
vec3 normalizedTangent = normalize(passTangent.xyz);
|
||||||
|
vec3 binormal = cross(normalizedTangent, normalizedNormal) * passTangent.w;
|
||||||
|
mat3 tbnTranspose = mat3(normalizedTangent, binormal, normalizedNormal);
|
||||||
|
|
||||||
|
vec3 viewNormal = gl_NormalMatrix * normalize(tbnTranspose * (normalTex.xyz * 2.0 - 1.0));
|
||||||
|
#else
|
||||||
|
vec3 viewNormal = gl_NormalMatrix * normalize(passNormal);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float shadowing = unshadowedLightRatio(linearDepth);
|
||||||
|
vec3 diffuseLight, ambientLight;
|
||||||
|
doLighting(passViewPos, normalize(viewNormal), shadowing, diffuseLight, ambientLight);
|
||||||
|
vec3 emission = getEmissionColor().xyz * emissiveMult;
|
||||||
|
#if @emissiveMap
|
||||||
|
emission *= texture2D(emissiveMap, emissiveMapUV).xyz;
|
||||||
|
#endif
|
||||||
|
vec3 lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + emission;
|
||||||
|
|
||||||
|
#if @clamp
|
||||||
|
lighting = clamp(lighting, vec3(0.0), vec3(1.0));
|
||||||
|
#else
|
||||||
|
lighting = max(lighting, 0.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragData[0].xyz *= lighting;
|
||||||
|
|
||||||
|
float shininess = gl_FrontMaterial.shininess;
|
||||||
|
vec3 matSpec = getSpecularColor().xyz;
|
||||||
|
#if @normalMap
|
||||||
|
matSpec *= normalTex.a;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (matSpec != vec3(0.0))
|
||||||
|
gl_FragData[0].xyz += getSpecular(normalize(viewNormal), normalize(passViewPos.xyz), shininess, matSpec) * shadowing;
|
||||||
|
#if @radialFog
|
||||||
|
float fogValue = clamp((euclideanDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
|
||||||
|
#else
|
||||||
|
float fogValue = clamp((linearDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
|
||||||
|
#endif
|
||||||
|
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
|
||||||
|
|
||||||
|
#if @translucentFramebuffer
|
||||||
|
if (noAlpha)
|
||||||
|
gl_FragData[0].a = 1.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
applyShadowDebugOverlay();
|
||||||
|
}
|
58
files/shaders/nv_default_vertex.glsl
Normal file
58
files/shaders/nv_default_vertex.glsl
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
#if @diffuseMap
|
||||||
|
varying vec2 diffuseMapUV;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @emissiveMap
|
||||||
|
varying vec2 emissiveMapUV;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @normalMap
|
||||||
|
varying vec2 normalMapUV;
|
||||||
|
varying vec4 passTangent;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying float euclideanDepth;
|
||||||
|
varying float linearDepth;
|
||||||
|
|
||||||
|
varying vec3 passViewPos;
|
||||||
|
varying vec3 passNormal;
|
||||||
|
|
||||||
|
#define PER_PIXEL_LIGHTING 1
|
||||||
|
|
||||||
|
#include "vertexcolors.glsl"
|
||||||
|
#include "shadows_vertex.glsl"
|
||||||
|
#include "lighting.glsl"
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
|
||||||
|
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
||||||
|
gl_ClipVertex = viewPos;
|
||||||
|
euclideanDepth = length(viewPos.xyz);
|
||||||
|
linearDepth = gl_Position.z;
|
||||||
|
|
||||||
|
#if @diffuseMap
|
||||||
|
diffuseMapUV = (gl_TextureMatrix[@diffuseMapUV] * gl_MultiTexCoord@diffuseMapUV).xy;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @emissiveMap
|
||||||
|
emissiveMapUV = (gl_TextureMatrix[@emissiveMapUV] * gl_MultiTexCoord@emissiveMapUV).xy;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @normalMap
|
||||||
|
normalMapUV = (gl_TextureMatrix[@normalMapUV] * gl_MultiTexCoord@normalMapUV).xy;
|
||||||
|
passTangent = gl_MultiTexCoord7.xyzw;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
passColor = gl_Color;
|
||||||
|
passViewPos = viewPos.xyz;
|
||||||
|
passNormal = gl_Normal.xyz;
|
||||||
|
|
||||||
|
#if @shadows_enabled
|
||||||
|
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);
|
||||||
|
setupShadowCoords(viewPos, viewNormal);
|
||||||
|
#endif
|
||||||
|
}
|
55
files/shaders/nv_nolighting_fragment.glsl
Normal file
55
files/shaders/nv_nolighting_fragment.glsl
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
#if @useGPUShader4
|
||||||
|
#extension GL_EXT_gpu_shader4: require
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @diffuseMap
|
||||||
|
uniform sampler2D diffuseMap;
|
||||||
|
varying vec2 diffuseMapUV;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform bool noAlpha;
|
||||||
|
|
||||||
|
#if @radialFog
|
||||||
|
varying float euclideanDepth;
|
||||||
|
#else
|
||||||
|
varying float linearDepth;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform bool useFalloff;
|
||||||
|
|
||||||
|
varying float passFalloff;
|
||||||
|
|
||||||
|
#include "vertexcolors.glsl"
|
||||||
|
#include "alpha.glsl"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
#if @diffuseMap
|
||||||
|
gl_FragData[0] = texture2D(diffuseMap, diffuseMapUV);
|
||||||
|
gl_FragData[0].a *= coveragePreservingAlphaScale(diffuseMap, diffuseMapUV);
|
||||||
|
#else
|
||||||
|
gl_FragData[0] = vec4(1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragData[0] *= getDiffuseColor();
|
||||||
|
|
||||||
|
if (useFalloff)
|
||||||
|
gl_FragData[0].a *= passFalloff;
|
||||||
|
|
||||||
|
alphaTest();
|
||||||
|
|
||||||
|
#if @radialFog
|
||||||
|
float fogValue = clamp((euclideanDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
|
||||||
|
#else
|
||||||
|
float fogValue = clamp((linearDepth - gl_Fog.start) * gl_Fog.scale, 0.0, 1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @translucentFramebuffer
|
||||||
|
if (noAlpha)
|
||||||
|
gl_FragData[0].a = 1.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, gl_Fog.color.xyz, fogValue);
|
||||||
|
}
|
49
files/shaders/nv_nolighting_vertex.glsl
Normal file
49
files/shaders/nv_nolighting_vertex.glsl
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
#if @diffuseMap
|
||||||
|
varying vec2 diffuseMapUV;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @radialFog
|
||||||
|
varying float euclideanDepth;
|
||||||
|
#else
|
||||||
|
varying float linearDepth;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform bool useFalloff;
|
||||||
|
uniform vec4 falloffParams;
|
||||||
|
|
||||||
|
varying vec3 passViewPos;
|
||||||
|
varying float passFalloff;
|
||||||
|
|
||||||
|
#include "vertexcolors.glsl"
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
|
||||||
|
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
||||||
|
gl_ClipVertex = viewPos;
|
||||||
|
#if @radialFog
|
||||||
|
euclideanDepth = length(viewPos.xyz);
|
||||||
|
#else
|
||||||
|
linearDepth = gl_Position.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @diffuseMap
|
||||||
|
diffuseMapUV = (gl_TextureMatrix[@diffuseMapUV] * gl_MultiTexCoord@diffuseMapUV).xy;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
passColor = gl_Color;
|
||||||
|
if (useFalloff)
|
||||||
|
{
|
||||||
|
vec3 viewNormal = gl_NormalMatrix * normalize(gl_Normal.xyz);
|
||||||
|
vec3 viewDir = normalize(viewPos.xyz);
|
||||||
|
float viewAngle = abs(dot(viewNormal, viewDir));
|
||||||
|
passFalloff = smoothstep(falloffParams.y, falloffParams.x, viewAngle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
passFalloff = 1.0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,6 +64,8 @@ varying float linearDepth;
|
||||||
#if !PER_PIXEL_LIGHTING
|
#if !PER_PIXEL_LIGHTING
|
||||||
centroid varying vec3 passLighting;
|
centroid varying vec3 passLighting;
|
||||||
centroid varying vec3 shadowDiffuseLighting;
|
centroid varying vec3 shadowDiffuseLighting;
|
||||||
|
#else
|
||||||
|
uniform float emissiveMult;
|
||||||
#endif
|
#endif
|
||||||
varying vec3 passViewPos;
|
varying vec3 passViewPos;
|
||||||
varying vec3 passNormal;
|
varying vec3 passNormal;
|
||||||
|
@ -168,7 +170,8 @@ void main()
|
||||||
#else
|
#else
|
||||||
vec3 diffuseLight, ambientLight;
|
vec3 diffuseLight, ambientLight;
|
||||||
doLighting(passViewPos, normalize(viewNormal), shadowing, diffuseLight, ambientLight);
|
doLighting(passViewPos, normalize(viewNormal), shadowing, diffuseLight, ambientLight);
|
||||||
lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + getEmissionColor().xyz;
|
vec3 emission = getEmissionColor().xyz * emissiveMult;
|
||||||
|
lighting = diffuseColor.xyz * diffuseLight + getAmbientColor().xyz * ambientLight + emission;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if @clamp
|
#if @clamp
|
||||||
|
|
|
@ -45,6 +45,7 @@ varying float linearDepth;
|
||||||
#if !PER_PIXEL_LIGHTING
|
#if !PER_PIXEL_LIGHTING
|
||||||
centroid varying vec3 passLighting;
|
centroid varying vec3 passLighting;
|
||||||
centroid varying vec3 shadowDiffuseLighting;
|
centroid varying vec3 shadowDiffuseLighting;
|
||||||
|
uniform float emissiveMult;
|
||||||
#endif
|
#endif
|
||||||
varying vec3 passViewPos;
|
varying vec3 passViewPos;
|
||||||
varying vec3 passNormal;
|
varying vec3 passNormal;
|
||||||
|
@ -114,7 +115,8 @@ void main(void)
|
||||||
#if !PER_PIXEL_LIGHTING
|
#if !PER_PIXEL_LIGHTING
|
||||||
vec3 diffuseLight, ambientLight;
|
vec3 diffuseLight, ambientLight;
|
||||||
doLighting(viewPos.xyz, viewNormal, diffuseLight, ambientLight, shadowDiffuseLighting);
|
doLighting(viewPos.xyz, viewNormal, diffuseLight, ambientLight, shadowDiffuseLighting);
|
||||||
passLighting = getDiffuseColor().xyz * diffuseLight + getAmbientColor().xyz * ambientLight + getEmissionColor().xyz;
|
vec3 emission = getEmissionColor().xyz * emissiveMult;
|
||||||
|
passLighting = getDiffuseColor().xyz * diffuseLight + getAmbientColor().xyz * ambientLight + emission;
|
||||||
shadowDiffuseLighting *= getDiffuseColor().xyz;
|
shadowDiffuseLighting *= getDiffuseColor().xyz;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue