Skip to content

Commit

Permalink
Add Color::absorptionAtDistance() to compute absorption for refractio…
Browse files Browse the repository at this point in the history
…n. (google#1964)

Specifying the transmittance color at a specific distance is more
user-friendly than specifying absorption coefficients directly.
  • Loading branch information
romainguy authored Dec 11, 2019
1 parent 28f0536 commit 8e00df1
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 5 deletions.
10 changes: 10 additions & 0 deletions assets/models/prism/prism.mtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Blender MTL File: 'None'
# Material Count: 1

newmtl None
Ns 500
Ka 0.8 0.8 0.8
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2
34 changes: 34 additions & 0 deletions assets/models/prism/prism.obj
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Blender v2.81 (sub 16) OBJ File: ''
# www.blender.org
mtllib prism.mtl
o Cube_Cube.001
v 0.500000 0.000000 0.325000
v 0.500000 1.000000 -0.000000
v -0.500000 0.000000 0.325000
v -0.500000 1.000000 0.000000
v 0.500000 0.000000 -0.325000
v -0.500000 0.000000 -0.325000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.375000 0.500000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
vn 0.0000 0.3091 0.9510
vn -1.0000 0.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn -0.0000 0.3091 -0.9510
usemtl None
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/4/2 4/3/2 6/5/2
f 5/6/3 2/7/3 1/8/3
f 3/9/4 6/5/4 5/6/4 1/10/4
f 4/11/5 2/12/5 5/6/5 6/5/5
14 changes: 14 additions & 0 deletions filament/include/filament/Color.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,20 @@ class UTILS_PUBLIC Color {
*/
static LinearColor illuminantD(float K);

/**
* computes the Beer-Lambert absorption coefficients from the specified
* transmittance color and distance. The computed absorption will guarantee
* the white light will become the specified color at the specified distance.
* The output of this function can be used as the absorption parameter of
* materials that use refraction.
*
* @param color the desired linear RGB color in sRGB space
* @param distance the distance at which white light should become the specified color
*
* @return absorption coefficients for the Beer-Lambert law
*/
static math::float3 absorptionAtDistance(LinearColor const& color, float distance);

private:
static math::float3 sRGBToLinear(math::float3 color) noexcept;
static math::float3 linearToSRGB(math::float3 color) noexcept;
Expand Down
6 changes: 6 additions & 0 deletions filament/src/Color.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

#include <math/mat3.h>

#include <cmath>

using namespace filament::math;

namespace filament {
Expand Down Expand Up @@ -77,4 +79,8 @@ LinearColor Color::illuminantD(float K) {
return saturate(linear / std::max(1e-5f, max(linear)));
}

LinearColor Color::absorptionAtDistance(LinearColor const& color, float distance) {
return -log(clamp(color, 1e-5f, 1.0f)) / std::max(1e-5f, distance);
}

} // namespace filament
7 changes: 7 additions & 0 deletions libs/math/include/math/TVecHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,13 @@ class TVecFunctions {
return v;
}

friend inline VECTOR<T> MATH_PURE log(VECTOR<T> v) {
for (size_t i = 0; i < v.size(); i++) {
v[i] = std::log(v[i]);
}
return v;
}

friend inline constexpr VECTOR<T> MATH_PURE saturate(const VECTOR<T>& lv) {
return clamp(lv, T(0), T(1));
}
Expand Down
3 changes: 2 additions & 1 deletion samples/material_sandbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,8 @@ static void gui(filament::Engine* engine, filament::View*) {
ImGui::SliderFloat("ior", &params.ior, 1.0f, 3.0f);
ImGui::SliderFloat("transmission", &params.transmission, 0.0f, 1.0f);
ImGui::SliderFloat("thickness", &params.thickness, 0.0f, 1.0f);
ImGui::ColorEdit3("absorption", &params.absorption.r);
ImGui::ColorEdit3("transmittance", &params.transmittanceColor.r);
ImGui::SliderFloat("distance", &params.distance, 0.0f, 4.0f);
}
}
}
Expand Down
10 changes: 6 additions & 4 deletions samples/material_sandbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ struct SandboxParameters {
float specularAntiAliasingVariance = 0.0f;
float specularAntiAliasingThreshold = 0.0f;
float transmission = 1.0f;
filament::math::float3 absorption = 0.0f;
float distance = 1.0f;
float ior = 1.5;

filament::sRGBColor specularColor = {0.0f, 0.0f, 0.0f};
filament::sRGBColor transmittanceColor = { 1.0f };
filament::sRGBColor specularColor = {0.0f };
filament::sRGBColor subsurfaceColor = {0.0f};
filament::sRGBColor sheenColor = {0.83f, 0.0f, 0.0f};
int currentMaterialModel = MATERIAL_MODEL_LIT;
Expand Down Expand Up @@ -205,7 +205,9 @@ inline filament::MaterialInstance* updateInstances(SandboxParameters& params,
materialInstance->setParameter("alpha", params.alpha);
}
if (hasRefraction) {
materialInstance->setParameter("absorption", params.absorption);
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);
Expand Down

0 comments on commit 8e00df1

Please sign in to comment.