Merge pull request #7796 from samcake/blue

Improve Translucent shapes global lighting with support for the ambient map reflection
This commit is contained in:
Brad Hefta-Gaub 2016-05-03 11:14:06 -07:00
commit bbf358f81d
8 changed files with 139 additions and 77 deletions

View file

@ -109,10 +109,15 @@ SphericalHarmonics getLightAmbientSphere(Light l) {
return l._ambientSphere;
}
bool getLightHasAmbientMap(Light l) {
return l._control.x > 0;
}
float getLightAmbientMapNumMips(Light l) {
return l._control.x;
}
<@if GPU_FEATURE_PROFILE == GPU_CORE @>
uniform lightBuffer {
Light light;

View file

@ -25,6 +25,43 @@ vec4 evalSkyboxLight(vec3 direction, float lod) {
}
<@endfunc@>
<@func declareEvalGlobalSpecularIrradiance(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere)@>
vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) {
return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5);
}
<@if supportAmbientMap@>
<$declareSkyboxMap()$>
<@endif@>
vec3 evalGlobalSpecularIrradiance(Light light, vec3 fragEyeDir, vec3 fragNormal, float roughness, vec3 fresnel, float obscurance) {
vec3 direction = -reflect(fragEyeDir, fragNormal);
vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness);
vec3 specularLight;
<@if supportIfAmbientMapElseAmbientSphere@>
if (getLightHasAmbientMap(light))
<@endif@>
<@if supportAmbientMap@>
{
float levels = getLightAmbientMapNumMips(light);
float lod = min(floor((roughness) * levels), levels);
specularLight = evalSkyboxLight(direction, lod).xyz;
}
<@endif@>
<@if supportIfAmbientMapElseAmbientSphere@>
else
<@endif@>
<@if supportAmbientSphere@>
{
specularLight = evalSphericalLight(getLightAmbientSphere(light), direction).xyz;
}
<@endif@>
return specularLight * ambientFresnel * getLightAmbientIntensity(light);
}
<@endfunc@>
<@func prepareGlobalLight()@>
// prepareGlobalLight
@ -45,11 +82,6 @@ vec4 evalSkyboxLight(vec3 direction, float lod) {
color += emissive;
<@endfunc@>
<@func declareAmbientFresnel()@>
vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) {
return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5);
}
<@endfunc@>
<@func declareEvalAmbientGlobalColor()@>
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
@ -60,7 +92,8 @@ vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obsc
<@endfunc@>
<@func declareEvalAmbientSphereGlobalColor()@>
<$declareAmbientFresnel()$>
<$declareEvalGlobalSpecularIrradiance(1, 0, 0)$>
vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
<$prepareGlobalLight()$>
@ -69,18 +102,15 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa
color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
// Specular highlight from ambient
vec3 direction = -reflect(fragEyeDir, fragNormal);
vec3 skyboxLight = evalSphericalLight(getLightAmbientSphere(light), direction).xyz;
vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness);
color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light);
vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, obscurance);
color += specularLighting;
return color;
}
<@endfunc@>
<@func declareEvalSkyboxGlobalColor()@>
<$declareSkyboxMap()$>
<$declareAmbientFresnel()$>
<$declareEvalGlobalSpecularIrradiance(0, 1, 0)$>
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) {
<$prepareGlobalLight()$>
@ -89,13 +119,8 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
// Specular highlight from ambient
vec3 direction = -reflect(fragEyeDir, fragNormal);
float levels = getLightAmbientMapNumMips(light);
float lod = min(floor((roughness) * levels), levels);
vec4 skyboxLight = evalSkyboxLight(direction, lod);
vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness);
color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light);
vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, obscurance);
color += specularLighting;
return color;
}
@ -125,4 +150,26 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
}
<@endfunc@>
<@func declareEvalGlobalLightingAlphaBlended()@>
<$declareEvalGlobalSpecularIrradiance(1, 1, 1)$>
vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness, float opacity) {
<$prepareGlobalLight()$>
// Diffuse from ambient
color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light);
// Specular highlight from ambient
vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, obscurance);
color += specularLighting / opacity;
return color;
}
<@endfunc@>
<@endif@>

View file

@ -506,9 +506,9 @@ GeometryCache::GeometryCache() :
std::make_shared<render::ShapePipeline>(getSimplePipeline(), nullptr,
[](const render::ShapePipeline&, gpu::Batch& batch) {
// Set the defaults needed for a simple program
batch.setResourceTexture(render::ShapePipeline::Slot::ALBEDO_MAP,
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
DependencyManager::get<TextureCache>()->getWhiteTexture());
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
}
);
@ -1736,11 +1736,11 @@ void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool cul
// If not textured, set a default albedo map
if (!textured) {
batch.setResourceTexture(render::ShapePipeline::Slot::ALBEDO_MAP,
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
DependencyManager::get<TextureCache>()->getWhiteTexture());
}
// Set a default normal map
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
}
@ -1758,7 +1758,7 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool culled
_emissiveShader = gpu::Shader::createProgram(VS, PSEmissive);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::NORMAL_FITTING_MAP));
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::MAP::NORMAL_FITTING));
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
gpu::Shader::makeProgram(*_emissiveShader, slotBindings);
});

View file

@ -138,8 +138,8 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
auto textureCache = DependencyManager::get<TextureCache>();
batch.setUniformBuffer(ShapePipeline::Slot::MATERIAL_BUFFER, _drawMaterial->getSchemaBuffer());
batch.setUniformBuffer(ShapePipeline::Slot::TEXMAPARRAY_BUFFER, _drawMaterial->getTexMapArrayBuffer());
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::MATERIAL, _drawMaterial->getSchemaBuffer());
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::TEXMAPARRAY, _drawMaterial->getTexMapArrayBuffer());
auto materialKey = _drawMaterial->getKey();
auto textureMaps = _drawMaterial->getTextureMaps();
@ -148,68 +148,68 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
if (materialKey.isAlbedoMap()) {
auto albedoMap = textureMaps[model::MaterialKey::ALBEDO_MAP];
if (albedoMap && albedoMap->isDefined()) {
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, albedoMap->getTextureView());
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, albedoMap->getTextureView());
} else {
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, textureCache->getGrayTexture());
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getGrayTexture());
}
} else {
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO_MAP, textureCache->getWhiteTexture());
batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getWhiteTexture());
}
// Roughness map
if (materialKey.isRoughnessMap()) {
auto roughnessMap = textureMaps[model::MaterialKey::ROUGHNESS_MAP];
if (roughnessMap && roughnessMap->isDefined()) {
batch.setResourceTexture(ShapePipeline::Slot::ROUGHNESS_MAP, roughnessMap->getTextureView());
batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, roughnessMap->getTextureView());
// texcoord are assumed to be the same has albedo
} else {
batch.setResourceTexture(ShapePipeline::Slot::ROUGHNESS_MAP, textureCache->getWhiteTexture());
batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture());
}
} else {
batch.setResourceTexture(ShapePipeline::Slot::ROUGHNESS_MAP, textureCache->getWhiteTexture());
batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture());
}
// Normal map
if (materialKey.isNormalMap()) {
auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP];
if (normalMap && normalMap->isDefined()) {
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, normalMap->getTextureView());
batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, normalMap->getTextureView());
// texcoord are assumed to be the same has albedo
} else {
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, textureCache->getBlueTexture());
batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, textureCache->getBlueTexture());
}
} else {
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, nullptr);
batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, nullptr);
}
// Metallic map
if (materialKey.isMetallicMap()) {
auto specularMap = textureMaps[model::MaterialKey::METALLIC_MAP];
if (specularMap && specularMap->isDefined()) {
batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, specularMap->getTextureView());
batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, specularMap->getTextureView());
// texcoord are assumed to be the same has albedo
} else {
batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, textureCache->getBlackTexture());
batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, textureCache->getBlackTexture());
}
} else {
batch.setResourceTexture(ShapePipeline::Slot::METALLIC_MAP, nullptr);
batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, nullptr);
}
// Occlusion map
if (materialKey.isOcclusionMap()) {
auto specularMap = textureMaps[model::MaterialKey::OCCLUSION_MAP];
if (specularMap && specularMap->isDefined()) {
batch.setResourceTexture(ShapePipeline::Slot::OCCLUSION_MAP, specularMap->getTextureView());
batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, specularMap->getTextureView());
// texcoord are assumed to be the same has albedo
} else {
batch.setResourceTexture(ShapePipeline::Slot::OCCLUSION_MAP, textureCache->getWhiteTexture());
batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, textureCache->getWhiteTexture());
}
} else {
batch.setResourceTexture(ShapePipeline::Slot::OCCLUSION_MAP, nullptr);
batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, nullptr);
}
// Emissive / Lightmap
@ -217,20 +217,20 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP];
if (lightmapMap && lightmapMap->isDefined()) {
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, lightmapMap->getTextureView());
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, lightmapMap->getTextureView());
} else {
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, textureCache->getGrayTexture());
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getGrayTexture());
}
} else if (materialKey.isEmissiveMap()) {
auto emissiveMap = textureMaps[model::MaterialKey::EMISSIVE_MAP];
if (emissiveMap && emissiveMap->isDefined()) {
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, emissiveMap->getTextureView());
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, emissiveMap->getTextureView());
} else {
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, textureCache->getBlackTexture());
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getBlackTexture());
}
} else {
batch.setResourceTexture(ShapePipeline::Slot::EMISSIVE_LIGHTMAP_MAP, nullptr);
batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, nullptr);
}
}
@ -474,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_BUFFER, state.cauterizedClusterBuffer);
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, state.cauterizedClusterBuffer);
} else {
batch.setUniformBuffer(ShapePipeline::Slot::SKINNING_BUFFER, state.clusterBuffer);
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::SKINNING, state.clusterBuffer);
}
} else {
if (canCauterize && _model->getCauterizeBones()) {

View file

@ -75,16 +75,16 @@ gpu::BufferView getDefaultMaterialBuffer() {
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
// Set a default albedo map
batch.setResourceTexture(render::ShapePipeline::Slot::ALBEDO_MAP,
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO,
DependencyManager::get<TextureCache>()->getWhiteTexture());
// Set a default normal map
batch.setResourceTexture(render::ShapePipeline::Slot::NORMAL_FITTING_MAP,
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
// Set a default material
if (pipeline.locations->materialBufferUnit >= 0) {
static const gpu::BufferView OPAQUE_SCHEMA_BUFFER = getDefaultMaterialBuffer();
batch.setUniformBuffer(ShapePipeline::Slot::MATERIAL_BUFFER, OPAQUE_SCHEMA_BUFFER);
batch.setUniformBuffer(ShapePipeline::Slot::BUFFER::MATERIAL, OPAQUE_SCHEMA_BUFFER);
}
}
@ -94,7 +94,7 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch) {
if (pipeline.locations->lightBufferUnit >= 0) {
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(batch,
pipeline.locations->lightBufferUnit,
-1);
pipeline.locations->lightAmbientMapUnit);
}
}

View file

@ -15,7 +15,8 @@
<@include model/Material.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalAmbientSphereGlobalColor()$>
<$declareEvalGlobalLightingAlphaBlended()$>
<@include gpu/Transform.slh@>
<$declareStandardCameraTransform()$>
@ -58,7 +59,7 @@ void main(void) {
TransformCamera cam = getTransformCamera();
_fragColor = vec4(evalAmbientSphereGlobalColor(
_fragColor = vec4(evalGlobalLightingAlphaBlended(
cam._viewInverse,
1.0,
1.0,
@ -67,6 +68,6 @@ void main(void) {
albedo,
metallic,
emissive,
roughness),
roughness, opacity),
opacity);
}

View file

@ -51,17 +51,18 @@ 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_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));
slotBindings.insert(gpu::Shader::Binding(std::string("metallicMap"), Slot::METALLIC_MAP));
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), Slot::EMISSIVE_LIGHTMAP_MAP));
slotBindings.insert(gpu::Shader::Binding(std::string("occlusionMap"), Slot::OCCLUSION_MAP));
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::LIGHT_BUFFER));
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), Slot::NORMAL_FITTING_MAP));
slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::BUFFER::SKINNING));
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), Slot::BUFFER::MATERIAL));
slotBindings.insert(gpu::Shader::Binding(std::string("texMapArrayBuffer"), Slot::BUFFER::TEXMAPARRAY));
slotBindings.insert(gpu::Shader::Binding(std::string("albedoMap"), Slot::MAP::ALBEDO));
slotBindings.insert(gpu::Shader::Binding(std::string("roughnessMap"), Slot::MAP::ROUGHNESS));
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), Slot::MAP::NORMAL));
slotBindings.insert(gpu::Shader::Binding(std::string("metallicMap"), Slot::MAP::METALLIC));
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), Slot::MAP::EMISSIVE_LIGHTMAP));
slotBindings.insert(gpu::Shader::Binding(std::string("occlusionMap"), Slot::MAP::OCCLUSION));
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::BUFFER::LIGHT));
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT));
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), Slot::NORMAL_FITTING));
gpu::Shader::makeProgram(*program, slotBindings);
@ -77,6 +78,7 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
locations->materialBufferUnit = program->getBuffers().findLocation("materialBuffer");
locations->texMapArrayBufferUnit = program->getBuffers().findLocation("texMapArrayBuffer");
locations->lightBufferUnit = program->getBuffers().findLocation("lightBuffer");
locations->lightAmbientMapUnit = program->getTextures().findLocation("skyboxMap");
ShapeKey key{filter._flags};
auto gpuPipeline = gpu::Pipeline::create(program, state);

View file

@ -193,18 +193,24 @@ class ShapePipeline {
public:
class Slot {
public:
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;
static const int EMISSIVE_LIGHTMAP_MAP = 3;
static const int ROUGHNESS_MAP = 4;
static const int OCCLUSION_MAP = 5;
enum BUFFER {
SKINNING = 2,
MATERIAL,
TEXMAPARRAY,
LIGHT
};
static const int LIGHT_BUFFER = 5;
static const int NORMAL_FITTING_MAP = 10;
enum MAP {
ALBEDO = 0,
NORMAL,
METALLIC,
EMISSIVE_LIGHTMAP,
ROUGHNESS,
OCCLUSION,
LIGHT_AMBIENT,
NORMAL_FITTING = 10,
};
};
class Locations {
@ -220,6 +226,7 @@ public:
int materialBufferUnit;
int texMapArrayBufferUnit;
int lightBufferUnit;
int lightAmbientMapUnit;
};
using LocationsPointer = std::shared_ptr<Locations>;