diff --git a/components/nif/property.cpp b/components/nif/property.cpp index de30e7da9c..71db7458db 100644 --- a/components/nif/property.cpp +++ b/components/nif/property.cpp @@ -46,12 +46,10 @@ void NiTexturingProperty::read(NIFStream *nif) for (unsigned int i = 0; i < numTextures; i++) { textures[i].read(nif); - // Ignore these at the moment if (i == 5 && textures[5].inUse) // Bump map settings { - /*float lumaScale =*/ nif->getFloat(); - /*float lumaOffset =*/ nif->getFloat(); - /*const Vector4 *lumaMatrix =*/ nif->getVector4(); + envMapLumaBias = nif->getVector2(); + bumpMapMatrix = nif->getVector4(); } } } diff --git a/components/nif/property.hpp b/components/nif/property.hpp index a3f399b83b..c72dbf6ba1 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -93,6 +93,9 @@ public: std::vector textures; + osg::Vec2f envMapLumaBias; + osg::Vec4f bumpMapMatrix; + void read(NIFStream *nif); void post(NIFFile *nif); }; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index b70391a588..644e824842 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1536,6 +1536,10 @@ namespace NifOsg { // Set this texture to Off by default since we can't render it with the fixed-function pipeline stateset->setTextureMode(texUnit, GL_TEXTURE_2D, osg::StateAttribute::OFF); + osg::Matrix2 bumpMapMatrix(texprop->bumpMapMatrix.x(), texprop->bumpMapMatrix.y(), + texprop->bumpMapMatrix.z(), texprop->bumpMapMatrix.w()); + stateset->addUniform(new osg::Uniform("bumpMapMatrix", bumpMapMatrix)); + stateset->addUniform(new osg::Uniform("envMapLumaBias", texprop->envMapLumaBias)); } else if (i == Nif::NiTexturingProperty::DecalTexture) { @@ -1559,7 +1563,7 @@ namespace NifOsg texture2d->setName("diffuseMap"); break; case Nif::NiTexturingProperty::BumpTexture: - texture2d->setName("normalMap"); + texture2d->setName("bumpMap"); break; case Nif::NiTexturingProperty::GlowTexture: texture2d->setName("emissiveMap"); diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index ae2da09476..31338da8b1 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -75,7 +75,7 @@ namespace Shader return newStateSet.get(); } - const char* defaultTextures[] = { "diffuseMap", "normalMap", "emissiveMap", "darkMap", "detailMap", "envMap", "specularMap", "decalMap" }; + const char* defaultTextures[] = { "diffuseMap", "normalMap", "emissiveMap", "darkMap", "detailMap", "envMap", "specularMap", "decalMap", "bumpMap" }; bool isTextureNameRecognized(const std::string& name) { for (unsigned int i=0; isetTextureMode(unit, GL_TEXTURE_2D, osg::StateAttribute::ON); + } } else Log(Debug::Error) << "ShaderVisitor encountered unknown texture " << texture; diff --git a/files/shaders/objects_fragment.glsl b/files/shaders/objects_fragment.glsl index eb605d4215..f6f3bc792a 100644 --- a/files/shaders/objects_fragment.glsl +++ b/files/shaders/objects_fragment.glsl @@ -42,6 +42,13 @@ uniform sampler2D specularMap; varying vec2 specularMapUV; #endif +#if @bumpMap +uniform sampler2D bumpMap; +varying vec2 bumpMapUV; +uniform vec2 envMapLumaBias; +uniform mat2 bumpMapMatrix; +#endif + varying float depth; #define PER_PIXEL_LIGHTING (@normalMap || @forcePPL) @@ -132,20 +139,24 @@ void main() gl_FragData[0].xyz += texture2D(emissiveMap, emissiveMapUV).xyz; #endif - #if @envMap + vec2 texCoordGen = envMapUV; + float envLuma = 1.0; #if @normalMap // if using normal map + env map, take advantage of per-pixel normals for texCoordGen vec3 viewVec = normalize(passViewPos.xyz); vec3 r = reflect( viewVec, viewNormal ); float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) ); - vec2 texCoordGen = vec2(r.x/m + 0.5, r.y/m + 0.5); - gl_FragData[0].xyz += texture2D(envMap, texCoordGen).xyz * envMapColor.xyz; -#else - gl_FragData[0].xyz += texture2D(envMap, envMapUV).xyz * envMapColor.xyz; + texCoordGen = vec2(r.x/m + 0.5, r.y/m + 0.5); #endif +#if @bumpMap + vec4 bumpTex = texture2D(bumpMap, bumpMapUV); + texCoordGen += bumpTex.rg * bumpMapMatrix; + envLuma = clamp(bumpTex.b * envMapLumaBias.x + envMapLumaBias.y, 0.0, 1.0); +#endif + gl_FragData[0].xyz += texture2D(envMap, texCoordGen).xyz * envMapColor.xyz * envLuma; #endif #if @specularMap diff --git a/files/shaders/objects_vertex.glsl b/files/shaders/objects_vertex.glsl index dcb2412745..ec5449b873 100644 --- a/files/shaders/objects_vertex.glsl +++ b/files/shaders/objects_vertex.glsl @@ -29,6 +29,10 @@ varying vec4 passTangent; varying vec2 envMapUV; #endif +#if @bumpMap +varying vec2 bumpMapUV; +#endif + #if @specularMap varying vec2 specularMapUV; #endif @@ -91,6 +95,10 @@ void main(void) passTangent = gl_MultiTexCoord7.xyzw; #endif +#if @bumpMap + bumpMapUV = (gl_TextureMatrix[@bumpMapUV] * gl_MultiTexCoord@bumpMapUV).xy; +#endif + #if @specularMap specularMapUV = (gl_TextureMatrix[@specularMapUV] * gl_MultiTexCoord@specularMapUV).xy; #endif