mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:53:51 +00:00
Merge remote-tracking branch 'scrawl/normalmap'
This commit is contained in:
commit
8dd7f0c53a
9 changed files with 262 additions and 31 deletions
|
@ -64,7 +64,7 @@ public:
|
||||||
bool inUse;
|
bool inUse;
|
||||||
NiSourceTexturePtr texture;
|
NiSourceTexturePtr texture;
|
||||||
|
|
||||||
int clamp, set, filter;
|
int clamp, uvSet, filter;
|
||||||
short unknown2;
|
short unknown2;
|
||||||
|
|
||||||
void read(NIFStream *nif)
|
void read(NIFStream *nif)
|
||||||
|
@ -75,7 +75,7 @@ public:
|
||||||
texture.read(nif);
|
texture.read(nif);
|
||||||
clamp = nif->getInt();
|
clamp = nif->getInt();
|
||||||
filter = nif->getInt();
|
filter = nif->getInt();
|
||||||
set = nif->getInt();
|
uvSet = nif->getInt();
|
||||||
|
|
||||||
// I have no idea, but I think these are actually two
|
// I have no idea, but I think these are actually two
|
||||||
// PS2-specific shorts (ps2L and ps2K), followed by an unknown
|
// PS2-specific shorts (ps2L and ps2K), followed by an unknown
|
||||||
|
@ -109,6 +109,17 @@ public:
|
||||||
* 5 - Bump map texture
|
* 5 - Bump map texture
|
||||||
* 6 - Decal texture
|
* 6 - Decal texture
|
||||||
*/
|
*/
|
||||||
|
enum TextureType
|
||||||
|
{
|
||||||
|
BaseTexture = 0,
|
||||||
|
DarkTexture = 1,
|
||||||
|
DetailTexture = 2,
|
||||||
|
GlossTexture = 3,
|
||||||
|
GlowTexture = 4,
|
||||||
|
BumpTexture = 5,
|
||||||
|
DecalTexture = 6
|
||||||
|
};
|
||||||
|
|
||||||
Texture textures[7];
|
Texture textures[7];
|
||||||
|
|
||||||
void read(NIFStream *nif)
|
void read(NIFStream *nif)
|
||||||
|
|
|
@ -555,11 +555,14 @@ static std::string findTextureName(const std::string &filename)
|
||||||
* texture file name references were kept as .tga.
|
* texture file name references were kept as .tga.
|
||||||
*/
|
*/
|
||||||
static const char path[] = "textures\\";
|
static const char path[] = "textures\\";
|
||||||
|
static const char path2[] = "textures/";
|
||||||
|
|
||||||
|
|
||||||
std::string texname = filename;
|
std::string texname = filename;
|
||||||
Misc::StringUtils::toLower(texname);
|
Misc::StringUtils::toLower(texname);
|
||||||
|
|
||||||
if(texname.compare(0, sizeof(path)-1, path) != 0)
|
if(texname.compare(0, sizeof(path)-1, path) != 0
|
||||||
|
&& texname.compare(0, sizeof(path2)-1, path2) != 0)
|
||||||
texname = path + texname;
|
texname = path + texname;
|
||||||
|
|
||||||
Ogre::String::size_type pos = texname.rfind('.');
|
Ogre::String::size_type pos = texname.rfind('.');
|
||||||
|
@ -575,7 +578,8 @@ static std::string findTextureName(const std::string &filename)
|
||||||
{
|
{
|
||||||
texname = filename;
|
texname = filename;
|
||||||
Misc::StringUtils::toLower(texname);
|
Misc::StringUtils::toLower(texname);
|
||||||
if(texname.compare(0, sizeof(path)-1, path) != 0)
|
if(texname.compare(0, sizeof(path)-1, path) != 0
|
||||||
|
&& texname.compare(0, sizeof(path2)-1, path2) != 0)
|
||||||
texname = path + texname;
|
texname = path + texname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -590,7 +594,8 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
|
||||||
const Nif::NiAlphaProperty *alphaprop,
|
const Nif::NiAlphaProperty *alphaprop,
|
||||||
const Nif::NiVertexColorProperty *vertprop,
|
const Nif::NiVertexColorProperty *vertprop,
|
||||||
const Nif::NiZBufferProperty *zprop,
|
const Nif::NiZBufferProperty *zprop,
|
||||||
const Nif::NiSpecularProperty *specprop)
|
const Nif::NiSpecularProperty *specprop,
|
||||||
|
bool &needTangents)
|
||||||
{
|
{
|
||||||
Ogre::MaterialManager &matMgr = Ogre::MaterialManager::getSingleton();
|
Ogre::MaterialManager &matMgr = Ogre::MaterialManager::getSingleton();
|
||||||
Ogre::MaterialPtr material = matMgr.getByName(name);
|
Ogre::MaterialPtr material = matMgr.getByName(name);
|
||||||
|
@ -634,6 +639,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
|
||||||
warn("Found internal texture, ignoring.");
|
warn("Found internal texture, ignoring.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
needTangents = !texName[Nif::NiTexturingProperty::BumpTexture].empty();
|
||||||
|
|
||||||
// Alpha modifiers
|
// Alpha modifiers
|
||||||
if(alphaprop)
|
if(alphaprop)
|
||||||
|
@ -741,7 +747,15 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
|
||||||
new sh::Vector4(specular.x, specular.y, specular.z, glossiness)));
|
new sh::Vector4(specular.x, specular.y, specular.z, glossiness)));
|
||||||
}
|
}
|
||||||
|
|
||||||
instance->setProperty("diffuseMap", sh::makeProperty(texName[0]));
|
instance->setProperty("diffuseMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BaseTexture]));
|
||||||
|
instance->setProperty("normalMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BumpTexture]));
|
||||||
|
instance->setProperty("emissiveMap", sh::makeProperty(texName[Nif::NiTexturingProperty::GlowTexture]));
|
||||||
|
if (!texName[Nif::NiTexturingProperty::GlowTexture].empty())
|
||||||
|
{
|
||||||
|
instance->setProperty("use_emissive_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||||
|
instance->setProperty("emissiveMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::GlowTexture].uvSet)));
|
||||||
|
}
|
||||||
|
|
||||||
for(int i = 1;i < 7;i++)
|
for(int i = 1;i < 7;i++)
|
||||||
{
|
{
|
||||||
if(!texName[i].empty())
|
if(!texName[i].empty())
|
||||||
|
@ -1022,11 +1036,20 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool needTangents=false;
|
||||||
std::string matname = NIFMaterialLoader::getMaterial(shape, mesh->getName(), mGroup,
|
std::string matname = NIFMaterialLoader::getMaterial(shape, mesh->getName(), mGroup,
|
||||||
texprop, matprop, alphaprop,
|
texprop, matprop, alphaprop,
|
||||||
vertprop, zprop, specprop);
|
vertprop, zprop, specprop, needTangents);
|
||||||
if(matname.length() > 0)
|
if(matname.length() > 0)
|
||||||
sub->setMaterialName(matname);
|
sub->setMaterialName(matname);
|
||||||
|
|
||||||
|
// build tangents if the material needs them
|
||||||
|
if (needTangents)
|
||||||
|
{
|
||||||
|
unsigned short src,dest;
|
||||||
|
if (!mesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src,dest))
|
||||||
|
mesh->buildTangentVectors(Ogre::VES_TANGENT, src,dest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findTriShape(Ogre::Mesh *mesh, const Nif::Node *node,
|
bool findTriShape(Ogre::Mesh *mesh, const Nif::Node *node,
|
||||||
|
|
23
extern/shiny/Docs/Macros.dox
vendored
23
extern/shiny/Docs/Macros.dox
vendored
|
@ -107,6 +107,23 @@
|
||||||
|
|
||||||
\section properties Property retrieval / binding
|
\section properties Property retrieval / binding
|
||||||
|
|
||||||
|
\subsection shPropertyHasValue shPropertyHasValue
|
||||||
|
|
||||||
|
<B>Usage:</B> \@shPropertyHasValue(property)
|
||||||
|
|
||||||
|
Gets replaced by 1 if the property's value is not empty, or 0 if it is empty.
|
||||||
|
Useful for checking whether an optional texture is present or not.
|
||||||
|
|
||||||
|
<B>Example:</B>
|
||||||
|
\code
|
||||||
|
#if @shPropertyHasValue(specularMap)
|
||||||
|
// specular mapping code
|
||||||
|
#endif
|
||||||
|
#if @shPropertyHasValue(normalMap)
|
||||||
|
// normal mapping code
|
||||||
|
#endif
|
||||||
|
\endcode
|
||||||
|
|
||||||
\subsection shUniformProperty shUniformProperty
|
\subsection shUniformProperty shUniformProperty
|
||||||
|
|
||||||
<B>Usage:</B> \@shUniformProperty<4f|3f|2f|1f|int> (uniformName, property)
|
<B>Usage:</B> \@shUniformProperty<4f|3f|2f|1f|int> (uniformName, property)
|
||||||
|
@ -130,15 +147,11 @@
|
||||||
|
|
||||||
<B>Example:</B>
|
<B>Example:</B>
|
||||||
\code
|
\code
|
||||||
#if @shPropertyBool(has_normal_map)
|
#if @shPropertyBool(has_vertex_colors)
|
||||||
...
|
...
|
||||||
#endif
|
#endif
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\subsection shPropertyNotBool shPropertyNotBool
|
|
||||||
|
|
||||||
Same as shPropertyBool, but inverts the result (i.e. when shPropertyBool would return 0, this returns 1 and vice versa)
|
|
||||||
|
|
||||||
\subsection shPropertyString shPropertyString
|
\subsection shPropertyString shPropertyString
|
||||||
|
|
||||||
Retrieve a string property of the pass that this shader belongs to
|
Retrieve a string property of the pass that this shader belongs to
|
||||||
|
|
1
extern/shiny/Main/MaterialInstance.hpp
vendored
1
extern/shiny/Main/MaterialInstance.hpp
vendored
|
@ -25,6 +25,7 @@ namespace sh
|
||||||
public:
|
public:
|
||||||
virtual void requestedConfiguration (MaterialInstance* m, const std::string& configuration) = 0; ///< called before creating
|
virtual void requestedConfiguration (MaterialInstance* m, const std::string& configuration) = 0; ///< called before creating
|
||||||
virtual void createdConfiguration (MaterialInstance* m, const std::string& configuration) = 0; ///< called after creating
|
virtual void createdConfiguration (MaterialInstance* m, const std::string& configuration) = 0; ///< called after creating
|
||||||
|
virtual ~MaterialInstanceListener(){}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
15
extern/shiny/Main/ShaderInstance.cpp
vendored
15
extern/shiny/Main/ShaderInstance.cpp
vendored
|
@ -194,13 +194,6 @@ namespace sh
|
||||||
bool val = retrieveValue<BooleanValue>(value, properties->getContext()).get();
|
bool val = retrieveValue<BooleanValue>(value, properties->getContext()).get();
|
||||||
replaceValue = val ? "1" : "0";
|
replaceValue = val ? "1" : "0";
|
||||||
}
|
}
|
||||||
else if (cmd == "shPropertyNotBool") // same as above, but inverts the result
|
|
||||||
{
|
|
||||||
std::string propertyName = args[0];
|
|
||||||
PropertyValuePtr value = properties->getProperty(propertyName);
|
|
||||||
bool val = retrieveValue<BooleanValue>(value, properties->getContext()).get();
|
|
||||||
replaceValue = val ? "0" : "1";
|
|
||||||
}
|
|
||||||
else if (cmd == "shPropertyString")
|
else if (cmd == "shPropertyString")
|
||||||
{
|
{
|
||||||
std::string propertyName = args[0];
|
std::string propertyName = args[0];
|
||||||
|
@ -214,6 +207,14 @@ namespace sh
|
||||||
std::string value = retrieveValue<StringValue>(properties->getProperty(propertyName), properties->getContext()).get();
|
std::string value = retrieveValue<StringValue>(properties->getProperty(propertyName), properties->getContext()).get();
|
||||||
replaceValue = (value == comparedAgainst) ? "1" : "0";
|
replaceValue = (value == comparedAgainst) ? "1" : "0";
|
||||||
}
|
}
|
||||||
|
else if (isCmd(source, pos, "@shPropertyHasValue"))
|
||||||
|
{
|
||||||
|
assert(args.size() == 1);
|
||||||
|
std::string propertyName = args[0];
|
||||||
|
PropertyValuePtr value = properties->getProperty(propertyName);
|
||||||
|
std::string val = retrieveValue<StringValue>(value, properties->getContext()).get();
|
||||||
|
replaceValue = (val.empty() ? "0" : "1");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
throw std::runtime_error ("unknown command \"" + cmd + "\"");
|
throw std::runtime_error ("unknown command \"" + cmd + "\"");
|
||||||
source.replace(pos, (end+1)-pos, replaceValue);
|
source.replace(pos, (end+1)-pos, replaceValue);
|
||||||
|
|
16
extern/shiny/Main/ShaderSet.cpp
vendored
16
extern/shiny/Main/ShaderSet.cpp
vendored
|
@ -6,6 +6,7 @@
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include "Factory.hpp"
|
#include "Factory.hpp"
|
||||||
|
|
||||||
|
@ -26,6 +27,10 @@ namespace sh
|
||||||
std::ifstream stream(sourceFile.c_str(), std::ifstream::in);
|
std::ifstream stream(sourceFile.c_str(), std::ifstream::in);
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
|
|
||||||
|
boost::filesystem::path p (sourceFile);
|
||||||
|
p = p.branch_path();
|
||||||
|
mBasePath = p.string();
|
||||||
|
|
||||||
buffer << stream.rdbuf();
|
buffer << stream.rdbuf();
|
||||||
stream.close();
|
stream.close();
|
||||||
mSource = buffer.str();
|
mSource = buffer.str();
|
||||||
|
@ -52,6 +57,12 @@ namespace sh
|
||||||
size_t start = currentToken.find('(')+1;
|
size_t start = currentToken.find('(')+1;
|
||||||
mGlobalSettings.push_back(currentToken.substr(start, currentToken.find(')')-start));
|
mGlobalSettings.push_back(currentToken.substr(start, currentToken.find(')')-start));
|
||||||
}
|
}
|
||||||
|
else if (boost::starts_with(currentToken, "@shPropertyHasValue"))
|
||||||
|
{
|
||||||
|
assert ((currentToken.find('(') != std::string::npos) && (currentToken.find(')') != std::string::npos));
|
||||||
|
size_t start = currentToken.find('(')+1;
|
||||||
|
mPropertiesToExist.push_back(currentToken.substr(start, currentToken.find(')')-start));
|
||||||
|
}
|
||||||
else if (boost::starts_with(currentToken, "@shPropertyEqual"))
|
else if (boost::starts_with(currentToken, "@shPropertyEqual"))
|
||||||
{
|
{
|
||||||
assert ((currentToken.find('(') != std::string::npos) && (currentToken.find(')') != std::string::npos)
|
assert ((currentToken.find('(') != std::string::npos) && (currentToken.find(')') != std::string::npos)
|
||||||
|
@ -135,6 +146,11 @@ namespace sh
|
||||||
{
|
{
|
||||||
boost::hash_combine(seed, retrieveValue<StringValue>(currentGlobalSettings->getProperty(*it), NULL).get());
|
boost::hash_combine(seed, retrieveValue<StringValue>(currentGlobalSettings->getProperty(*it), NULL).get());
|
||||||
}
|
}
|
||||||
|
for (std::vector<std::string>::iterator it = mPropertiesToExist.begin(); it != mPropertiesToExist.end(); ++it)
|
||||||
|
{
|
||||||
|
std::string v = retrieveValue<StringValue>(properties->getProperty(*it), properties->getContext()).get();
|
||||||
|
boost::hash_combine(seed, static_cast<bool>(v != ""));
|
||||||
|
}
|
||||||
boost::hash_combine(seed, static_cast<int>(Factory::getInstance().getCurrentLanguage()));
|
boost::hash_combine(seed, static_cast<int>(Factory::getInstance().getCurrentLanguage()));
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
4
extern/shiny/Main/ShaderSet.hpp
vendored
4
extern/shiny/Main/ShaderSet.hpp
vendored
|
@ -53,6 +53,10 @@ namespace sh
|
||||||
std::vector <std::string> mGlobalSettings; ///< names of the global settings that affect the shader source
|
std::vector <std::string> mGlobalSettings; ///< names of the global settings that affect the shader source
|
||||||
std::vector <std::string> mProperties; ///< names of the per-material properties that affect the shader source
|
std::vector <std::string> mProperties; ///< names of the per-material properties that affect the shader source
|
||||||
|
|
||||||
|
std::vector <std::string> mPropertiesToExist;
|
||||||
|
///< same as mProperties, however in this case, it is only relevant if the property is empty or not
|
||||||
|
/// (we don't care about the value)
|
||||||
|
|
||||||
ShaderInstanceMap mInstances; ///< maps permutation ID (generated from the properties) to \a ShaderInstance
|
ShaderInstanceMap mInstances; ///< maps permutation ID (generated from the properties) to \a ShaderInstance
|
||||||
|
|
||||||
void parse(); ///< find out which properties and global settings affect the shader source
|
void parse(); ///< find out which properties and global settings affect the shader source
|
||||||
|
|
|
@ -6,6 +6,10 @@ material openmw_objects_base
|
||||||
emissive 0.0 0.0 0.0
|
emissive 0.0 0.0 0.0
|
||||||
vertmode 0
|
vertmode 0
|
||||||
diffuseMap black.png
|
diffuseMap black.png
|
||||||
|
normalMap
|
||||||
|
emissiveMap
|
||||||
|
use_emissive_map false
|
||||||
|
emissiveMapUVSet 0
|
||||||
|
|
||||||
is_transparent false // real transparency, alpha rejection doesn't count here
|
is_transparent false // real transparency, alpha rejection doesn't count here
|
||||||
scene_blend default
|
scene_blend default
|
||||||
|
@ -22,6 +26,9 @@ material openmw_objects_base
|
||||||
{
|
{
|
||||||
vertexcolor_mode $vertmode
|
vertexcolor_mode $vertmode
|
||||||
is_transparent $is_transparent
|
is_transparent $is_transparent
|
||||||
|
normalMap $normalMap
|
||||||
|
emissiveMapUVSet $emissiveMapUVSet
|
||||||
|
emissiveMap $emissiveMap
|
||||||
}
|
}
|
||||||
|
|
||||||
diffuse $diffuse
|
diffuse $diffuse
|
||||||
|
@ -37,6 +44,20 @@ material openmw_objects_base
|
||||||
{
|
{
|
||||||
direct_texture $diffuseMap
|
direct_texture $diffuseMap
|
||||||
create_in_ffp true
|
create_in_ffp true
|
||||||
|
tex_coord_set $emissiveMapUVSet
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit normalMap
|
||||||
|
{
|
||||||
|
direct_texture $normalMap
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit emissiveMap
|
||||||
|
{
|
||||||
|
create_in_ffp $use_emissive_map
|
||||||
|
colour_op add
|
||||||
|
direct_texture $emissiveMap
|
||||||
|
tex_coord_set $emissiveMapUVSet
|
||||||
}
|
}
|
||||||
|
|
||||||
texture_unit shadowMap0
|
texture_unit shadowMap0
|
||||||
|
|
|
@ -14,13 +14,19 @@
|
||||||
#define NEED_DEPTH
|
#define NEED_DEPTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define NORMAL_MAP @shPropertyHasValue(normalMap)
|
||||||
|
#define EMISSIVE_MAP @shPropertyHasValue(emissiveMap)
|
||||||
|
|
||||||
|
// right now we support 2 UV sets max. implementing them is tedious, and we're probably not going to need more
|
||||||
|
#define SECOND_UV_SET @shPropertyString(emissiveMapUVSet)
|
||||||
|
|
||||||
|
// if normal mapping is enabled, we force pixel lighting
|
||||||
|
#define VERTEX_LIGHTING (!@shPropertyHasValue(normalMap))
|
||||||
|
|
||||||
#define UNDERWATER @shGlobalSettingBool(render_refraction)
|
#define UNDERWATER @shGlobalSettingBool(render_refraction)
|
||||||
|
|
||||||
#define VERTEXCOLOR_MODE @shPropertyString(vertexcolor_mode)
|
#define VERTEXCOLOR_MODE @shPropertyString(vertexcolor_mode)
|
||||||
|
|
||||||
#define VERTEX_LIGHTING 1
|
|
||||||
|
|
||||||
#define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix)
|
#define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix)
|
||||||
|
|
||||||
#ifdef SH_VERTEX_SHADER
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
@ -40,8 +46,22 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
shVertexInput(float2, uv0)
|
shVertexInput(float2, uv0)
|
||||||
shOutput(float2, UV)
|
#if SECOND_UV_SET
|
||||||
|
shVertexInput(float2, uv1)
|
||||||
|
#endif
|
||||||
|
shOutput(float4, UV)
|
||||||
|
|
||||||
shNormalInput(float4)
|
shNormalInput(float4)
|
||||||
|
|
||||||
|
#if NORMAL_MAP
|
||||||
|
shTangentInput(float4)
|
||||||
|
shOutput(float3, tangentPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !VERTEX_LIGHTING
|
||||||
|
shOutput(float3, normalPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NEED_DEPTH
|
#ifdef NEED_DEPTH
|
||||||
shOutput(float, depthPassthrough)
|
shOutput(float, depthPassthrough)
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,6 +72,10 @@
|
||||||
shColourInput(float4)
|
shColourInput(float4)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if VERTEXCOLOR_MODE != 0 && !VERTEX_LIGHTING
|
||||||
|
shOutput(float4, colourPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if VERTEX_LIGHTING
|
#if VERTEX_LIGHTING
|
||||||
shUniform(float, lightCount) @shAutoConstant(lightCount, light_count)
|
shUniform(float, lightCount) @shAutoConstant(lightCount, light_count)
|
||||||
shUniform(float4, lightPosition[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightPosition, light_position_view_space_array, @shGlobalSettingString(num_lights))
|
shUniform(float4, lightPosition[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightPosition, light_position_view_space_array, @shGlobalSettingString(num_lights))
|
||||||
|
@ -93,7 +117,21 @@
|
||||||
SH_START_PROGRAM
|
SH_START_PROGRAM
|
||||||
{
|
{
|
||||||
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
UV = uv0;
|
|
||||||
|
UV.xy = uv0;
|
||||||
|
#if SECOND_UV_SET
|
||||||
|
UV.zw = uv1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NORMAL_MAP
|
||||||
|
tangentPassthrough = tangent.xyz;
|
||||||
|
#endif
|
||||||
|
#if !VERTEX_LIGHTING
|
||||||
|
normalPassthrough = normal.xyz;
|
||||||
|
#endif
|
||||||
|
#if VERTEXCOLOR_MODE != 0 && !VERTEX_LIGHTING
|
||||||
|
colourPassthrough = colour;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NEED_DEPTH
|
#ifdef NEED_DEPTH
|
||||||
|
|
||||||
|
@ -189,7 +227,23 @@
|
||||||
|
|
||||||
SH_BEGIN_PROGRAM
|
SH_BEGIN_PROGRAM
|
||||||
shSampler2D(diffuseMap)
|
shSampler2D(diffuseMap)
|
||||||
shInput(float2, UV)
|
|
||||||
|
#if NORMAL_MAP
|
||||||
|
shSampler2D(normalMap)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if EMISSIVE_MAP
|
||||||
|
shSampler2D(emissiveMap)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shInput(float4, UV)
|
||||||
|
|
||||||
|
#if NORMAL_MAP
|
||||||
|
shInput(float3, tangentPassthrough)
|
||||||
|
#endif
|
||||||
|
#if !VERTEX_LIGHTING
|
||||||
|
shInput(float3, normalPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NEED_DEPTH
|
#ifdef NEED_DEPTH
|
||||||
shInput(float, depthPassthrough)
|
shInput(float, depthPassthrough)
|
||||||
|
@ -197,6 +251,10 @@
|
||||||
|
|
||||||
shInput(float3, objSpacePositionPassthrough)
|
shInput(float3, objSpacePositionPassthrough)
|
||||||
|
|
||||||
|
#if VERTEXCOLOR_MODE != 0 && !VERTEX_LIGHTING
|
||||||
|
shInput(float4, colourPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if FOG
|
#if FOG
|
||||||
shUniform(float3, fogColour) @shAutoConstant(fogColour, fog_colour)
|
shUniform(float3, fogColour) @shAutoConstant(fogColour, fog_colour)
|
||||||
shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params)
|
shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params)
|
||||||
|
@ -233,11 +291,86 @@
|
||||||
#if VERTEX_LIGHTING
|
#if VERTEX_LIGHTING
|
||||||
shInput(float4, lightResult)
|
shInput(float4, lightResult)
|
||||||
shInput(float3, directionalResult)
|
shInput(float3, directionalResult)
|
||||||
|
#else
|
||||||
|
shUniform(float, lightCount) @shAutoConstant(lightCount, light_count)
|
||||||
|
shUniform(float4, lightPosition[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightPosition, light_position_view_space_array, @shGlobalSettingString(num_lights))
|
||||||
|
shUniform(float4, lightDiffuse[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightDiffuse, light_diffuse_colour_array, @shGlobalSettingString(num_lights))
|
||||||
|
shUniform(float4, lightAttenuation[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightAttenuation, light_attenuation_array, @shGlobalSettingString(num_lights))
|
||||||
|
shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour)
|
||||||
|
shUniform(float4x4, worldView) @shAutoConstant(worldView, worldview_matrix)
|
||||||
|
#if VERTEXCOLOR_MODE != 2
|
||||||
|
shUniform(float4, materialAmbient) @shAutoConstant(materialAmbient, surface_ambient_colour)
|
||||||
|
#endif
|
||||||
|
#if VERTEXCOLOR_MODE != 2
|
||||||
|
shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour)
|
||||||
|
#endif
|
||||||
|
#if VERTEXCOLOR_MODE != 1
|
||||||
|
shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour)
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SH_START_PROGRAM
|
SH_START_PROGRAM
|
||||||
{
|
{
|
||||||
shOutputColour(0) = shSample(diffuseMap, UV);
|
shOutputColour(0) = shSample(diffuseMap, UV.xy);
|
||||||
|
|
||||||
|
#if NORMAL_MAP
|
||||||
|
float3 normal = normalPassthrough;
|
||||||
|
float3 binormal = cross(tangentPassthrough.xyz, normal.xyz);
|
||||||
|
float3x3 tbn = float3x3(tangentPassthrough.xyz, binormal, normal.xyz);
|
||||||
|
|
||||||
|
#if SH_GLSL
|
||||||
|
tbn = transpose(tbn);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float3 TSnormal = shSample(normalMap, UV.xy).xyz * 2 - 1;
|
||||||
|
|
||||||
|
normal = normalize (shMatrixMult( transpose(tbn), TSnormal ));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !VERTEX_LIGHTING
|
||||||
|
float3 viewPos = shMatrixMult(worldView, float4(objSpacePositionPassthrough,1)).xyz;
|
||||||
|
float3 viewNormal = normalize(shMatrixMult(worldView, float4(normal.xyz, 0)).xyz);
|
||||||
|
|
||||||
|
float3 lightDir;
|
||||||
|
float d;
|
||||||
|
float4 lightResult = float4(0,0,0,1);
|
||||||
|
@shForeach(@shGlobalSettingString(num_lights))
|
||||||
|
lightDir = lightPosition[@shIterator].xyz - (viewPos * lightPosition[@shIterator].w);
|
||||||
|
d = length(lightDir);
|
||||||
|
lightDir = normalize(lightDir);
|
||||||
|
|
||||||
|
#if VERTEXCOLOR_MODE == 2
|
||||||
|
lightResult.xyz += colourPassthrough.xyz * lightDiffuse[@shIterator].xyz
|
||||||
|
* shSaturate(1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d)))
|
||||||
|
* max(dot(viewNormal.xyz, lightDir), 0);
|
||||||
|
#else
|
||||||
|
lightResult.xyz += materialDiffuse.xyz * lightDiffuse[@shIterator].xyz
|
||||||
|
* shSaturate(1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d)))
|
||||||
|
* max(dot(viewNormal.xyz, lightDir), 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @shIterator == 0
|
||||||
|
float3 directionalResult = lightResult.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@shEndForeach
|
||||||
|
|
||||||
|
|
||||||
|
#if VERTEXCOLOR_MODE == 2
|
||||||
|
lightResult.xyz += lightAmbient.xyz * colourPassthrough.xyz + materialEmissive.xyz;
|
||||||
|
lightResult.a *= colourPassthrough.a;
|
||||||
|
#endif
|
||||||
|
#if VERTEXCOLOR_MODE == 1
|
||||||
|
lightResult.xyz += lightAmbient.xyz * materialAmbient.xyz + colourPassthrough.xyz;
|
||||||
|
#endif
|
||||||
|
#if VERTEXCOLOR_MODE == 0
|
||||||
|
lightResult.xyz += lightAmbient.xyz * materialAmbient.xyz + materialEmissive.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if VERTEXCOLOR_MODE != 2
|
||||||
|
lightResult.a *= materialDiffuse.a;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// shadows only for the first (directional) light
|
// shadows only for the first (directional) light
|
||||||
#if SHADOWS
|
#if SHADOWS
|
||||||
|
@ -283,6 +416,14 @@
|
||||||
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue);
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if EMISSIVE_MAP
|
||||||
|
#if SECOND_UV_SET
|
||||||
|
shOutputColour(0).xyz += shSample(emissiveMap, UV.zw).xyz;
|
||||||
|
#else
|
||||||
|
shOutputColour(0).xyz += shSample(emissiveMap, UV.xy).xyz;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// prevent negative colour output (for example with negative lights)
|
// prevent negative colour output (for example with negative lights)
|
||||||
|
|
Loading…
Reference in a new issue