allow making VPLs diffuse for faster preview convergence

metadata
Wenzel Jakob 2010-08-27 01:22:48 +02:00
parent 271d1bbded
commit eaf8ba36cb
11 changed files with 53 additions and 14 deletions

View File

@ -46,6 +46,12 @@ public:
/// Is shadow map generation generation performed in a single pass?
inline bool isSinglePass() const { return m_singlePass; }
/// Set whether or not non-diffuse VPLs are permitted
inline void setAllowNonDiffuseVPLs(bool allowNonDiffuseVPLs) { m_allowNonDiffuseVPLs = allowNonDiffuseVPLs; }
/// Are non-diffuse VPLs permitted? This is more realistic, but can take a long time to converge.
inline bool allowNonDiffuseVPLs() const { return m_allowNonDiffuseVPLs; }
/// Set the current shadow map resolution
inline void setShadowMapResolution(int resolution) { m_shadowMapResolution = resolution; }
@ -144,7 +150,7 @@ private:
bool hasLuminaire;
int param_shadowMap, param_vplPos, param_camPos, param_vplPower;
int param_vplN, param_vplS, param_vplT, param_vplWi, param_vplUV;
int param_nearClip, param_invClipRange, param_minDist;
int param_nearClip, param_invClipRange, param_minDist, param_allowNonDiffuseVPLs;
inline VPLProgramConfiguration() { }
@ -226,7 +232,7 @@ private:
ref<GPUTexture> m_shadowMap;
Float m_nearClip, m_invClipRange;
int m_shadowMapResolution;
bool m_singlePass;
bool m_singlePass, m_allowNonDiffuseVPLs;
/* Rendering related */
std::map<std::string, ProgramAndConfiguration> m_programs;

View File

@ -8,7 +8,7 @@ MTS_NAMESPACE_BEGIN
VPLShaderManager::VPLShaderManager(const Scene *scene, Renderer *renderer)
: m_scene(scene), m_renderer(renderer), m_clamping(0.1f),
m_maxClipDist(std::numeric_limits<Float>::infinity()), m_initialized(false),
m_shadowMapResolution(512), m_singlePass(false) {
m_shadowMapResolution(512), m_singlePass(false), m_allowNonDiffuseVPLs(false) {
}
VPLShaderManager::~VPLShaderManager() {
@ -320,6 +320,7 @@ void VPLShaderManager::configure(const VPL &vpl, const BSDF *bsdf, const Luminai
<< "uniform vec3 vplPower, vplS, vplT, vplN, vplWi;" << endl
<< "uniform float nearClip, invClipRange, minDist;" << endl
<< "uniform vec2 vplUV;" << endl
<< "uniform bool allowNonDiffuseVPLs;" << endl
<< endl
<< "/* Inputs <- Vertex program */" << endl
<< "varying vec3 normal, tangent, lightVec, camVec;" << endl
@ -361,18 +362,20 @@ void VPLShaderManager::configure(const VPL &vpl, const BSDF *bsdf, const Luminai
<< " vec3 vplWo = -vec3(dot(vplS, nLightVec)," << endl
<< " dot(vplT, nLightVec)," << endl
<< " dot(vplN, nLightVec));" << endl
<< " if (d < minDist) d = minDist;" << endl
<< " gl_FragColor.rgb = " << bsdfEvalName << "(uv, wi, wo)" << endl;
<< " vec3 vplLo = vplPower;" << endl
<< " if (allowNonDiffuseVPLs)" << endl
<< " vplLo *= " << vplEvalName;
if (vpl.type == ESurfaceVPL)
oss << " * " << vplEvalName << "(vplUV, vplWi, vplWo)" << endl;
oss << "(vplUV, vplWi, vplWo);" << endl;
else
oss << " * " << vplEvalName << "_dir(vplWo)" << endl;
oss << "_dir(vplWo);" << endl;
oss << " if (d < minDist) d = minDist;" << endl
<< " gl_FragColor.rgb = vplLo * " << bsdfEvalName << "(uv, wi, wo)" << endl;
if (vpl.type == ESurfaceVPL || (vpl.type == ELuminaireVPL
&& (vpl.luminaire->getType() & Luminaire::EOnSurface)))
oss << " * vplPower * shadow * abs(cosTheta(wo) * cosTheta(vplWo)) / (d*d)";
oss << " * (shadow * abs(cosTheta(wo) * cosTheta(vplWo)) / (d*d))";
else
oss << " * vplPower * shadow * abs(cosTheta(wo)) / (d*d)";
oss << " * (shadow * abs(cosTheta(wo)) / (d*d))";
if (luminaire != NULL) {
oss << endl;
oss << " + " << lumEvalName << "_area(uv)"
@ -399,6 +402,7 @@ void VPLShaderManager::configure(const VPL &vpl, const BSDF *bsdf, const Luminai
m_targetConfig.param_nearClip = program->getParameterID("nearClip", false);
m_targetConfig.param_invClipRange = program->getParameterID("invClipRange", false);
m_targetConfig.param_minDist = program->getParameterID("minDist", false);
m_targetConfig.param_allowNonDiffuseVPLs = program->getParameterID("allowNonDiffuseVPLs", false);
m_current.program = program;
m_current.config = m_targetConfig;
m_programs[configName] = m_current;
@ -413,14 +417,19 @@ void VPLShaderManager::configure(const VPL &vpl, const BSDF *bsdf, const Luminai
program->setParameter(config.param_shadowMap, m_shadowMap);
program->setParameter(config.param_vplPos, vpl.its.p);
program->setParameter(config.param_camPos, camPos);
program->setParameter(config.param_vplPower, vpl.P);
program->setParameter(config.param_vplN, vpl.its.shFrame.n);
program->setParameter(config.param_vplS, vpl.its.shFrame.s);
program->setParameter(config.param_vplT, vpl.its.shFrame.t);
if (vpl.type == ESurfaceVPL) {
program->setParameter(config.param_vplWi, vpl.its.wi);
program->setParameter(config.param_vplUV, vpl.its.uv);
program->setParameter(config.param_allowNonDiffuseVPLs, m_allowNonDiffuseVPLs);
}
if (!m_allowNonDiffuseVPLs && vpl.type == ESurfaceVPL)
program->setParameter(config.param_vplPower, vpl.P
* vpl.its.shape->getBSDF()->getDiffuseReflectance(vpl.its) * INV_PI);
else
program->setParameter(config.param_vplPower, vpl.P);
program->setParameter(config.param_nearClip, m_nearClip);
program->setParameter(config.param_invClipRange, m_invClipRange);
program->setParameter(config.param_minDist, m_minDist);

View File

@ -132,6 +132,7 @@ struct SceneContext {
QSize windowSize, sizeIncrease;
Vector2i scrollOffset;
Float reinhardKey, reinhardBurn;
bool allowNonDiffuseVPLs;
/* Preview state */
std::deque<VPL> vpls;

View File

@ -297,6 +297,14 @@ void GLWidget::setShadowMapResolution(int res) {
}
}
void GLWidget::setAllowNonDiffuseVPLs(bool value) {
if (value != m_context->allowNonDiffuseVPLs) {
m_context->allowNonDiffuseVPLs = value;
resetPreview();
}
}
void GLWidget::setPreviewMethod(EPreviewMethod method) {
if (method != m_context->previewMethod) {
m_context->previewMethod = method;

View File

@ -58,6 +58,7 @@ public slots:
void setGamma(bool srgb, Float gamma);
void setReinhardKey(Float value);
void setReinhardBurn(Float value);
void setAllowNonDiffuseVPLs(bool value);
void setExposure(Float exposure);
void onException(const QString &what);
void onScroll();

View File

@ -927,6 +927,7 @@ void MainWindow::on_actionPreviewSettings_triggered() {
connect(&d, SIGNAL(reinhardBurnChanged(Float)), ui->glView, SLOT(setReinhardBurn(Float)));
connect(&d, SIGNAL(previewMethodChanged(EPreviewMethod)), ui->glView, SLOT(setPreviewMethod(EPreviewMethod)));
connect(&d, SIGNAL(toneMappingMethodChanged(EToneMappingMethod)), ui->glView, SLOT(setToneMappingMethod(EToneMappingMethod)));
connect(&d, SIGNAL(allowNonDiffuseVPLsChanged(bool)), ui->glView, SLOT(setAllowNonDiffuseVPLs(bool)));
d.setMaximumSize(d.minimumSize());
d.exec();
QSettings settings("mitsuba-renderer.org", "qtgui");
@ -939,6 +940,7 @@ void MainWindow::on_actionPreviewSettings_triggered() {
settings.setValue("preview_clamping", context->clamping);
settings.setValue("preview_previewMethod", context->previewMethod);
settings.setValue("preview_toneMappingMethod", context->toneMappingMethod);
settings.setValue("preview_allowNonDiffuseVPLs", context->allowNonDiffuseVPLs);
#else
if (!m_previewSettings) {
m_previewSettings = new PreviewSettingsDlg(this);
@ -978,6 +980,7 @@ void MainWindow::onPreviewSettingsClose() {
settings.setValue("preview_clamping", context->clamping);
settings.setValue("preview_previewMethod", context->previewMethod);
settings.setValue("preview_toneMappingMethod", context->toneMappingMethod);
settings.setValue("preview_allowNonDiffuseVPLs", context->allowNonDiffuseVPLs);
}
}
@ -1608,6 +1611,7 @@ SceneContext::SceneContext(SceneContext *ctx) {
scrollOffset = ctx->scrollOffset;
reinhardKey = ctx->reinhardKey;
reinhardBurn = ctx->reinhardBurn;
allowNonDiffuseVPLs = ctx->allowNonDiffuseVPLs;
}
SceneContext::~SceneContext() {

View File

@ -356,6 +356,7 @@ void PreviewThread::run() {
m_shaderManager->setShadowMapResolution(m_context->shadowMapResolution);
m_shaderManager->setClamping(m_context->clamping);
m_shaderManager->setSinglePass(m_context->previewMethod == EOpenGLSinglePass);
m_shaderManager->setAllowNonDiffuseVPLs(m_context->allowNonDiffuseVPLs);
if (m_timer->getMilliseconds() > 1000) {
Float count = m_vplsPerSecond / (Float) m_timer->getMilliseconds() * 1000;

View File

@ -56,6 +56,7 @@ PreviewSettingsDialog::PreviewSettingsDialog(QWidget *parent, SceneContext *ctx,
ui->clampingSlider->setValue(clamping);
ui->gammaSpinBox->setValue(ctx->gamma);
ui->sRGBCheckBox->setCheckState(ctx->srgb ? Qt::Checked : Qt::Unchecked);
ui->nonDiffuseVPLBox->setCheckState(ctx->allowNonDiffuseVPLs ? Qt::Checked : Qt::Unchecked);
ui->previewMethodCombo->setModel(new MethodModel(this,
cap->isSupported(RendererCapabilities::EGeometryShaders)));
ui->previewMethodCombo->setCurrentIndex(ctx->previewMethod);
@ -87,6 +88,7 @@ void PreviewSettingsDialog::on_resetButton_clicked() {
ui->keySlider->setValue((int) ((0.18-REINHARD_MIN)/REINHARD_RANGE * 100));
ui->sRGBCheckBox->setCheckState(Qt::Checked);
ui->nonDiffuseVPLBox->setCheckState(Qt::Unchecked);
}
void PreviewSettingsDialog::on_keySlider_valueChanged(int value) {
@ -137,6 +139,10 @@ void PreviewSettingsDialog::on_sRGBCheckBox_stateChanged(int state) {
emit gammaChanged(state == Qt::Checked, (Float) ui->gammaSpinBox->value());
}
void PreviewSettingsDialog::on_nonDiffuseVPLBox_stateChanged(int state) {
emit allowNonDiffuseVPLsChanged(state == Qt::Checked);
}
void PreviewSettingsDialog::on_previewMethodCombo_activated(int index) {
bool visible = index != ERayTrace && index != ERayTraceCoherent;
ui->shadowResolutionCombo->setVisible(visible);

View File

@ -26,6 +26,7 @@ signals:
void toneMappingMethodChanged(EToneMappingMethod method);
void reinhardKeyChanged(Float key);
void reinhardBurnChanged(Float burn);
void allowNonDiffuseVPLsChanged(bool);
protected slots:
void on_pathLengthSlider_valueChanged(int value);
@ -35,6 +36,7 @@ protected slots:
void on_exposureSpinBox_valueChanged(double value);
void on_gammaSpinBox_valueChanged(double value);
void on_sRGBCheckBox_stateChanged(int state);
void on_nonDiffuseVPLBox_stateChanged(int state);
void on_resetButton_clicked();
void on_previewMethodCombo_activated(int index);
void on_toneMappingMethodCombo_activated(int index);

View File

@ -504,7 +504,7 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item row="5" column="2" colspan="2">
<widget class="QCheckBox" name="nonDiffuseBox">
<widget class="QCheckBox" name="nonDiffuseVPLBox">
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
@ -534,7 +534,7 @@ p, li { white-space: pre-wrap; }
<string>&amp;Other :</string>
</property>
<property name="buddy">
<cstring>nonDiffuseBox</cstring>
<cstring>nonDiffuseVPLBox</cstring>
</property>
</widget>
</item>
@ -546,7 +546,7 @@ p, li { white-space: pre-wrap; }
<tabstop>pathLengthEdit</tabstop>
<tabstop>clampingSlider</tabstop>
<tabstop>shadowResolutionCombo</tabstop>
<tabstop>nonDiffuseBox</tabstop>
<tabstop>nonDiffuseVPLBox</tabstop>
<tabstop>toneMappingMethodCombo</tabstop>
<tabstop>keySlider</tabstop>
<tabstop>exposureSpinBox</tabstop>

View File

@ -31,6 +31,7 @@ void SceneLoader::run() {
m_result->clamping = (Float) settings.value("preview_clamping", 0.1f).toDouble();
m_result->previewMethod = (EPreviewMethod) settings.value("preview_previewMethod", EOpenGL).toInt();
m_result->toneMappingMethod = (EToneMappingMethod) settings.value("preview_toneMappingMethod", EGamma).toInt();
m_result->allowNonDiffuseVPLs = settings.value("preview_allowNonDiffuseVPLs", false).toBool();
if (endsWith(lowerCase, ".exr")) {
/* This is an image, not a scene */