diff --git a/libraries/model/src/model/Material.cpp b/libraries/model/src/model/Material.cpp index 802650df93..1ea407122f 100755 --- a/libraries/model/src/model/Material.cpp +++ b/libraries/model/src/model/Material.cpp @@ -18,13 +18,15 @@ using namespace gpu; Material::Material() : _key(0), _schemaBuffer(), + _texMapArrayBuffer(), _textureMaps() { // created from nothing: create the Buffer to store the properties Schema schema; _schemaBuffer = gpu::BufferView(std::make_shared(sizeof(Schema), (const gpu::Byte*) &schema)); - + TexMapArraySchema TexMapArraySchema; + _texMapArrayBuffer = gpu::BufferView(std::make_shared(sizeof(TexMapArraySchema), (const gpu::Byte*) &TexMapArraySchema)); } Material::Material(const Material& material) : @@ -35,6 +37,10 @@ Material::Material(const Material& material) : Schema schema; _schemaBuffer = gpu::BufferView(std::make_shared(sizeof(Schema), (const gpu::Byte*) &schema)); _schemaBuffer.edit() = material._schemaBuffer.get(); + + TexMapArraySchema texMapArraySchema; + _texMapArrayBuffer = gpu::BufferView(std::make_shared(sizeof(TexMapArraySchema), (const gpu::Byte*) &texMapArraySchema)); + _texMapArrayBuffer.edit() = material._texMapArrayBuffer.get(); } Material& Material::operator= (const Material& material) { @@ -46,6 +52,10 @@ Material& Material::operator= (const Material& material) { _schemaBuffer = gpu::BufferView(std::make_shared(sizeof(Schema), (const gpu::Byte*) &schema)); _schemaBuffer.edit() = material._schemaBuffer.get(); + TexMapArraySchema texMapArraySchema; + _texMapArrayBuffer = gpu::BufferView(std::make_shared(sizeof(TexMapArraySchema), (const gpu::Byte*) &texMapArraySchema)); + _texMapArrayBuffer.edit() = material._texMapArrayBuffer.get(); + return (*this); } @@ -101,6 +111,15 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur if (channel == MaterialKey::ALBEDO_MAP) { resetOpacityMap(); + + // update the texcoord0 with albedo + _texMapArrayBuffer.edit()._texcoordTransforms[0] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4()); + } + + if (channel == MaterialKey::LIGHTMAP_MAP) { + // update the texcoord1 with lightmap + _texMapArrayBuffer.edit()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4()); + _texMapArrayBuffer.edit()._lightmapParams = (textureMap ? glm::vec4(textureMap->getLightmapOffsetScale(), 0.0, 0.0) : glm::vec4(0.0, 1.0, 0.0, 0.0)); } _schemaBuffer.edit()._key = (uint32)_key._flags.to_ulong(); diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index c500e9ec10..4cfb2120ee 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -298,9 +298,21 @@ public: // conversion from legacy material properties to PBR equivalent static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; } + // Texture Map Array Schema + static const int NUM_TEXCOORD_TRANSFORMS{ 2 }; + class TexMapArraySchema { + public: + glm::mat4 _texcoordTransforms[NUM_TEXCOORD_TRANSFORMS]; + glm::vec4 _lightmapParams{ 0.0, 1.0, 0.0, 0.0 }; + TexMapArraySchema() {} + }; + + const UniformBufferView& getTexMapArrayBuffer() const { return _texMapArrayBuffer; } private: mutable MaterialKey _key; mutable UniformBufferView _schemaBuffer; + mutable UniformBufferView _texMapArrayBuffer; + TextureMaps _textureMaps; }; typedef std::shared_ptr< Material > MaterialPointer; diff --git a/libraries/render-utils/src/MaterialTextures.slh b/libraries/render-utils/src/MaterialTextures.slh index 34bb7c429b..512b7a533c 100644 --- a/libraries/render-utils/src/MaterialTextures.slh +++ b/libraries/render-utils/src/MaterialTextures.slh @@ -11,6 +11,39 @@ <@if not MODEL_MATERIAL_TEXTURES_SLH@> <@def MODEL_MATERIAL_TEXTURES_SLH@> + +<@func declareMaterialTexMapArrayBuffer()@> + +const int MAX_TEXCOORDS = 2; + +struct TexMapArray { + mat4 _texcoordTransforms[MAX_TEXCOORDS]; + vec4 _lightmapParams; +}; + +uniform texMapArrayBuffer { + TexMapArray _texMapArray; +}; + +TexMapArray getTexMapArray() { + return _texMapArray; +} + +<@func evalTexMapArrayTexcoord0(texMapArray, inTexcoord0, outTexcoord0)@> +{ + <$outTexcoord0$> = (<$texMapArray$>._texcoordTransforms[0] * vec4(<$inTexcoord0$>.st, 0.0, 1.0)).st; +} +<@endfunc@> + +<@func evalTexMapArrayTexcoord1(texMapArray, inTexcoord1, outTexcoord1)@> +{ + <$outTexcoord1$> = (<$texMapArray$>._texcoordTransforms[1] * vec4(<$inTexcoord1$>.st, 0.0, 1.0)).st; +} +<@endfunc@> + +<@endfunc@> + + <@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion)@> <@if withAlbedo@> @@ -80,9 +113,12 @@ float fetchOcclusionMap(vec2 uv) { <@func declareMaterialLightmap()@> + +<$declareMaterialTexMapArrayBuffer()$> + uniform sampler2D emissiveMap; -uniform vec2 emissiveParams; vec3 fetchLightmapMap(vec2 uv) { + vec2 emissiveParams = getTexMapArray()._lightmapParams.xy; return (vec3(emissiveParams.x) + emissiveParams.y * texture(emissiveMap, uv).rgb); } <@endfunc@> diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index a273d92112..6571674e44 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -138,21 +138,17 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat auto textureCache = DependencyManager::get(); - batch.setUniformBuffer(ShapePipeline::Slot::MATERIAL_GPU, _drawMaterial->getSchemaBuffer()); + batch.setUniformBuffer(ShapePipeline::Slot::MATERIAL_BUFFER, _drawMaterial->getSchemaBuffer()); + batch.setUniformBuffer(ShapePipeline::Slot::TEXMAPARRAY_BUFFER, _drawMaterial->getTexMapArrayBuffer()); auto materialKey = _drawMaterial->getKey(); auto textureMaps = _drawMaterial->getTextureMaps(); - glm::mat4 texcoordTransform[2]; // Albedo if (materialKey.isAlbedoMap()) { auto albedoMap = textureMaps[model::MaterialKey::ALBEDO_MAP]; if (albedoMap && albedoMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, albedoMap->getTextureView()); - - if (!albedoMap->getTextureTransform().isIdentity()) { - albedoMap->getTextureTransform().getMatrix(texcoordTransform[0]); - } } else { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, textureCache->getGrayTexture()); } @@ -222,13 +218,6 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat if (lightmapMap && lightmapMap->isDefined()) { batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, lightmapMap->getTextureView()); - - auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale(); - batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y); - - if (!lightmapMap->getTextureTransform().isIdentity()) { - lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]); - } } else { batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, textureCache->getGrayTexture()); } @@ -243,12 +232,6 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat } else { batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, nullptr); } - - // Texcoord transforms ? - if (locations->texcoordMatrices >= 0) { - batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform); - // batch._glUniformMatrix4fv(locations->texcoordMatrices, (materialKey.isLightmapMap() ? 2 : 1), false, (const float*)&texcoordTransform); - } } void MeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, bool canCauterize) const { @@ -491,9 +474,9 @@ void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline: Transform transform; if (state.clusterBuffer) { if (canCauterize && _model->getCauterizeBones()) { - batch.setUniformBuffer(ShapePipeline::Slot::SKINNING_GPU, state.cauterizedClusterBuffer); + batch.setUniformBuffer(ShapePipeline::Slot::SKINNING_BUFFER, state.cauterizedClusterBuffer); } else { - batch.setUniformBuffer(ShapePipeline::Slot::SKINNING_GPU, state.clusterBuffer); + batch.setUniformBuffer(ShapePipeline::Slot::SKINNING_BUFFER, state.clusterBuffer); } } else { if (canCauterize && _model->getCauterizeBones()) { diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index aa0f9dc7d9..bca8f3791f 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -80,15 +80,11 @@ void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) { // Set a default normal map batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP, DependencyManager::get()->getNormalFittingTexture()); - // Set default coordinates - if (pipeline.locations->texcoordMatrices >= 0) { - static const glm::mat4 TEX_COORDS[2]; - batch._glUniformMatrix4fv(pipeline.locations->texcoordMatrices, 2, false, (const float*)&TEX_COORDS); - } + // Set a default material if (pipeline.locations->materialBufferUnit >= 0) { static const gpu::BufferView OPAQUE_SCHEMA_BUFFER = getDefaultMaterialBuffer(); - batch.setUniformBuffer(ShapePipeline::Slot::MATERIAL_GPU, OPAQUE_SCHEMA_BUFFER); + batch.setUniformBuffer(ShapePipeline::Slot::MATERIAL_BUFFER, OPAQUE_SCHEMA_BUFFER); } } diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh index 63992c35ad..687dab536b 100644 --- a/libraries/render-utils/src/Skinning.slh +++ b/libraries/render-utils/src/Skinning.slh @@ -11,7 +11,6 @@ <@if not SKINNING_SLH@> <@def SKINNING_SLH@> -const int MAX_TEXCOORDS = 2; const int MAX_CLUSTERS = 128; const int INDICES_PER_VERTEX = 4; diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv index 0507f1c6c5..f1989dcf76 100755 --- a/libraries/render-utils/src/model.slv +++ b/libraries/render-utils/src/model.slv @@ -16,8 +16,8 @@ <@include gpu/Transform.slh@> <$declareStandardTransform()$> -const int MAX_TEXCOORDS = 2; -uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; +<@include MaterialTextures.slh@> +<$declareMaterialTexMapArrayBuffer()$> out vec3 _color; out float _alpha; @@ -29,7 +29,8 @@ void main(void) { _color = colorToLinearRGB(inColor.xyz); _alpha = inColor.w; - _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$> // standard transform TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/model_lightmap.slf b/libraries/render-utils/src/model_lightmap.slf index 46d81d39e1..3afbbfd405 100755 --- a/libraries/render-utils/src/model_lightmap.slf +++ b/libraries/render-utils/src/model_lightmap.slf @@ -30,7 +30,7 @@ void main(void) { Material mat = getMaterial(); int matKey = getMaterialKey(mat); <$fetchMaterialTextures(matKey, _texCoord0, albedo, roughness)$> - <$fetchMaterialLightmap(_texCoord1, emissive)$> + <$fetchMaterialLightmap(_texCoord1, lightmapVal)$> packDeferredFragmentLightmap( @@ -40,5 +40,5 @@ void main(void) { getMaterialRoughness(mat) * roughness, getMaterialMetallic(mat), getMaterialFresnel(mat), - (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); + lightmapVal); } diff --git a/libraries/render-utils/src/model_lightmap.slv b/libraries/render-utils/src/model_lightmap.slv index 8696b70373..f73b6a02a7 100755 --- a/libraries/render-utils/src/model_lightmap.slv +++ b/libraries/render-utils/src/model_lightmap.slv @@ -17,9 +17,8 @@ <@include gpu/Transform.slh@> <$declareStandardTransform()$> -const int MAX_TEXCOORDS = 2; - -uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; +<@include MaterialTextures.slh@> +<$declareMaterialTexMapArrayBuffer()$> out vec4 _position; out vec2 _texCoord0; @@ -32,8 +31,9 @@ void main(void) { _color = colorToLinearRGB(inColor.xyz); // and the texture coordinates - _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; - _texCoord1 = (texcoordMatrices[1] * vec4(inTexCoord1.st, 0.0, 1.0)).st; + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord1)$> // standard transform TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slv b/libraries/render-utils/src/model_lightmap_normal_map.slv index eb8f80656d..cb333f50e3 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slv +++ b/libraries/render-utils/src/model_lightmap_normal_map.slv @@ -17,9 +17,8 @@ <@include gpu/Transform.slh@> <$declareStandardTransform()$> -const int MAX_TEXCOORDS = 2; - -uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; +<@include MaterialTextures.slh@> +<$declareMaterialTexMapArrayBuffer()$> out vec4 _position; out vec2 _texCoord0; @@ -32,9 +31,9 @@ void main(void) { // pass along the color in linear space _color = colorToLinearRGB(inColor.xyz); - // and the texture coordinates - _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; - _texCoord1 = (texcoordMatrices[1] * vec4(inTexCoord1.st, 0.0, 1.0)).st; + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _texCoord1)$> // standard transform TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/model_normal_map.slv b/libraries/render-utils/src/model_normal_map.slv index 4f45902dae..ded37923c2 100755 --- a/libraries/render-utils/src/model_normal_map.slv +++ b/libraries/render-utils/src/model_normal_map.slv @@ -17,9 +17,8 @@ <@include gpu/Transform.slh@> <$declareStandardTransform()$> -const int MAX_TEXCOORDS = 2; - -uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; +<@include MaterialTextures.slh@> +<$declareMaterialTexMapArrayBuffer()$> out vec4 _position; out vec2 _texCoord0; @@ -33,8 +32,8 @@ void main(void) { _color = colorToLinearRGB(inColor.rgb); _alpha = inColor.a; - // and the texture coordinates - _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.xy, 0.0, 1.0)).st; + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$> // standard transform TransformCamera cam = getTransformCamera(); diff --git a/libraries/render-utils/src/skin_model.slv b/libraries/render-utils/src/skin_model.slv index e5d1857d44..c8501b8ddf 100755 --- a/libraries/render-utils/src/skin_model.slv +++ b/libraries/render-utils/src/skin_model.slv @@ -19,7 +19,8 @@ <@include Skinning.slh@> -uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; +<@include MaterialTextures.slh@> +<$declareMaterialTexMapArrayBuffer()$> out vec4 _position; out vec2 _texCoord0; @@ -37,9 +38,9 @@ void main(void) { _color = colorToLinearRGB(inColor.rgb); _alpha = inColor.a; - // and the texture coordinates - _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; - + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$> + // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); diff --git a/libraries/render-utils/src/skin_model_normal_map.slv b/libraries/render-utils/src/skin_model_normal_map.slv index 5348ad5234..db4b206405 100755 --- a/libraries/render-utils/src/skin_model_normal_map.slv +++ b/libraries/render-utils/src/skin_model_normal_map.slv @@ -19,7 +19,8 @@ <@include Skinning.slh@> -uniform mat4 texcoordMatrices[MAX_TEXCOORDS]; +<@include MaterialTextures.slh@> +<$declareMaterialTexMapArrayBuffer()$> out vec4 _position; out vec2 _texCoord0; @@ -39,9 +40,9 @@ void main(void) { _color = colorToLinearRGB(inColor.rgb); _alpha = inColor.a; - // and the texture coordinates - _texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st; - + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$> + interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); interpolatedTangent = vec4(normalize(interpolatedTangent.xyz), 0.0); diff --git a/libraries/render/src/render/ShapePipeline.cpp b/libraries/render/src/render/ShapePipeline.cpp index 6974a7e385..b09d4b1356 100644 --- a/libraries/render/src/render/ShapePipeline.cpp +++ b/libraries/render/src/render/ShapePipeline.cpp @@ -51,8 +51,9 @@ void ShapePlumber::addPipeline(const Key& key, const gpu::ShaderPointer& program void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& program, const gpu::StatePointer& state, BatchSetter batchSetter) { gpu::Shader::BindingSet slotBindings; - slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::SKINNING_GPU)); - slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), Slot::MATERIAL_GPU)); + slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::SKINNING_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), Slot::MATERIAL_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("texMapArrayBuffer"), Slot::TEXMAPARRAY_BUFFER)); slotBindings.insert(gpu::Shader::Binding(std::string("albedoMap"), Slot::ALBEDO_MAP)); slotBindings.insert(gpu::Shader::Binding(std::string("roughnessMap"), Slot::ROUGHNESS_MAP)); slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), Slot::NORMAL_MAP)); @@ -65,8 +66,6 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p gpu::Shader::makeProgram(*program, slotBindings); auto locations = std::make_shared(); - locations->texcoordMatrices = program->getUniforms().findLocation("texcoordMatrices"); - locations->emissiveParams = program->getUniforms().findLocation("emissiveParams"); locations->normalFittingMapUnit = program->getTextures().findLocation("normalFittingMap"); locations->albedoTextureUnit = program->getTextures().findLocation("albedoMap"); locations->roughnessTextureUnit = program->getTextures().findLocation("roughnessMap"); @@ -76,6 +75,7 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p locations->occlusionTextureUnit = program->getTextures().findLocation("occlusionMap"); locations->skinClusterBufferUnit = program->getBuffers().findLocation("skinClusterBuffer"); locations->materialBufferUnit = program->getBuffers().findLocation("materialBuffer"); + locations->texMapArrayBufferUnit = program->getBuffers().findLocation("texMapArrayBuffer"); locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer"); ShapeKey key{filter._flags}; diff --git a/libraries/render/src/render/ShapePipeline.h b/libraries/render/src/render/ShapePipeline.h index 0f795aadde..22aa22d4c9 100644 --- a/libraries/render/src/render/ShapePipeline.h +++ b/libraries/render/src/render/ShapePipeline.h @@ -193,8 +193,9 @@ class ShapePipeline { public: class Slot { public: - static const int SKINNING_GPU = 2; - static const int MATERIAL_GPU = 3; + static const int SKINNING_BUFFER = 2; + static const int MATERIAL_BUFFER = 3; + static const int TEXMAPARRAY_BUFFER = 4; static const int ALBEDO_MAP = 0; static const int NORMAL_MAP = 1; static const int METALLIC_MAP = 2; @@ -202,23 +203,22 @@ public: static const int ROUGHNESS_MAP = 4; static const int OCCLUSION_MAP = 5; - static const int LIGHT_BUFFER = 4; + static const int LIGHT_BUFFER = 5; static const int NORMAL_FITTING_MAP = 10; }; class Locations { public: - int texcoordMatrices; int albedoTextureUnit; int normalTextureUnit; int roughnessTextureUnit; int metallicTextureUnit; int emissiveTextureUnit; int occlusionTextureUnit; - int emissiveParams; int normalFittingMapUnit; int skinClusterBufferUnit; int materialBufferUnit; + int texMapArrayBufferUnit; int lightBufferUnit; }; using LocationsPointer = std::shared_ptr;