Fix emissive in unlit shaders

This change applies exposure compensation just like with
lit shaders.
This commit is contained in:
Romain Guy
2020-02-25 09:47:06 -08:00
parent 8eaa1f5e88
commit 8b2ea72be2
4 changed files with 99 additions and 86 deletions

View File

@@ -6,12 +6,13 @@ A new header is inserted each time a *tag* is created.
## Next release
- The Android support libraries (gltfio and filament-utils) now use dynamic linking.
- Screen-space refraction is now supported.
- Removed depth-prepass related APIs. (⚠ API Change)
- gltfio: add asynchronous API to ResourceLoader.
- gltfio: generate normals for flat-shaded models that do not have normals.
- Material instances now allow dynamic depth testing and other rasterization state.
- Support for Bloom as a post-process effect.
- Unlit materials now apply emissive in the same way as lit materials.
- Screen-space refraction is now supported.
- Support for HDR Bloom as a post-process effect.
- Added Java bindings for geometry::SurfaceOrientation.
- Fixed bug rendering transparent objects with Metal backend.
- Fixed crash on macOS Catalina when rendering with Metal backend.

View File

@@ -299,6 +299,89 @@ static void setup(Engine* engine, View*, Scene* scene) {
g_params.bloomOptions.dirt = FilamentApp::get().getDirtTexture();
}
static filament::MaterialInstance* updateInstances(
SandboxParameters& params, filament::Engine& engine) {
int material = params.currentMaterialModel;
if (material == MATERIAL_MODEL_LIT) {
if (params.currentBlending == BLENDING_TRANSPARENT) material = MATERIAL_TRANSPARENT;
if (params.currentBlending == BLENDING_FADE) material = MATERIAL_FADE;
if (params.ssr) {
if (params.currentBlending == BLENDING_THIN_REFRACTION) material = MATERIAL_THIN_SS_REFRACTION;
if (params.currentBlending == BLENDING_SOLID_REFRACTION) material = MATERIAL_SOLID_SS_REFRACTION;
} else {
if (params.currentBlending == BLENDING_THIN_REFRACTION) material = MATERIAL_THIN_REFRACTION;
if (params.currentBlending == BLENDING_SOLID_REFRACTION) material = MATERIAL_SOLID_REFRACTION;
}
}
bool hasRefraction = params.currentBlending == BLENDING_THIN_REFRACTION ||
params.currentBlending == BLENDING_SOLID_REFRACTION;
MaterialInstance* materialInstance = params.materialInstance[material];
materialInstance->setParameter("baseColor", RgbType::sRGB, params.color);
if (params.currentMaterialModel != MATERIAL_MODEL_CLOTH) {
math::float4 emissive(Color::toLinear(params.emissiveColor), params.emissiveEC);
materialInstance->setParameter("emissive", emissive);
}
if (params.currentMaterialModel == MATERIAL_MODEL_LIT) {
materialInstance->setParameter("roughness", params.roughness);
materialInstance->setParameter("metallic", params.metallic);
if (!hasRefraction) {
materialInstance->setParameter("reflectance", params.reflectance);
}
materialInstance->setParameter("clearCoat", params.clearCoat);
materialInstance->setParameter("clearCoatRoughness", params.clearCoatRoughness);
materialInstance->setParameter("anisotropy", params.anisotropy);
if (params.currentBlending != BLENDING_OPAQUE) {
materialInstance->setParameter("alpha", params.alpha);
}
if (hasRefraction) {
math::float3 color = Color::toLinear(params.transmittanceColor);
materialInstance->setParameter("absorption",
Color::absorptionAtDistance(color, params.distance));
materialInstance->setParameter("ior", params.ior);
materialInstance->setParameter("transmission", params.transmission);
materialInstance->setParameter("thickness", params.thickness);
}
}
if (params.currentMaterialModel == MATERIAL_MODEL_SPECGLOSS) {
materialInstance->setParameter("glossiness", params.glossiness);
materialInstance->setParameter("specularColor", params.specularColor);
materialInstance->setParameter("reflectance", params.reflectance);
materialInstance->setParameter("clearCoat", params.clearCoat);
materialInstance->setParameter("clearCoatRoughness", params.clearCoatRoughness);
materialInstance->setParameter("anisotropy", params.anisotropy);
}
if (params.currentMaterialModel == MATERIAL_MODEL_SUBSURFACE) {
materialInstance->setParameter("roughness", params.roughness);
materialInstance->setParameter("metallic", params.metallic);
materialInstance->setParameter("reflectance", params.reflectance);
materialInstance->setParameter("thickness", params.thickness);
materialInstance->setParameter("subsurfacePower", params.subsurfacePower);
materialInstance->setParameter("subsurfaceColor", RgbType::sRGB, params.subsurfaceColor);
}
if (params.currentMaterialModel == MATERIAL_MODEL_CLOTH) {
materialInstance->setParameter("roughness", params.roughness);
materialInstance->setParameter("sheenColor", RgbType::sRGB, params.sheenColor);
materialInstance->setParameter("subsurfaceColor", RgbType::sRGB, params.subsurfaceColor);
}
if (params.currentMaterialModel != MATERIAL_MODEL_UNLIT) {
materialInstance->setSpecularAntiAliasingVariance(params.specularAntiAliasingVariance);
materialInstance->setSpecularAntiAliasingThreshold(params.specularAntiAliasingThreshold);
}
return materialInstance;
}
static void gui(filament::Engine* engine, filament::View*) {
auto& params = g_params;
ImGui::SetNextWindowSize(ImVec2(0.0f, 0.0f));
@@ -368,7 +451,7 @@ static void gui(filament::Engine* engine, filament::View*) {
}
ImGui::ColorEdit3("emissiveColor", &params.emissiveColor.r);
ImGui::SliderFloat("emissiveEC", &params.emissiveEC, 0.0f, 6.0f);
ImGui::SliderFloat("emissiveEC", &params.emissiveEC, 0.0f, 12.0f);
}
if (ImGui::CollapsingHeader("Shading AA")) {

View File

@@ -192,84 +192,4 @@ inline void createInstances(SandboxParameters& params, filament::Engine& engine)
.build(engine, params.light);
}
inline filament::MaterialInstance* updateInstances(SandboxParameters& params,
filament::Engine& engine) {
using namespace filament;
int material = params.currentMaterialModel;
if (material == MATERIAL_MODEL_LIT) {
if (params.currentBlending == BLENDING_TRANSPARENT) material = MATERIAL_TRANSPARENT;
if (params.currentBlending == BLENDING_FADE) material = MATERIAL_FADE;
if (params.ssr) {
if (params.currentBlending == BLENDING_THIN_REFRACTION) material = MATERIAL_THIN_SS_REFRACTION;
if (params.currentBlending == BLENDING_SOLID_REFRACTION) material = MATERIAL_SOLID_SS_REFRACTION;
} else {
if (params.currentBlending == BLENDING_THIN_REFRACTION) material = MATERIAL_THIN_REFRACTION;
if (params.currentBlending == BLENDING_SOLID_REFRACTION) material = MATERIAL_SOLID_REFRACTION;
}
}
bool hasRefraction = params.currentBlending == BLENDING_THIN_REFRACTION ||
params.currentBlending == BLENDING_SOLID_REFRACTION;
MaterialInstance* materialInstance = params.materialInstance[material];
materialInstance->setParameter("baseColor", RgbType::sRGB, params.color);
math::float4 emissive(Color::toLinear(params.emissiveColor), params.emissiveEC);
materialInstance->setParameter("emissive", emissive);
if (params.currentMaterialModel == MATERIAL_MODEL_LIT) {
materialInstance->setParameter("roughness", params.roughness);
materialInstance->setParameter("metallic", params.metallic);
if (!hasRefraction) {
materialInstance->setParameter("reflectance", params.reflectance);
}
materialInstance->setParameter("clearCoat", params.clearCoat);
materialInstance->setParameter("clearCoatRoughness", params.clearCoatRoughness);
materialInstance->setParameter("anisotropy", params.anisotropy);
if (params.currentBlending != BLENDING_OPAQUE) {
materialInstance->setParameter("alpha", params.alpha);
}
if (hasRefraction) {
math::float3 color = Color::toLinear(params.transmittanceColor);
materialInstance->setParameter("absorption",
Color::absorptionAtDistance(color, params.distance));
materialInstance->setParameter("ior", params.ior);
materialInstance->setParameter("transmission", params.transmission);
materialInstance->setParameter("thickness", params.thickness);
}
}
if (params.currentMaterialModel == MATERIAL_MODEL_SPECGLOSS) {
materialInstance->setParameter("glossiness", params.glossiness);
materialInstance->setParameter("specularColor", params.specularColor);
materialInstance->setParameter("reflectance", params.reflectance);
materialInstance->setParameter("clearCoat", params.clearCoat);
materialInstance->setParameter("clearCoatRoughness", params.clearCoatRoughness);
materialInstance->setParameter("anisotropy", params.anisotropy);
}
if (params.currentMaterialModel == MATERIAL_MODEL_SUBSURFACE) {
materialInstance->setParameter("roughness", params.roughness);
materialInstance->setParameter("metallic", params.metallic);
materialInstance->setParameter("reflectance", params.reflectance);
materialInstance->setParameter("thickness", params.thickness);
materialInstance->setParameter("subsurfacePower", params.subsurfacePower);
materialInstance->setParameter("subsurfaceColor", RgbType::sRGB, params.subsurfaceColor);
}
if (params.currentMaterialModel == MATERIAL_MODEL_CLOTH) {
materialInstance->setParameter("roughness", params.roughness);
materialInstance->setParameter("sheenColor", RgbType::sRGB, params.sheenColor);
materialInstance->setParameter("subsurfaceColor", RgbType::sRGB, params.subsurfaceColor);
}
if (params.currentMaterialModel != MATERIAL_MODEL_UNLIT) {
materialInstance->setSpecularAntiAliasingVariance(params.specularAntiAliasingVariance);
materialInstance->setSpecularAntiAliasingThreshold(params.specularAntiAliasingThreshold);
}
return materialInstance;
}
#endif // TNT_FILAMENT_SAMPLES_MATERIAL_SANDBOX_H

View File

@@ -1,3 +1,14 @@
void addEmissive(const MaterialInputs material, inout vec4 color) {
#if defined(MATERIAL_HAS_EMISSIVE)
// The emissive property applies independently of the shading model
// It is defined as a color + exposure compensation
highp vec4 emissive = material.emissive;
highp float attenuation = computePreExposedIntensity(
pow(2.0, frameUniforms.ev100 + emissive.w - 3.0), frameUniforms.exposure);
color.rgb += emissive.rgb * attenuation;
#endif
}
/**
* Evaluates unlit materials. In this lighting model, only the base color and
* emissive properties are taken into account:
@@ -21,9 +32,7 @@ vec4 evaluateMaterial(const MaterialInputs material) {
}
#endif
#if defined(MATERIAL_HAS_EMISSIVE)
color.rgb += material.emissive.rgb;
#endif
addEmissive(material, color);
#if defined(HAS_DIRECTIONAL_LIGHTING)
#if defined(HAS_SHADOWING)