Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add contour shader #128

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions include/polyscope/render/color_maps.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ bool buildColormapSelector(std::string& cm, std::string fieldname = "##colormap_


// ColorMaps currently available below
// Sequential:
// Sequential & perceptually uniform:
// - viridis (CM_VIRIDIS)
// - magma (CM_MAGMA)
// - inferno (CM_INFERNO)
// - plasma (CM_PLASMA)
// - gray (CM_GRAY)
//
// Sequential:
// - blues (CM_BLUES)
// - reds (CM_REDS)
//
Expand All @@ -32,7 +38,6 @@ bool buildColormapSelector(std::string& cm, std::string fieldname = "##colormap_
// - rainbow (CM_RAINBOW)
// - jet (CM_JET)
// - turbo (CM_TURBO)
// - hsv (CM_HSV)
//
// Cyclic:
// - phase (CM_PHASE)
Expand Down
5 changes: 4 additions & 1 deletion include/polyscope/render/colormap_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ namespace render {
// === the default colormaps themselves
// (stored in color_maps.cpp)

extern const std::vector<glm::vec3> CM_GRAY;
extern const std::vector<glm::vec3> CM_VIRIDIS;
extern const std::vector<glm::vec3> CM_PLASMA;
extern const std::vector<glm::vec3> CM_INFERNO;
extern const std::vector<glm::vec3> CM_MAGMA;
extern const std::vector<glm::vec3> CM_COOLWARM;
extern const std::vector<glm::vec3> CM_BLUES;
extern const std::vector<glm::vec3> CM_PIYG;
Expand All @@ -21,7 +25,6 @@ extern const std::vector<glm::vec3> CM_JET;
extern const std::vector<glm::vec3> CM_TURBO;
extern const std::vector<glm::vec3> CM_REDS;
extern const std::vector<glm::vec3> CM_PHASE;
extern const std::vector<glm::vec3> CM_HSV;


} // namespace render
Expand Down
1 change: 1 addition & 0 deletions include/polyscope/render/opengl/shaders/rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extern const ShaderReplacementRule SHADE_CHECKER_VALUE2; // generate a tw
extern const ShaderReplacementRule SHADE_CHECKER_CATEGORY; // generate a checker with colors from a categorical int
extern const ShaderReplacementRule SHADEVALUE_MAG_VALUE2; // generate a shadeValue from the magnitude of shadeValue2
extern const ShaderReplacementRule ISOLINE_STRIPE_VALUECOLOR; // modulate albedoColor based on shadeValue
extern const ShaderReplacementRule CONTOUR_VALUECOLOR; // modulate albedoColor based on shadeValue
extern const ShaderReplacementRule CHECKER_VALUE2COLOR; // modulate albedoColor based on shadeValue2
extern const ShaderReplacementRule SHADE_BASECOLOR; // constant from u_baseColor
extern const ShaderReplacementRule PREMULTIPLY_COLOR;
Expand Down
4 changes: 4 additions & 0 deletions include/polyscope/scalar_quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ class ScalarQuantity {
PersistentValue<bool> isolinesEnabled;
PersistentValue<ScaledValue<float>> isolineWidth;
PersistentValue<float> isolineDarkness;
PersistentValue<bool> contoursEnabled;
PersistentValue<ScaledValue<float>> contourFrequency;
PersistentValue<float> contourThickness;
PersistentValue<float> contourDarkness;
};

} // namespace polyscope
Expand Down
105 changes: 105 additions & 0 deletions include/polyscope/scalar_quantity.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,48 @@ void ScalarQuantity<QuantityT>::buildScalarUI() {

ImGui::PopItemWidth();
}

// Contours
if (contoursEnabled.get()) {
ImGui::PushItemWidth(100);

// Contour frequency
ImGui::TextUnformatted("Contour frequency");
ImGui::SameLine();
if (contourFrequency.get().isRelative()) {
if (ImGui::DragFloat("##Contour frequency relative", contourFrequency.get().getValuePtr(), .001, 0.0001, 1.0, "%.4f",
2.0)) {
contourFrequency.manuallyChanged();
requestRedraw();
}
} else {
float scaleWidth = dataRange.second - dataRange.first;
if (ImGui::DragFloat("##Contour frequency absolute", contourFrequency.get().getValuePtr(), scaleWidth / 1000, 0.,
scaleWidth, "%.4f", 2.0)) {
contourFrequency.manuallyChanged();
requestRedraw();
}
}

// Contour thickness
ImGui::TextUnformatted("Contour thickness");
ImGui::SameLine();
if (ImGui::DragFloat("##Contour thickness", &contourThickness.get(), 0.01, 0., 1.)) {
contourThickness.manuallyChanged();
requestRedraw();
}

// Contour darkness
ImGui::TextUnformatted("Contour darkness");
ImGui::SameLine();
if (ImGui::DragFloat("##Contour darkness", &contourDarkness.get(), 0.01, 0., 1.)) {
contourDarkness.manuallyChanged();
requestRedraw();
}

ImGui::PopItemWidth();
}

}

template <typename QuantityT>
Expand All @@ -195,6 +237,9 @@ std::vector<std::string> ScalarQuantity<QuantityT>::addScalarRules(std::vector<s
if (isolinesEnabled.get()) {
rules.push_back("ISOLINE_STRIPE_VALUECOLOR");
}
if (contoursEnabled.get()) {
rules.push_back("CONTOUR_VALUECOLOR");
}
return rules;
}

Expand All @@ -210,6 +255,12 @@ void ScalarQuantity<QuantityT>::setScalarUniforms(render::ShaderProgram& p) {
p.setUniform("u_modLen", getIsolineWidth());
p.setUniform("u_modDarkness", getIsolineDarkness());
}

if (contoursEnabled.get()) {
p.setUniform("u_modFrequency", getContourFrequency());
p.setUniform("u_modThickness", getContourThickness());
p.setUniform("u_modDarkness", getContourDarkness());
}
}

template <typename QuantityT>
Expand Down Expand Up @@ -319,4 +370,58 @@ bool ScalarQuantity<QuantityT>::getIsolinesEnabled() {
return isolinesEnabled.get();
}

template <typename QuantityT>
QuantityT* ScalarQuantity<QuantityT>::setContourFrequency(double size, bool isRelative) {
contourFrequency = ScaledValue<float>(size, isRelative);
if (!contoursEnabled.get()) {
setContoursEnabled(true);
}
requestRedraw();
return &quantity;
}
template <typename QuantityT>
double ScalarQuantity<QuantityT>::getContourFrequency() {
return contourFrequency.get().asAbsolute();
}

template <typename QuantityT>
QuantityT* ScalarQuantity<QuantityT>::setContourThickness(double val) {
contourThickness = val;
if (!contoursEnabled.get()) {
setContoursEnabled(true);
}
requestRedraw();
return &quantity;
}
template <typename QuantityT>
double ScalarQuantity<QuantityT>::getContourThickness() {
return contourThickness.get();
}

template <typename QuantityT>
QuantityT* ScalarQuantity<QuantityT>::setContourDarkness(double val) {
contourDarkness = val;
if (!contoursEnabled.get()) {
setContoursEnabled(true);
}
requestRedraw();
return &quantity;
}
template <typename QuantityT>
double ScalarQuantity<QuantityT>::getContourDarkness() {
return contourDarkness.get();
}

template <typename QuantityT>
QuantityT* ScalarQuantity<QuantityT>::setContoursEnabled(bool newEnabled) {
contoursEnabled = newEnabled;
quantity.refresh();
requestRedraw();
return &quantity;
}
template <typename QuantityT>
bool ScalarQuantity<QuantityT>::getContoursEnabled() {
return contoursEnabled.get();
}

} // namespace polyscope
15 changes: 12 additions & 3 deletions src/render/color_maps.cpp

Large diffs are not rendered by default.

37 changes: 21 additions & 16 deletions src/render/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,9 @@ ShaderProgram::ShaderProgram(DrawMode dm) : drawMode(dm), uniqueID(render::engin
}
}


Engine::Engine() {}
Engine::~Engine() {}

void Engine::buildEngineGui() {

ImGui::SetNextItemOpen(false, ImGuiCond_FirstUseEver);
ImGui::SetNextTreeNodeOpen(false, ImGuiCond_FirstUseEver);
if (ImGui::TreeNode("Appearance")) {

// == Display
Expand All @@ -296,7 +292,7 @@ void Engine::buildEngineGui() {
ImGui::ColorEdit4("background color", (float*)&view::bgColor, ImGuiColorEditFlags_NoInputs);

// == Transparency
ImGui::SetNextItemOpen(false, ImGuiCond_FirstUseEver);
ImGui::SetNextTreeNodeOpen(false, ImGuiCond_FirstUseEver);
if (ImGui::TreeNode("Transparency")) {

if (ImGui::BeginCombo("Mode", modeName(transparencyMode).c_str())) {
Expand Down Expand Up @@ -336,7 +332,7 @@ void Engine::buildEngineGui() {
// == Ground plane
groundPlane.buildGui();

ImGui::SetNextItemOpen(false, ImGuiCond_FirstUseEver);
ImGui::SetNextTreeNodeOpen(false, ImGuiCond_FirstUseEver);
if (ImGui::TreeNode("Tone Mapping")) {
ImGui::SliderFloat("exposure", &exposure, 0.1, 2.0, "%.3f",
ImGuiSliderFlags_Logarithmic | ImGuiSliderFlags_NoRoundToFormat);
Expand All @@ -348,7 +344,7 @@ void Engine::buildEngineGui() {
}

// == Anti-aliasing
ImGui::SetNextItemOpen(false, ImGuiCond_FirstUseEver);
ImGui::SetNextTreeNodeOpen(false, ImGuiCond_FirstUseEver);
if (ImGui::TreeNode("Anti-Aliasing")) {
if (ImGui::InputInt("SSAA (pretty)", &ssaaFactor, 1)) {
ssaaFactor = std::min(ssaaFactor, 4);
Expand All @@ -360,10 +356,10 @@ void Engine::buildEngineGui() {
}

// == Materials
ImGui::SetNextItemOpen(false, ImGuiCond_FirstUseEver);
ImGui::SetNextTreeNodeOpen(false, ImGuiCond_FirstUseEver);
if (ImGui::TreeNode("Materials")) {

ImGui::SetNextItemOpen(false, ImGuiCond_FirstUseEver);
ImGui::SetNextTreeNodeOpen(false, ImGuiCond_FirstUseEver);
if (ImGui::TreeNode("Load material")) {

size_t buffLen = 512;
Expand Down Expand Up @@ -395,7 +391,7 @@ void Engine::buildEngineGui() {
// == Color maps
if (ImGui::TreeNode("Color Maps")) {

ImGui::SetNextItemOpen(false, ImGuiCond_FirstUseEver);
ImGui::SetNextTreeNodeOpen(false, ImGuiCond_FirstUseEver);
if (ImGui::TreeNode("Load color map")) {

size_t buffLen = 512;
Expand Down Expand Up @@ -910,7 +906,7 @@ void Engine::loadDefaultMaterial(std::string name) {
newMaterial->rules = {"LIGHT_PASSTHRU", "INVERSE_TONEMAP"};
newMaterial->setUniforms = [&](ShaderProgram& p){ setTonemapUniforms(p); };

}
}
else if(name == "mud") {
newMaterial->supportsRGB = false;
for(int i = 0; i < 4; i++) {buff[i] = &bindata_mud[0]; buffSize[i] = bindata_mud.size();}
Expand Down Expand Up @@ -1108,8 +1104,16 @@ void Engine::configureImGui() {
void Engine::loadDefaultColorMap(std::string name) {

const std::vector<glm::vec3>* buff = nullptr;
if (name == "viridis") {
if (name == "gray") {
buff = &CM_GRAY;
} else if (name == "viridis") {
buff = &CM_VIRIDIS;
} else if (name == "magma") {
buff = &CM_MAGMA;
} else if (name == "inferno") {
buff = &CM_INFERNO;
} else if (name == "plasma") {
buff = &CM_PLASMA;
} else if (name == "coolwarm") {
buff = &CM_COOLWARM;
} else if (name == "blues") {
Expand All @@ -1128,8 +1132,6 @@ void Engine::loadDefaultColorMap(std::string name) {
buff = &CM_JET;
} else if (name == "turbo") {
buff = &CM_TURBO;
} else if (name == "hsv") {
buff = &CM_HSV;
} else {
exception("unrecognized default colormap " + name);
}
Expand All @@ -1141,7 +1143,11 @@ void Engine::loadDefaultColorMap(std::string name) {
}

void Engine::loadDefaultColorMaps() {
loadDefaultColorMap("gray");
loadDefaultColorMap("viridis");
loadDefaultColorMap("plasma");
loadDefaultColorMap("inferno");
loadDefaultColorMap("magma");
loadDefaultColorMap("coolwarm");
loadDefaultColorMap("blues");
loadDefaultColorMap("reds");
Expand All @@ -1151,7 +1157,6 @@ void Engine::loadDefaultColorMaps() {
loadDefaultColorMap("rainbow");
loadDefaultColorMap("jet");
loadDefaultColorMap("turbo");
loadDefaultColorMap("hsv");
}


Expand Down
26 changes: 26 additions & 0 deletions src/render/opengl/shaders/rules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,32 @@ const ShaderReplacementRule ISOLINE_STRIPE_VALUECOLOR (
/* textures */ {}
);


const ShaderReplacementRule CONTOUR_VALUECOLOR (
/* rule name */ "CONTOUR_VALUECOLOR",
{ /* replacement sources */
{"FRAG_DECLARATIONS", R"(
uniform float u_modFrequency;
uniform float u_modThickness;
uniform float u_modDarkness;
)"},
{"GENERATE_SHADE_COLOR", R"(
/* TODO: get rid of arbitrary constants */
vec2 gradF = vec2( dFdx(shadeValue), dFdy(shadeValue) );
float w = 1./( 1000. * u_modFrequency * u_modThickness * length(gradF) );
float s = u_modDarkness * exp( -pow( w*(fract(abs(100.0*u_modFrequency*shadeValue))-0.5), 8.0 ));
albedoColor *= 1.-s;
)"}
},
/* uniforms */ {
{"u_modFrequency", DataType::Float},
{"u_modThickness", DataType::Float},
{"u_modDarkness", DataType::Float},
},
/* attributes */ {},
/* textures */ {}
);

const ShaderReplacementRule CHECKER_VALUE2COLOR (
/* rule name */ "CHECKER_VALUE2COLOR",
{ /* replacement sources */
Expand Down