Skip to content
Snippets Groups Projects
Commit 8d5f01e5 authored by Michael Migliore's avatar Michael Migliore
Browse files

PBR Neutral tone mapper

parent d5e4f891
No related branches found
No related tags found
No related merge requests found
## PBR Neutral tone mapping
A new alternative tone mapping method has been added to `vtkToneMappingPass`.
It's based on the reference implementation of Khronos PBR Neutral.
......@@ -14,6 +14,7 @@
#include "vtkOpaquePass.h"
#include "vtkOpenGLRenderer.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRenderPassCollection.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
......@@ -24,7 +25,7 @@
int TestToneMappingPass(int argc, char* argv[])
{
vtkNew<vtkRenderWindow> renWin;
renWin->SetSize(400, 800);
renWin->SetSize(900, 900);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
......@@ -33,8 +34,7 @@ int TestToneMappingPass(int argc, char* argv[])
sphere->SetThetaResolution(20);
sphere->SetPhiResolution(20);
double y = 0.0;
for (int i = 0; i < 8; i++)
for (int i = 0; i < 9; i++)
{
vtkNew<vtkRenderer> renderer;
......@@ -84,19 +84,20 @@ int TestToneMappingPass(int argc, char* argv[])
toneMappingP->SetGenericFilmicUncharted2Presets();
toneMappingP->SetUseACES(false);
break;
case 8:
toneMappingP->SetToneMappingType(vtkToneMappingPass::NeutralPBR);
break;
}
toneMappingP->SetDelegatePass(cameraP);
vtkOpenGLRenderer::SafeDownCast(renderer)->SetPass(toneMappingP);
double x = 0.5 * (i & 1);
if (i)
{
y += 1 / 4.f * !(i & 1);
}
double oneThird = 1.0 / 3.0;
double x = (i % 3) * oneThird;
double y = (i / 3) * oneThird;
renderer->SetViewport(x, y, x + 0.5, y + 1 / 4.f);
renderer->SetBackground(0.5, 0.5, 0.5);
renderer->SetViewport(x, y, x + oneThird, y + oneThird);
renWin->AddRenderer(renderer);
// add one light in front of the object
......@@ -141,6 +142,7 @@ int TestToneMappingPass(int argc, char* argv[])
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->SetInterpolationToPBR();
renderer->AddActor(actor);
renderer->ResetCamera();
......
4595f98960d268ccf75b17b50761f5559aab38e975f0c74fb61687ea1ca0ef8d1260661bb317d074dc8824f3d4e8aee0378d3dd538c038bcf06a59bdde042ad3
af28d7481039a61d908c16db917bf1655c3b8931b2ab771b7f6dcd39825efc6c3ee5072b52301a4d6c1795597f1305eccee1556afff45e71b681eca50ce40418
......@@ -188,6 +188,25 @@ void vtkToneMappingPass::Render(const vtkRenderState* s)
" toned = clamp(toned, vec3(0.f), vec3(1.f));\n"
"//VTK::FSQ::Impl");
break;
case NeutralPBR:
// adapted from Khronos reference implementation:
// https://github.com/KhronosGroup/ToneMapping/blob/main/PBR_Neutral/pbrNeutral.glsl
vtkShaderProgram::Substitute(FSSource, "//VTK::FSQ::Impl",
" const float startCompression = 0.8 - 0.04;\n"
" const float desaturation = 0.15;\n"
" float x = min(color.r, min(color.g, color.b));\n"
" float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n"
" vec3 toned = color - vec3(offset);\n"
" float peak = max(toned.r, max(toned.g, toned.b));\n"
" if (peak >= startCompression)\n"
" {\n"
" const float d = 1. - startCompression;\n"
" float newPeak = 1. - d * d / (peak + d - startCompression);\n"
" toned *= newPeak / peak;\n"
" float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);\n"
" toned = mix(toned, newPeak * vec3(1, 1, 1), g);\n"
" }\n"
"//VTK::FSQ::Impl");
}
// Recorrect gamma and output
......
......@@ -68,7 +68,8 @@ public:
Clamp = 0,
Reinhard = 1,
Exponential = 2,
GenericFilmic = 3
GenericFilmic = 3,
NeutralPBR = 4
};
///@{
......@@ -76,7 +77,7 @@ public:
* Get/Set the tone mapping type.
* Default is GenericFilmic
*/
vtkSetClampMacro(ToneMappingType, int, 0, 3);
vtkSetClampMacro(ToneMappingType, int, 0, 4);
vtkGetMacro(ToneMappingType, int);
///@}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment