From 00782b0e76a598f338447011fc1e8feadcf9d057 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 22 Feb 2016 18:19:36 -0800 Subject: [PATCH] GOing home, this is in the middle of adding the Roughness texture and potentially cleaning up the different compinations of shaders regarding the material textures --- libraries/gpu/src/gpu/Format.cpp | 2 +- libraries/gpu/src/gpu/Format.h | 2 +- libraries/gpu/src/gpu/Texture.h | 54 +++++++++++++++++++ .../src/model-networking/ModelCache.cpp | 10 +++- .../src/model-networking/ModelCache.h | 7 +++ .../src/model-networking/TextureCache.cpp | 6 +-- .../src/model-networking/TextureCache.h | 10 ++-- libraries/model/src/model/Material.cpp | 6 +++ libraries/model/src/model/Material.h | 4 +- libraries/model/src/model/Material.slh | 1 + libraries/model/src/model/TextureMap.cpp | 31 ++++++++++- libraries/render-utils/src/model.slf | 7 +-- libraries/render-utils/src/model_lightmap.slf | 5 +- .../src/model_lightmap_normal_map.slf | 13 +++-- .../model_lightmap_normal_specular_map.slf | 16 +++--- .../src/model_lightmap_specular_map.slf | 6 ++- .../render-utils/src/model_normal_map.slf | 5 +- .../src/model_normal_specular_map.slf | 4 +- .../render-utils/src/model_specular_map.slf | 4 +- 19 files changed, 155 insertions(+), 38 deletions(-) diff --git a/libraries/gpu/src/gpu/Format.cpp b/libraries/gpu/src/gpu/Format.cpp index a66fc19458..7c603919fd 100644 --- a/libraries/gpu/src/gpu/Format.cpp +++ b/libraries/gpu/src/gpu/Format.cpp @@ -11,7 +11,7 @@ using namespace gpu; const Element Element::COLOR_RGBA_32{ VEC4, NUINT8, RGBA }; -const Element Element::COLOR_RGBA{ VEC4, FLOAT, RGBA }; +const Element Element::VEC4F_COLOR_RGBA{ VEC4, FLOAT, RGBA }; const Element Element::VEC2F_UV{ VEC2, FLOAT, UV }; const Element Element::VEC2F_XY{ VEC2, FLOAT, XY }; const Element Element::VEC3F_XYZ{ VEC3, FLOAT, XYZ }; diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 54d40c3e12..625ca6cec3 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -247,7 +247,7 @@ public: } static const Element COLOR_RGBA_32; - static const Element COLOR_RGBA; + static const Element VEC4F_COLOR_RGBA; static const Element VEC2F_UV; static const Element VEC2F_XY; static const Element VEC3F_XYZ; diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 378f49c2f4..e05dc84c25 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -14,6 +14,7 @@ #include "Resource.h" #include //min max and more +#include #include @@ -139,6 +140,53 @@ protected: class Texture : public Resource { public: + class Usage { + public: + enum FlagBit { + COLOR = 0, // Texture is a color map + NORMAL, // Texture is a normal map + ALPHA, // Texture has an alpha channel + ALPHA_MASK, // Texture alpha channel is a Mask 0/1 + + NUM_FLAGS, + }; + typedef std::bitset Flags; + + // The key is the Flags + Flags _flags; + + Usage() : _flags(0) {} + Usage(const Flags& flags) : _flags(flags) {} + + bool operator== (const Usage& rhs) const { return _flags == rhs._flags; } + bool operator!= (const Usage& rhs) const { return _flags != rhs._flags; } + + class Builder { + friend class Usage; + Flags _flags{ 0 }; + public: + Builder() {} + + Usage build() const { return Usage(_flags); } + + Builder& withColor() { _flags.set(COLOR); return (*this); } + Builder& withNormal() { _flags.set(NORMAL); return (*this); } + Builder& withAlpha() { _flags.set(ALPHA); return (*this); } + Builder& withAlphaMask() { _flags.set(ALPHA_MASK); return (*this); } + }; + Usage(const Builder& builder) : Usage(builder._flags) {} + + bool isColor() const { return _flags[COLOR]; } + bool isNormal() const { return _flags[NORMAL]; } + + bool isAlpha() const { return _flags[ALPHA]; } + bool isAlphaMask() const { return _flags[ALPHA_MASK]; } + + + bool operator==(const Usage& usage) { return (_flags == usage._flags); } + bool operator!=(const Usage& usage) { return (_flags != usage._flags); } + }; + class Pixels { public: Pixels() {} @@ -343,6 +391,10 @@ public: bool isDefined() const { return _defined; } + // Usage is a a set of flags providing Semantic about the usage of the Texture. + void setUsage(const Usage& usage) { _usage = usage; } + Usage getUsage() const { return _usage; } + // For Cube Texture, it's possible to generate the irradiance spherical harmonics and make them availalbe with the texture bool generateIrradiance(); const SHPointer& getIrradiance(uint16 slice = 0) const { return _irradiance; } @@ -380,6 +432,8 @@ protected: Type _type = TEX_1D; + Usage _usage; + SHPointer _irradiance; bool _autoGenerateMips = false; bool _isIrradianceValid = false; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 63cc113f5a..2bb71ba855 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -316,7 +316,7 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas return networkMesh; } -static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl) { +static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FBXMaterial& material, const QUrl& textureBaseUrl) { auto textureCache = DependencyManager::get(); NetworkMaterial* networkMaterial = new NetworkMaterial(); @@ -324,6 +324,9 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const if (!material.albedoTexture.filename.isEmpty()) { networkMaterial->albedoTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.albedoTexture.filename)), DEFAULT_TEXTURE, material.albedoTexture.content); + QObject::connect(networkMaterial->albedoTexture.data(), &NetworkTexture::networkTextureCreated, + geometry, &NetworkGeometry::textureLoaded); + networkMaterial->albedoTextureName = material.albedoTexture.name; auto albedoMap = model::TextureMapPointer(new model::TextureMap()); @@ -407,7 +410,7 @@ void NetworkGeometry::modelParseSuccess(FBXGeometry* geometry) { QHash fbxMatIDToMatID; foreach(const FBXMaterial& material, _geometry->materials) { fbxMatIDToMatID[material.materialID] = _materials.size(); - _materials.emplace_back(buildNetworkMaterial(material, _textureBaseUrl)); + _materials.emplace_back(buildNetworkMaterial(this, material, _textureBaseUrl)); } @@ -453,3 +456,6 @@ const NetworkMaterial* NetworkGeometry::getShapeMaterial(int shapeID) { } } +void NetworkGeometry::textureLoaded(const QWeakPointer& networkTexture) { + numTextureLoaded++; +} diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 1d43424813..c43a1e6d79 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -105,6 +105,9 @@ signals: // Fired when something went wrong. void onFailure(NetworkGeometry& networkGeometry, Error error); +public slots: + void textureLoaded(const QWeakPointer& networkTexture); + protected slots: void mappingRequestDone(const QByteArray& data); void mappingRequestError(QNetworkReply::NetworkError error); @@ -115,6 +118,7 @@ protected slots: void modelParseSuccess(FBXGeometry* geometry); void modelParseError(int error, QString str); + protected: void attemptRequestInternal(); void requestMapping(const QUrl& url); @@ -133,6 +137,7 @@ protected: QUrl _modelUrl; QVariantHash _mapping; QUrl _textureBaseUrl; + int numTextureLoaded = 0; Resource* _resource = nullptr; std::unique_ptr _geometry; // This should go away evenutally once we can put everything we need in the model::AssetPointer @@ -173,6 +178,7 @@ public: class NetworkMaterial { public: + model::MaterialPointer _material; QString albedoTextureName; QSharedPointer albedoTexture; @@ -186,6 +192,7 @@ public: QSharedPointer emissiveTexture; QString lightmapTextureName; QSharedPointer lightmapTexture; + }; diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 2ec9ab4027..c10b82d235 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -339,10 +339,6 @@ void NetworkTexture::setImage(const QImage& image, void* voidTexture, int origin finishedLoading(true); - imageLoaded(image); -} - -void NetworkTexture::imageLoaded(const QImage& image) { - // nothing by default + emit networkTextureCreated(qWeakPointerCast (_self)); } diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index 1a0d22a8d3..2cfd225889 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -83,8 +83,6 @@ private: gpu::TexturePointer _blueTexture; gpu::TexturePointer _blackTexture; gpu::TexturePointer _normalFittingTexture; - - QHash > _dilatableNetworkTextures; }; /// A simple object wrapper for an OpenGL texture. @@ -114,7 +112,11 @@ public: int getHeight() const { return _height; } TextureLoaderFunc getTextureLoader() const; - + +signals: + void networkTextureCreated(const QWeakPointer& self); + + protected: virtual void downloadFinished(const QByteArray& data) override; @@ -123,8 +125,6 @@ protected: // FIXME: This void* should be a gpu::Texture* but i cannot get it to work for now, moving on... Q_INVOKABLE void setImage(const QImage& image, void* texture, int originalWidth, int originalHeight); - virtual void imageLoaded(const QImage& image); - private: TextureType _type; diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index 770b110ad9..522debad59 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -46,11 +46,13 @@ Material::~Material() { void Material::setEmissive(const Color& emissive, bool isSRGB) { _key.setEmissive(glm::any(glm::greaterThan(emissive, Color(0.0f)))); + _schemaBuffer.edit()._key = (uint32) _key._flags.to_ulong(); _schemaBuffer.edit()._emissive = (isSRGB ? ColorUtils::toLinearVec3(emissive) : emissive); } void Material::setOpacity(float opacity) { _key.setTransparent((opacity < 1.0f)); + _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); _schemaBuffer.edit()._opacity = opacity; } @@ -62,6 +64,7 @@ void Material::setAlbedo(const Color& albedo, bool isSRGB) { void Material::setRoughness(float roughness) { roughness = std::min(1.0f, std::max(roughness, 0.0f)); _key.setGlossy((roughness < 1.0f)); + _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); _schemaBuffer.edit()._roughness = roughness; } @@ -72,6 +75,7 @@ void Material::setFresnel(const Color& fresnel, bool isSRGB) { void Material::setMetallic(float metallic) { _key.setMetallic(metallic > 0.0f); + _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); _schemaBuffer.edit()._metallic = metallic; } @@ -79,9 +83,11 @@ void Material::setMetallic(float metallic) { void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) { if (textureMap) { _key.setMapChannel(channel, (true)); + _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); _textureMaps[channel] = textureMap; } else { _key.setMapChannel(channel, (false)); + _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); _textureMaps.erase(channel); } } diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index df58f60eb1..a6b1cd3706 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -252,7 +252,9 @@ public: float _metallic{ 0.0f }; // Not Metallic - glm::vec4 _spare0{ 0.0f }; + glm::vec3 _spare0{ 0.0f }; + + uint32_t _key{ 0 }; // a copy of the materialKey // for alignment beauty, Material size == Mat4x4 diff --git a/libraries/model/src/model/Material.slh b/libraries/model/src/model/Material.slh index 90a7784042..02bd9568dc 100644 --- a/libraries/model/src/model/Material.slh +++ b/libraries/model/src/model/Material.slh @@ -37,4 +37,5 @@ float getMaterialMetallic(Material m) { return m._fresnelMetallic.a; } float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); } + <@endif@> diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 17d610e87f..b75f2d6acc 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -54,22 +54,38 @@ void TextureMap::setLightmapOffsetScale(float offset, float scale) { gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, const std::string& srcImageName) { QImage image = srcImage; bool validAlpha = false; + bool alphaAsMask = true; + const uint8 OPAQUE_ALPHA = 255; + const uint8 TRANSLUCENT_ALPHA = 0; if (image.hasAlphaChannel()) { + std::map alphaHistogram; + if (image.format() != QImage::Format_ARGB32) { image = image.convertToFormat(QImage::Format_ARGB32); } - // Actual alpha channel? + // Actual alpha channel? create the histogram for (int y = 0; y < image.height(); ++y) { const QRgb* data = reinterpret_cast(image.constScanLine(y)); for (int x = 0; x < image.width(); ++x) { auto alpha = qAlpha(data[x]); - if (alpha != 255) { + alphaHistogram[alpha] ++; + if (alpha != OPAQUE_ALPHA) { validAlpha = true; break; } } } + + // If alpha was meaningfull refine + if (validAlpha && (alphaHistogram.size() > 1)) { + auto totalNumPixels = image.height() * image.width(); + auto numOpaques = alphaHistogram[OPAQUE_ALPHA]; + auto numTranslucents = alphaHistogram[TRANSLUCENT_ALPHA]; + auto numTransparents = totalNumPixels - numOpaques - numTranslucents; + + alphaAsMask = ((numTransparents / (double)totalNumPixels) < 0.05); + } } if (!validAlpha && image.format() != QImage::Format_RGB888) { @@ -89,10 +105,21 @@ gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, con } theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + + auto usage = gpu::Texture::Usage::Builder().withColor(); + if (validAlpha) { + usage.withAlpha(); + if (alphaAsMask) { + usage.withAlphaMask(); + } + } + theTexture->setUsage(usage.build()); + theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); theTexture->autoGenerateMips(-1); // FIXME queue for transfer to GPU and block on completion + } return theTexture; diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index d09ae500ec..a1a75161b9 100755 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -15,8 +15,8 @@ <@include model/Material.slh@> -// the diffuse texture uniform sampler2D albedoMap; +uniform sampler2D roughnessMap; in vec4 _position; in vec3 _normal; @@ -25,8 +25,9 @@ in vec2 _texCoord0; void main(void) { - // Fetch albedo map + // Fetch maps vec4 albedo = texture(albedoMap, _texCoord0); + float roughness = texture(roughnessMap, _texCoord0); Material mat = getMaterial(); @@ -34,7 +35,7 @@ void main(void) { normalize(_normal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, - getMaterialRoughness(mat), + getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat), getMaterialFresnel(mat)); } diff --git a/libraries/render-utils/src/model_lightmap.slf b/libraries/render-utils/src/model_lightmap.slf index a896f5b915..a3505ba779 100755 --- a/libraries/render-utils/src/model_lightmap.slf +++ b/libraries/render-utils/src/model_lightmap.slf @@ -18,6 +18,7 @@ // the albedo texture uniform sampler2D albedoMap; +uniform sampler2D roughnessMap; // the emissive map texture and parameters uniform sampler2D emissiveMap; @@ -30,7 +31,9 @@ in vec3 _normal; in vec3 _color; void main(void) { + // Fetch maps vec4 albedo = texture(albedoMap, _texCoord0); + float roughness = texture(roughnessMap, _texCoord0); vec4 emissive = texture(emissiveMap, _texCoord1); Material mat = getMaterial(); @@ -39,7 +42,7 @@ void main(void) { normalize(_normal), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, - getMaterialRoughness(mat), + getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat), getMaterialFresnel(mat), (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slf b/libraries/render-utils/src/model_lightmap_normal_map.slf index 6431dfb069..223cec71fb 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map.slf @@ -18,6 +18,7 @@ // the albedo texture uniform sampler2D albedoMap; +uniform sampler2D roughnessMap; // the normal map texture uniform sampler2D normalMap; @@ -34,17 +35,19 @@ in vec3 _tangent; in vec3 _color; void main(void) { + // Fetch maps + vec4 albedo = texture(albedoMap, _texCoord0); + float roughness = texture(roughness, _texCoord0); + vec4 emissive = texture(emissiveMap, _texCoord1); + vec3 localNormal = vec3(texture(normalMap, _texCoord0)) - vec3(0.5, 0.5, 0.5); + // compute the view normal from the various bits vec3 normalizedNormal = normalize(_normal); vec3 normalizedTangent = normalize(_tangent); vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); - vec3 localNormal = vec3(texture(normalMap, _texCoord0)) - vec3(0.5, 0.5, 0.5); vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); - - // set the diffuse, normal, specular data - vec4 albedo = texture(albedoMap, _texCoord0); - vec4 emissive = texture(emissiveMap, _texCoord1); + Material mat = getMaterial(); diff --git a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf index 66aacbb7f6..99799a4b25 100755 --- a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf @@ -18,6 +18,7 @@ // the albedo texture uniform sampler2D albedoMap; +uniform sampler2D roughnessMap; // the emissive map texture and parameters uniform sampler2D emissiveMap; @@ -37,18 +38,19 @@ in vec3 _tangent; in vec3 _color; void main(void) { + // Fetch maps + vec4 albedo = texture(albedoMap, _texCoord0); + float roughness = texture(roughnessMap, _texCoord0); + vec3 specular = texture(specularMap, _texCoord0).rgb; + vec4 emissive = texture(emissiveMap, _texCoord1); + vec3 localNormal = vec3(texture(normalMap, _texCoord0)) - vec3(0.5, 0.5, 0.5); + // compute the view normal from the various bits vec3 normalizedNormal = normalize(_normal); vec3 normalizedTangent = normalize(_tangent); vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); - vec3 localNormal = vec3(texture(normalMap, _texCoord0)) - vec3(0.5, 0.5, 0.5); vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); - - // set the albedo, normal, specular data - vec4 albedo = texture(albedoMap, _texCoord0); - vec3 specular = texture(specularMap, _texCoord0).rgb; - vec4 emissive = texture(emissiveMap, _texCoord1); Material mat = getMaterial(); @@ -56,7 +58,7 @@ void main(void) { normalize(viewNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, - getMaterialRoughness(mat), + getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat), specular, // no use of getMaterialFresnel(mat) (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); diff --git a/libraries/render-utils/src/model_lightmap_specular_map.slf b/libraries/render-utils/src/model_lightmap_specular_map.slf index 84fb47f73f..590dfe5727 100755 --- a/libraries/render-utils/src/model_lightmap_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_specular_map.slf @@ -18,6 +18,7 @@ // the albedo texture uniform sampler2D albedoMap; +uniform sampler2D roughnessMap; // the emissive map texture and parameters uniform sampler2D emissiveMap; @@ -33,8 +34,9 @@ in vec3 _normal; in vec3 _color; void main(void) { - // set the albedo, normal, specular data + // Fetch maps vec4 albedo = texture(albedoMap, _texCoord0); + float roughness = texture(roughnessMap, _texCoord0); vec3 specular = texture(specularMap, _texCoord0).rgb; vec4 emissive = texture(emissiveMap, _texCoord1); @@ -44,7 +46,7 @@ void main(void) { normalize(_normal), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, - getMaterialRoughness(mat), + getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat), specular, // no use of getMaterialFresnel(mat) (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); diff --git a/libraries/render-utils/src/model_normal_map.slf b/libraries/render-utils/src/model_normal_map.slf index 204cfaec3f..8adde1d850 100755 --- a/libraries/render-utils/src/model_normal_map.slf +++ b/libraries/render-utils/src/model_normal_map.slf @@ -15,9 +15,11 @@ <@include DeferredBufferWrite.slh@> <@include model/Material.slh@> +<@include model/MaterialTextures.slh@> // the albedo texture uniform sampler2D albedoMap; +uniform sampler2D roughnessMap; // the normal map texture uniform sampler2D normalMap; @@ -38,6 +40,7 @@ void main(void) { normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); vec4 albedo = texture(albedoMap, _texCoord0.st); + float roughness = texture(roughnessMap, _texCoord0); Material mat = getMaterial(); @@ -45,7 +48,7 @@ void main(void) { normalize(viewNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, - getMaterialRoughness(mat), + getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat), getMaterialFresnel(mat)); } diff --git a/libraries/render-utils/src/model_normal_specular_map.slf b/libraries/render-utils/src/model_normal_specular_map.slf index ef39460ddd..95a13198c0 100755 --- a/libraries/render-utils/src/model_normal_specular_map.slf +++ b/libraries/render-utils/src/model_normal_specular_map.slf @@ -18,6 +18,7 @@ // the albedo texture uniform sampler2D albedoMap; +uniform sampler2D roughnessMap; // the normal map texture uniform sampler2D normalMap; @@ -42,6 +43,7 @@ void main(void) { // set the albedo, normal, specular data vec4 albedo = texture(albedoMap, _texCoord0); + vec4 roughness = texture(roughnessMap, _texCoord0); vec3 specular = texture(specularMap, _texCoord0).rgb; Material mat = getMaterial(); @@ -50,7 +52,7 @@ void main(void) { normalize(viewNormal.xyz), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, - getMaterialRoughness(mat), + getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat), specular //getMaterialFresnel(mat) ); diff --git a/libraries/render-utils/src/model_specular_map.slf b/libraries/render-utils/src/model_specular_map.slf index 54d6a8a33f..5821ab8154 100755 --- a/libraries/render-utils/src/model_specular_map.slf +++ b/libraries/render-utils/src/model_specular_map.slf @@ -18,6 +18,7 @@ // the albedo texture uniform sampler2D albedoMap; +uniform sampler2D roughnessMap; // the specular texture uniform sampler2D specularMap; @@ -31,6 +32,7 @@ in vec3 _color; void main(void) { // set the albedo, normal, specular data vec4 albedo = texture(albedoMap, _texCoord0); + float roughness = texture(roughnessMap, _texCoord0); vec3 specular = texture(specularMap, _texCoord0).rgb; Material mat = getMaterial(); @@ -39,7 +41,7 @@ void main(void) { normalize(_normal), evalOpaqueFinalAlpha(getMaterialOpacity(mat), albedo.a), getMaterialAlbedo(mat) * albedo.rgb * _color, - getMaterialRoughness(mat), + getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat), specular //getMaterialFresnel(mat) );