Merge pull request #7743 from samcake/color

group several separate glUniform parameters into a single Uniform Buffer
This commit is contained in:
Andrew Meadows 2016-04-27 10:02:56 -07:00
commit 93f4bc759d
15 changed files with 114 additions and 68 deletions

View file

@ -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<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema));
TexMapArraySchema TexMapArraySchema;
_texMapArrayBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(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<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema));
_schemaBuffer.edit<Schema>() = material._schemaBuffer.get<Schema>();
TexMapArraySchema texMapArraySchema;
_texMapArrayBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(TexMapArraySchema), (const gpu::Byte*) &texMapArraySchema));
_texMapArrayBuffer.edit<TexMapArraySchema>() = material._texMapArrayBuffer.get<TexMapArraySchema>();
}
Material& Material::operator= (const Material& material) {
@ -46,6 +52,10 @@ Material& Material::operator= (const Material& material) {
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema));
_schemaBuffer.edit<Schema>() = material._schemaBuffer.get<Schema>();
TexMapArraySchema texMapArraySchema;
_texMapArrayBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(TexMapArraySchema), (const gpu::Byte*) &texMapArraySchema));
_texMapArrayBuffer.edit<TexMapArraySchema>() = material._texMapArrayBuffer.get<TexMapArraySchema>();
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<TexMapArraySchema>()._texcoordTransforms[0] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
}
if (channel == MaterialKey::LIGHTMAP_MAP) {
// update the texcoord1 with lightmap
_texMapArrayBuffer.edit<TexMapArraySchema>()._texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
_texMapArrayBuffer.edit<TexMapArraySchema>()._lightmapParams = (textureMap ? glm::vec4(textureMap->getLightmapOffsetScale(), 0.0, 0.0) : glm::vec4(0.0, 1.0, 0.0, 0.0));
}
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();

View file

@ -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;

View file

@ -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@>

View file

@ -138,21 +138,17 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
auto textureCache = DependencyManager::get<TextureCache>();
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()) {

View file

@ -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<TextureCache>()->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);
}
}

View file

@ -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;

View file

@ -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();

View file

@ -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);
}

View file

@ -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();

View file

@ -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();

View file

@ -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();

View file

@ -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();

View file

@ -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);

View file

@ -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>();
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};

View file

@ -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<Locations>;