Skip to content

Commit

Permalink
Improvements to advanced viewer options (AcademySoftwareFoundation#1093)
Browse files Browse the repository at this point in the history
- Simplify the Viewing Options section, and move it to the top for quick access.
- Create dedicated sections for Scene Options and Asset Loading Options.
- Fix an edge case with the Split Direct Light option.
  • Loading branch information
jstone-lucasfilm authored Oct 5, 2022
1 parent 39dfdd5 commit a4de7b3
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 156 deletions.
265 changes: 120 additions & 145 deletions source/MaterialXView/Viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,13 @@ Viewer::Viewer(const std::string& materialFilename,
_genContextMdl(mx::MdlShaderGenerator::create()),
#endif
_unitRegistry(mx::UnitConverterRegistry::create()),
_drawEnvironment(false),
_outlineSelection(false),
_renderTransparency(true),
_renderDoubleSided(true),
_splitByUdims(true),
_mergeMaterials(false),
_showAllInputs(false),
_renderTransparency(true),
_renderDoubleSided(true),
_outlineSelection(false),
_drawEnvironment(false),
_targetShader("standard_surface"),
_captureRequested(false),
_exitRequested(false),
Expand Down Expand Up @@ -436,7 +436,7 @@ void Viewer::loadEnvironmentLight()
}

// Look for an irradiance map using an expected filename convention.
mx::ImagePtr envIrradianceMap;
mx::ImagePtr envIrradianceMap = _imageHandler->getInvalidImage();
if (!_normalizeEnvironment && !_splitDirectLight)
{
mx::FilePath envIrradiancePath = _envRadianceFilename.getParentPath() / IRRADIANCE_MAP_FOLDER / _envRadianceFilename.getBaseName();
Expand Down Expand Up @@ -688,62 +688,90 @@ void Viewer::createAdvancedSettings(Widget* parent)
ng::Widget* advancedPopup = new ng::Widget(scrollPanel);
advancedPopup->set_layout(new ng::GroupLayout(13));

ng::Label* meshLabel = new ng::Label(advancedPopup, "Mesh Options");
meshLabel->set_font_size(20);
meshLabel->set_font("sans-bold");
ng::Label* viewLabel = new ng::Label(advancedPopup, "Viewing Options");
viewLabel->set_font_size(20);
viewLabel->set_font("sans-bold");

ng::CheckBox* splitUdimsBox = new ng::CheckBox(advancedPopup, "Split By UDIMs");
splitUdimsBox->set_checked(_splitByUdims);
splitUdimsBox->set_callback([this](bool enable)
ng::CheckBox* drawEnvironmentBox = new ng::CheckBox(advancedPopup, "Draw Environment");
drawEnvironmentBox->set_checked(_drawEnvironment);
drawEnvironmentBox->set_callback([this](bool enable)
{
_splitByUdims = enable;
_drawEnvironment = enable;
});

ng::Label* materialLabel = new ng::Label(advancedPopup, "Material Options");
materialLabel->set_font_size(20);
materialLabel->set_font("sans-bold");
ng::CheckBox* outlineSelectedGeometryBox = new ng::CheckBox(advancedPopup, "Outline Selected Geometry");
outlineSelectedGeometryBox->set_checked(_outlineSelection);
outlineSelectedGeometryBox->set_callback([this](bool enable)
{
_outlineSelection = enable;
});

ng::CheckBox* mergeMaterialsBox = new ng::CheckBox(advancedPopup, "Merge Materials");
mergeMaterialsBox->set_checked(_mergeMaterials);
mergeMaterialsBox->set_callback([this](bool enable)
ng::Label* renderLabel = new ng::Label(advancedPopup, "Render Options");
renderLabel->set_font_size(20);
renderLabel->set_font("sans-bold");

ng::CheckBox* transparencyBox = new ng::CheckBox(advancedPopup, "Render Transparency");
transparencyBox->set_checked(_renderTransparency);
transparencyBox->set_callback([this](bool enable)
{
_mergeMaterials = enable;
_renderTransparency = enable;
});

ng::CheckBox* showInputsBox = new ng::CheckBox(advancedPopup, "Show All Inputs");
showInputsBox->set_checked(_showAllInputs);
showInputsBox->set_callback([this](bool enable)
ng::CheckBox* doubleSidedBox = new ng::CheckBox(advancedPopup, "Render Double-Sided");
doubleSidedBox->set_checked(_renderDoubleSided);
doubleSidedBox->set_callback([this](bool enable)
{
_showAllInputs = enable;
});
_renderDoubleSided = enable;
});

Widget* unitGroup = new Widget(advancedPopup);
unitGroup->set_layout(new ng::BoxLayout(ng::Orientation::Horizontal));
new ng::Label(unitGroup, "Distance Unit:");
ng::ComboBox* distanceUnitBox = new ng::ComboBox(unitGroup, _distanceUnitOptions);
distanceUnitBox->set_fixed_size(ng::Vector2i(100, 20));
distanceUnitBox->set_chevron_icon(-1);
if (_distanceUnitConverter)
ng::CheckBox* importanceSampleBox = new ng::CheckBox(advancedPopup, "Environment FIS");
importanceSampleBox->set_checked(_genContext.getOptions().hwSpecularEnvironmentMethod == mx::SPECULAR_ENVIRONMENT_FIS);
importanceSampleBox->set_callback([this](bool enable)
{
distanceUnitBox->set_selected_index(_distanceUnitConverter->getUnitAsInteger("meter"));
}
distanceUnitBox->set_callback([this](int index)
_genContext.getOptions().hwSpecularEnvironmentMethod = enable ? mx::SPECULAR_ENVIRONMENT_FIS : mx::SPECULAR_ENVIRONMENT_PREFILTER;
_genContextEssl.getOptions().hwSpecularEnvironmentMethod = _genContext.getOptions().hwSpecularEnvironmentMethod;
reloadShaders();
});

ng::CheckBox* refractionBox = new ng::CheckBox(advancedPopup, "Transmission Refraction");
refractionBox->set_checked(_genContext.getOptions().hwTransmissionRenderMethod == mx::TRANSMISSION_REFRACTION);
refractionBox->set_callback([this](bool enable)
{
_genContext.getOptions().hwTransmissionRenderMethod = enable ? mx::TRANSMISSION_REFRACTION : mx::TRANSMISSION_OPACITY;
_genContextEssl.getOptions().hwTransmissionRenderMethod = _genContext.getOptions().hwTransmissionRenderMethod;
reloadShaders();
});

Widget* albedoGroup = new Widget(advancedPopup);
albedoGroup->set_layout(new ng::BoxLayout(ng::Orientation::Horizontal));
new ng::Label(albedoGroup, "Albedo Method:");
mx::StringVec albedoOptions = { "Analytic", "Table", "MC" };
ng::ComboBox* albedoBox = new ng::ComboBox(albedoGroup, albedoOptions);
albedoBox->set_chevron_icon(-1);
albedoBox->set_selected_index((int) _genContext.getOptions().hwDirectionalAlbedoMethod );
albedoBox->set_callback([this](int index)
{
_genContext.getOptions().hwDirectionalAlbedoMethod = (mx::HwDirectionalAlbedoMethod) index;
reloadShaders();
updateAlbedoTable();
});

Widget* sampleGroup = new Widget(advancedPopup);
sampleGroup->set_layout(new ng::BoxLayout(ng::Orientation::Horizontal));
new ng::Label(sampleGroup, "Environment Samples:");
mx::StringVec sampleOptions;
for (int i = MIN_ENV_SAMPLE_COUNT; i <= MAX_ENV_SAMPLE_COUNT; i *= 4)
{
m_process_events = false;
_genContext.getOptions().targetDistanceUnit = _distanceUnitOptions[index];
_genContextEssl.getOptions().targetDistanceUnit = _distanceUnitOptions[index];
#if MATERIALX_BUILD_GEN_OSL
_genContextOsl.getOptions().targetDistanceUnit = _distanceUnitOptions[index];
#endif
#if MATERIALX_BUILD_GEN_MDL
_genContextMdl.getOptions().targetDistanceUnit = _distanceUnitOptions[index];
#endif
for (MaterialPtr material : _materials)
{
material->bindShader();
material->bindUnits(_unitRegistry, _genContext);
}
sampleOptions.push_back(std::to_string(i));
m_process_events = true;
}
ng::ComboBox* sampleBox = new ng::ComboBox(sampleGroup, sampleOptions);
sampleBox->set_chevron_icon(-1);
sampleBox->set_selected_index((int)std::log2(_lightHandler->getEnvSampleCount() / MIN_ENV_SAMPLE_COUNT) / 2);
sampleBox->set_callback([this](int index)
{
_lightHandler->setEnvSampleCount(MIN_ENV_SAMPLE_COUNT * (int) std::pow(4, index));
});

ng::Label* lightingLabel = new ng::Label(advancedPopup, "Lighting Options");
Expand All @@ -764,20 +792,6 @@ void Viewer::createAdvancedSettings(Widget* parent)
_lightHandler->setIndirectLighting(enable);
});

ng::CheckBox* normalizeEnvironmentBox = new ng::CheckBox(advancedPopup, "Normalize Environment");
normalizeEnvironmentBox->set_checked(_normalizeEnvironment);
normalizeEnvironmentBox->set_callback([this](bool enable)
{
_normalizeEnvironment = enable;
});

ng::CheckBox* splitDirectLightBox = new ng::CheckBox(advancedPopup, "Split Direct Light");
splitDirectLightBox->set_checked(_splitDirectLight);
splitDirectLightBox->set_callback([this](bool enable)
{
_splitDirectLight = enable;
});

ng::Widget* lightRotationRow = new ng::Widget(advancedPopup);
lightRotationRow->set_layout(new ng::BoxLayout(ng::Orientation::Horizontal));
mx::UIProperties ui;
Expand Down Expand Up @@ -820,109 +834,70 @@ void Viewer::createAdvancedSettings(Widget* parent)
});
ambientOcclusionGainBox->set_editable(true);

ng::Label* renderLabel = new ng::Label(advancedPopup, "Render Options");
renderLabel->set_font_size(20);
renderLabel->set_font("sans-bold");

ng::CheckBox* transparencyBox = new ng::CheckBox(advancedPopup, "Render Transparency");
transparencyBox->set_checked(_renderTransparency);
transparencyBox->set_callback([this](bool enable)
{
_renderTransparency = enable;
});

ng::CheckBox* doubleSidedBox = new ng::CheckBox(advancedPopup, "Render Double-Sided");
doubleSidedBox->set_checked(_renderDoubleSided);
doubleSidedBox->set_callback([this](bool enable)
{
_renderDoubleSided = enable;
});

ng::CheckBox* importanceSampleBox = new ng::CheckBox(advancedPopup, "Environment FIS");
importanceSampleBox->set_checked(_genContext.getOptions().hwSpecularEnvironmentMethod == mx::SPECULAR_ENVIRONMENT_FIS);
importanceSampleBox->set_callback([this](bool enable)
{
_genContext.getOptions().hwSpecularEnvironmentMethod = enable ? mx::SPECULAR_ENVIRONMENT_FIS : mx::SPECULAR_ENVIRONMENT_PREFILTER;
_genContextEssl.getOptions().hwSpecularEnvironmentMethod = _genContext.getOptions().hwSpecularEnvironmentMethod;
reloadShaders();
});

ng::CheckBox* refractionBox = new ng::CheckBox(advancedPopup, "Transmission Refraction");
refractionBox->set_checked(_genContext.getOptions().hwTransmissionRenderMethod == mx::TRANSMISSION_REFRACTION);
refractionBox->set_callback([this](bool enable)
{
_genContext.getOptions().hwTransmissionRenderMethod = enable ? mx::TRANSMISSION_REFRACTION : mx::TRANSMISSION_OPACITY;
_genContextEssl.getOptions().hwTransmissionRenderMethod = _genContext.getOptions().hwTransmissionRenderMethod;
reloadShaders();
});
ng::Label* sceneLabel = new ng::Label(advancedPopup, "Scene Options");
sceneLabel->set_font_size(20);
sceneLabel->set_font("sans-bold");

Widget* albedoGroup = new Widget(advancedPopup);
albedoGroup->set_layout(new ng::BoxLayout(ng::Orientation::Horizontal));
new ng::Label(albedoGroup, "Albedo Method:");
mx::StringVec albedoOptions = { "Analytic", "Table", "MC" };
ng::ComboBox* albedoBox = new ng::ComboBox(albedoGroup, albedoOptions);
albedoBox->set_chevron_icon(-1);
albedoBox->set_selected_index((int) _genContext.getOptions().hwDirectionalAlbedoMethod );
albedoBox->set_callback([this](int index)
Widget* unitGroup = new Widget(advancedPopup);
unitGroup->set_layout(new ng::BoxLayout(ng::Orientation::Horizontal));
new ng::Label(unitGroup, "Distance Unit:");
ng::ComboBox* distanceUnitBox = new ng::ComboBox(unitGroup, _distanceUnitOptions);
distanceUnitBox->set_fixed_size(ng::Vector2i(100, 20));
distanceUnitBox->set_chevron_icon(-1);
if (_distanceUnitConverter)
{
_genContext.getOptions().hwDirectionalAlbedoMethod = (mx::HwDirectionalAlbedoMethod) index;
reloadShaders();
updateAlbedoTable();
});

Widget* sampleGroup = new Widget(advancedPopup);
sampleGroup->set_layout(new ng::BoxLayout(ng::Orientation::Horizontal));
new ng::Label(sampleGroup, "Environment Samples:");
mx::StringVec sampleOptions;
for (int i = MIN_ENV_SAMPLE_COUNT; i <= MAX_ENV_SAMPLE_COUNT; i *= 4)
distanceUnitBox->set_selected_index(_distanceUnitConverter->getUnitAsInteger("meter"));
}
distanceUnitBox->set_callback([this](int index)
{
m_process_events = false;
sampleOptions.push_back(std::to_string(i));
_genContext.getOptions().targetDistanceUnit = _distanceUnitOptions[index];
_genContextEssl.getOptions().targetDistanceUnit = _distanceUnitOptions[index];
#if MATERIALX_BUILD_GEN_OSL
_genContextOsl.getOptions().targetDistanceUnit = _distanceUnitOptions[index];
#endif
#if MATERIALX_BUILD_GEN_MDL
_genContextMdl.getOptions().targetDistanceUnit = _distanceUnitOptions[index];
#endif
for (MaterialPtr material : _materials)
{
material->bindShader();
material->bindUnits(_unitRegistry, _genContext);
}
m_process_events = true;
}
ng::ComboBox* sampleBox = new ng::ComboBox(sampleGroup, sampleOptions);
sampleBox->set_chevron_icon(-1);
sampleBox->set_selected_index((int)std::log2(_lightHandler->getEnvSampleCount() / MIN_ENV_SAMPLE_COUNT) / 2);
sampleBox->set_callback([this](int index)
{
_lightHandler->setEnvSampleCount(MIN_ENV_SAMPLE_COUNT * (int) std::pow(4, index));
});

ng::Label* viewLabel = new ng::Label(advancedPopup, "Viewing Options");
viewLabel->set_font_size(20);
viewLabel->set_font("sans-bold");
ng::Label* loadingLabel = new ng::Label(advancedPopup, "Asset Loading Options");
loadingLabel->set_font_size(20);
loadingLabel->set_font("sans-bold");

ng::CheckBox* outlineSelectedGeometryBox = new ng::CheckBox(advancedPopup, "Outline Selected Geometry");
outlineSelectedGeometryBox->set_checked(_outlineSelection);
outlineSelectedGeometryBox->set_callback([this](bool enable)
ng::CheckBox* splitUdimsBox = new ng::CheckBox(advancedPopup, "Split By UDIMs");
splitUdimsBox->set_checked(_splitByUdims);
splitUdimsBox->set_callback([this](bool enable)
{
_outlineSelection = enable;
_splitByUdims = enable;
});

ng::CheckBox* drawEnvironmentBox = new ng::CheckBox(advancedPopup, "Render Environment");
drawEnvironmentBox->set_checked(_drawEnvironment);
drawEnvironmentBox->set_callback([this](bool enable)
ng::CheckBox* mergeMaterialsBox = new ng::CheckBox(advancedPopup, "Merge Materials");
mergeMaterialsBox->set_checked(_mergeMaterials);
mergeMaterialsBox->set_callback([this](bool enable)
{
_drawEnvironment = enable;
_mergeMaterials = enable;
});

ng::CheckBox* turntableEnabledCheckBox = new ng::CheckBox(advancedPopup, "Enable Turntable");
turntableEnabledCheckBox->set_checked(_turntableEnabled);
turntableEnabledCheckBox->set_callback([this](bool enable)
ng::CheckBox* showInputsBox = new ng::CheckBox(advancedPopup, "Show All Inputs");
showInputsBox->set_checked(_showAllInputs);
showInputsBox->set_callback([this](bool enable)
{
toggleTurntable(enable);
_showAllInputs = enable;
});

ng::Widget* meshTurntableRow = new ng::Widget(advancedPopup);
meshTurntableRow->set_layout(new ng::BoxLayout(ng::Orientation::Horizontal));
ui.uiMin = mx::Value::createValue(2);
ui.uiMax = mx::Value::createValue(360);
ng::IntBox<int>* meshTurntableBox = createIntWidget(meshTurntableRow, "Turntable Steps:",
_turntableSteps, &ui, [this](int value)
ng::CheckBox* splitDirectLightBox = new ng::CheckBox(advancedPopup, "Split Direct Light");
splitDirectLightBox->set_checked(_splitDirectLight);
splitDirectLightBox->set_callback([this](bool enable)
{
_turntableSteps = std::clamp(value, 2, 360);
_splitDirectLight = enable;
});
meshTurntableBox->set_editable(true);

ng::Label* translationLabel = new ng::Label(advancedPopup, "Translation Options (T)");
translationLabel->set_font_size(20);
Expand Down
22 changes: 11 additions & 11 deletions source/MaterialXView/Viewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,22 +375,22 @@ class Viewer : public ng::Screen
// Unit registry
mx::UnitConverterRegistryPtr _unitRegistry;

// Mesh options
bool _splitByUdims;
// Viewing options
bool _drawEnvironment;
bool _outlineSelection;

// Material options
bool _mergeMaterials;
bool _showAllInputs;
// Render options
bool _renderTransparency;
bool _renderDoubleSided;

// Unit options
// Scene options
mx::StringVec _distanceUnitOptions;
mx::LinearUnitConverterPtr _distanceUnitConverter;

// Render options
bool _renderTransparency;
bool _renderDoubleSided;
bool _outlineSelection;
bool _drawEnvironment;
// Asset loading options
bool _splitByUdims;
bool _mergeMaterials;
bool _showAllInputs;

// Shader translation
std::string _targetShader;
Expand Down

0 comments on commit a4de7b3

Please sign in to comment.