From e6243b3df3cf72406f36f30867986a4377060dd4 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 Oct 2021 17:25:51 -0700 Subject: [PATCH] better API for MSAA options --- .../filament-android/src/main/cpp/View.cpp | 17 ++++++ .../com/google/android/filament/View.java | 55 +++++++++++++++++++ filament/include/filament/Options.h | 22 ++++++++ filament/include/filament/View.h | 19 +++++++ filament/src/Renderer.cpp | 4 +- filament/src/View.cpp | 8 +++ filament/src/details/View.h | 17 +++++- libs/viewer/include/viewer/Settings.h | 2 +- libs/viewer/include/viewer/SimpleViewer.h | 5 +- libs/viewer/src/AutomationSpec.cpp | 2 +- libs/viewer/src/Settings.cpp | 43 +++++++++++++-- libs/viewer/src/SimpleViewer.cpp | 6 +- libs/viewer/tests/test_settings.cpp | 4 +- samples/material_sandbox.cpp | 3 + 14 files changed, 189 insertions(+), 18 deletions(-) diff --git a/android/filament-android/src/main/cpp/View.cpp b/android/filament-android/src/main/cpp/View.cpp index 686867f5eb..7969c60fd3 100644 --- a/android/filament-android/src/main/cpp/View.cpp +++ b/android/filament-android/src/main/cpp/View.cpp @@ -86,13 +86,19 @@ Java_com_google_android_filament_View_nSetRenderTarget(JNIEnv*, jclass, extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_View_nSetSampleCount(JNIEnv*, jclass, jlong nativeView, jint count) { View* view = (View*) nativeView; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" view->setSampleCount((uint8_t) count); +#pragma clang diagnostic pop } extern "C" JNIEXPORT jint JNICALL Java_com_google_android_filament_View_nGetSampleCount(JNIEnv*, jclass, jlong nativeView) { View* view = (View*) nativeView; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" return view->getSampleCount(); +#pragma clang diagnostic pop } extern "C" JNIEXPORT void JNICALL @@ -355,6 +361,17 @@ Java_com_google_android_filament_View_nSetVignetteOptions(JNIEnv*, jclass, jlong .color = LinearColorA{r, g, b, a}, .enabled = (bool)enabled}); } +extern "C" +JNIEXPORT void JNICALL +Java_com_google_android_filament_View_nSetMultiSampleAntiAliasingOptions(JNIEnv* env, jclass clazz, + jlong nativeView, jboolean enabled, jint sampleCount, jboolean customResolve) { + View* view = (View*) nativeView; + view->setMultiSampleAntiAliasingOptions({ + .enabled = (bool)enabled, + .sampleCount = (uint8_t)sampleCount, + .customResolve = (bool)customResolve}); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_View_nSetTemporalAntiAliasingOptions(JNIEnv *, jclass, diff --git a/android/filament-android/src/main/java/com/google/android/filament/View.java b/android/filament-android/src/main/java/com/google/android/filament/View.java index ef32575aac..8787949b44 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/View.java +++ b/android/filament-android/src/main/java/com/google/android/filament/View.java @@ -75,6 +75,7 @@ public class View { private VignetteOptions mVignetteOptions; private ColorGrading mColorGrading; private TemporalAntiAliasingOptions mTemporalAntiAliasingOptions; + private MultiSampleAntiAliasingOptions mMultiSampleAntiAliasingOptions; private VsmShadowOptions mVsmShadowOptions; /** @@ -291,6 +292,29 @@ public class View { public boolean ssctEnabled = false; } + /** + * Options for Multi-sample Anti-aliasing (MSAA) + * @see View#setMultiSampleAntiAliasingOptions + */ + public static class MultiSampleAntiAliasingOptions { + /** enables or disables temporal anti-aliasing */ + public boolean enabled = false; + + /** + * number of samples to use for multi-sampled anti-aliasing.\n + * 0: treated as 1 + * 1: no anti-aliasing + * n: sample count. Effective sample could be different depending on the + * GPU capabilities. + */ + public int sampleCount = 4; + + /** + * custom resolve improves quality for HDR scenes, but may impact performance. + */ + public boolean customResolve = false; + }; + /** * Options for Temporal Anti-aliasing (TAA) * @see View#setTemporalAntiAliasingOptions @@ -1047,7 +1071,10 @@ public class View { *

* * @param count number of samples to use for multi-sampled anti-aliasing. + * + * @deprecated use setMultiSampleAntiAliasingOptions instead */ + @Deprecated public void setSampleCount(int count) { nSetSampleCount(getNativeObject(), count); } @@ -1060,7 +1087,10 @@ public class View { *

* * @return value set by {@link #setSampleCount} + * + * @deprecated use getMultiSampleAntiAliasingOptions instead */ + @Deprecated public int getSampleCount() { return nGetSampleCount(getNativeObject()); } @@ -1089,6 +1119,30 @@ public class View { return AntiAliasing.values()[nGetAntiAliasing(getNativeObject())]; } + /** + * Enables or disable multi-sample anti-aliasing (MSAA). Disabled by default. + * + * @param options multi-sample anti-aliasing options + */ + public void setMultiSampleAntiAliasingOptions(@NonNull MultiSampleAntiAliasingOptions options) { + mMultiSampleAntiAliasingOptions = options; + nSetMultiSampleAntiAliasingOptions(getNativeObject(), + options.enabled, options.sampleCount, options.customResolve); + } + + /** + * Returns multi-sample anti-aliasing options. + * + * @return multi-sample anti-aliasing options + */ + @NonNull + public MultiSampleAntiAliasingOptions getMultiSampleAntiAliasingOptions() { + if (mMultiSampleAntiAliasingOptions == null) { + mMultiSampleAntiAliasingOptions = new MultiSampleAntiAliasingOptions(); + } + return mMultiSampleAntiAliasingOptions; + } + /** * Enables or disable temporal anti-aliasing (TAA). Disabled by default. * @@ -1660,6 +1714,7 @@ public class View { boolean nativeResolution, int foregroundRingCount, int backgroundRingCount, int fastGatherRingCount, int maxForegroundCOC, int maxBackgroundCOC); private static native void nSetVignetteOptions(long nativeView, float midPoint, float roundness, float feather, float r, float g, float b, float a, boolean enabled); private static native void nSetTemporalAntiAliasingOptions(long nativeView, float feedback, float filterWidth, boolean enabled); + private static native void nSetMultiSampleAntiAliasingOptions(long nativeView, boolean enabled, int sampleCount, boolean customResolve); private static native boolean nIsShadowingEnabled(long nativeView); private static native void nSetScreenSpaceRefractionEnabled(long nativeView, boolean enabled); private static native boolean nIsScreenSpaceRefractionEnabled(long nativeView); diff --git a/filament/include/filament/Options.h b/filament/include/filament/Options.h index fd9a58a1ad..7911dcffd6 100644 --- a/filament/include/filament/Options.h +++ b/filament/include/filament/Options.h @@ -284,6 +284,28 @@ struct AmbientOcclusionOptions { } ssct; }; +/** + * Options for Temporal Multi-Sample Anti-aliasing (MSAA) + * @see setMultiSampleAntiAliasingOptions() + */ +struct MultiSampleAntiAliasingOptions { + bool enabled = false; //!< enables or disables msaa + + /** + * sampleCount number of samples to use for multi-sampled anti-aliasing.\n + * 0: treated as 1 + * 1: no anti-aliasing + * n: sample count. Effective sample could be different depending on the + * GPU capabilities. + */ + uint8_t sampleCount = 4; + + /** + * custom resolve improves quality for HDR scenes, but may impact performance. + */ + bool customResolve = false; +}; + /** * Options for Temporal Anti-aliasing (TAA) * @see setTemporalAntiAliasingOptions() diff --git a/filament/include/filament/View.h b/filament/include/filament/View.h index 069632aa9b..2ba9e428e3 100644 --- a/filament/include/filament/View.h +++ b/filament/include/filament/View.h @@ -80,6 +80,7 @@ public: using RenderQuality = RenderQuality; using AmbientOcclusionOptions = AmbientOcclusionOptions; using TemporalAntiAliasingOptions = TemporalAntiAliasingOptions; + using MultiSampleAntiAliasingOptions = MultiSampleAntiAliasingOptions; using VsmShadowOptions = VsmShadowOptions; /** @@ -279,7 +280,9 @@ public: * cost. See setAntialiasing. * * @see setAntialiasing + * @deprecated use setMultiSampleAntiAliasingOptions instead */ + UTILS_DEPRECATED void setSampleCount(uint8_t count = 1) noexcept; /** @@ -287,7 +290,9 @@ public: * A value of 0 or 1 means MSAA is disabled. * * @return value set by setSampleCount(). + * @deprecated use getMultiSampleAntiAliasingOptions instead */ + UTILS_DEPRECATED uint8_t getSampleCount() const noexcept; /** @@ -324,6 +329,20 @@ public: */ TemporalAntiAliasingOptions const& getTemporalAntiAliasingOptions() const noexcept; + /** + * Enables or disable multi-sample anti-aliasing (MSAA). Disabled by default. + * + * @param options multi-sample anti-aliasing options + */ + void setMultiSampleAntiAliasingOptions(MultiSampleAntiAliasingOptions options) noexcept; + + /** + * Returns multi-sample anti-aliasing options. + * + * @return multi-sample anti-aliasing options + */ + MultiSampleAntiAliasingOptions const& getMultiSampleAntiAliasingOptions() const noexcept; + /** * Sets this View's color grading transforms. * diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp index 46f7bb5f91..b0023ef312 100644 --- a/filament/src/Renderer.cpp +++ b/filament/src/Renderer.cpp @@ -229,8 +229,8 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { bool hasColorGrading = hasPostProcess; bool hasDithering = view.getDithering() == Dithering::TEMPORAL; bool hasFXAA = view.getAntiAliasing() == AntiAliasing::FXAA; - uint8_t msaaSampleCount = view.getSampleCount(); float2 scale = view.updateScale(mFrameInfoManager.getLastFrameInfo()); + auto msaaOptions = view.getMultiSampleAntiAliasingOptions(); auto dsrOptions = view.getDynamicResolutionOptions(); auto bloomOptions = view.getBloomOptions(); auto dofOptions = view.getDepthOfFieldOptions(); @@ -250,6 +250,8 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { scale = 1.0f; } + const uint8_t msaaSampleCount = msaaOptions.enabled ? msaaOptions.sampleCount : 1u; + const bool scaled = any(notEqual(scale, float2(1.0f))); filament::Viewport svp = vp.scale(scale); if (svp.empty()) { diff --git a/filament/src/View.cpp b/filament/src/View.cpp index c0cfa80e7b..ecd918fadd 100644 --- a/filament/src/View.cpp +++ b/filament/src/View.cpp @@ -923,6 +923,14 @@ const View::TemporalAntiAliasingOptions& View::getTemporalAntiAliasingOptions() return upcast(this)->getTemporalAntiAliasingOptions(); } +void View::setMultiSampleAntiAliasingOptions(MultiSampleAntiAliasingOptions options) noexcept { + upcast(this)->setMultiSampleAntiAliasingOptions(options); +} + +const View::MultiSampleAntiAliasingOptions& View::getMultiSampleAntiAliasingOptions() const noexcept { + return upcast(this)->getMultiSampleAntiAliasingOptions(); +} + void View::setColorGrading(ColorGrading* colorGrading) noexcept { return upcast(this)->setColorGrading(upcast(colorGrading)); } diff --git a/filament/src/details/View.h b/filament/src/details/View.h index 25e01808a6..acf4688584 100644 --- a/filament/src/details/View.h +++ b/filament/src/details/View.h @@ -214,11 +214,13 @@ public: } void setSampleCount(uint8_t count) noexcept { - mSampleCount = uint8_t(count < 1u ? 1u : count); + count = uint8_t(count < 1u ? 1u : count); + mMultiSampleAntiAliasingOptions.sampleCount = count; + mMultiSampleAntiAliasingOptions.enabled = count > 1u; } uint8_t getSampleCount() const noexcept { - return mSampleCount; + return mMultiSampleAntiAliasingOptions.sampleCount; } void setAntiAliasing(AntiAliasing type) noexcept { @@ -239,6 +241,15 @@ public: return mTemporalAntiAliasingOptions; } + void setMultiSampleAntiAliasingOptions(MultiSampleAntiAliasingOptions options) noexcept { + options.sampleCount = uint8_t(options.sampleCount < 1u ? 1u : options.sampleCount); + mMultiSampleAntiAliasingOptions = options; + } + + const MultiSampleAntiAliasingOptions& getMultiSampleAntiAliasingOptions() const noexcept { + return mMultiSampleAntiAliasingOptions; + } + void setColorGrading(FColorGrading* colorGrading) noexcept { mColorGrading = colorGrading == nullptr ? mDefaultColorGrading : colorGrading; } @@ -526,7 +537,6 @@ private: FRenderTarget* mRenderTarget = nullptr; uint8_t mVisibleLayers = 0x1; - uint8_t mSampleCount = 1; AntiAliasing mAntiAliasing = AntiAliasing::FXAA; Dithering mDithering = Dithering::TEMPORAL; bool mShadowingEnabled = true; @@ -540,6 +550,7 @@ private: DepthOfFieldOptions mDepthOfFieldOptions; VignetteOptions mVignetteOptions; TemporalAntiAliasingOptions mTemporalAntiAliasingOptions; + MultiSampleAntiAliasingOptions mMultiSampleAntiAliasingOptions; BlendMode mBlendMode = BlendMode::OPAQUE; const FColorGrading* mColorGrading = nullptr; const FColorGrading* mDefaultColorGrading = nullptr; diff --git a/libs/viewer/include/viewer/Settings.h b/libs/viewer/include/viewer/Settings.h index 15c1a20f86..41639c2416 100644 --- a/libs/viewer/include/viewer/Settings.h +++ b/libs/viewer/include/viewer/Settings.h @@ -151,8 +151,8 @@ struct DynamicLightingSettings { // This defines fields in the same order as the setter methods in filament::View. struct ViewSettings { - uint8_t sampleCount = 1; AntiAliasing antiAliasing = AntiAliasing::FXAA; + MultiSampleAntiAliasingOptions msaa; TemporalAntiAliasingOptions taa; ColorGradingSettings colorGrading; AmbientOcclusionOptions ssao; diff --git a/libs/viewer/include/viewer/SimpleViewer.h b/libs/viewer/include/viewer/SimpleViewer.h index 45703a7010..f3787f2d8f 100644 --- a/libs/viewer/include/viewer/SimpleViewer.h +++ b/libs/viewer/include/viewer/SimpleViewer.h @@ -177,7 +177,10 @@ public: * Enables hardware-based MSAA antialiasing. * Defaults to true. */ - void enableMsaa(bool b) { mSettings.view.sampleCount = b ? 4 : 1; } + void enableMsaa(bool b) { + mSettings.view.msaa.sampleCount = 4; + mSettings.view.msaa.enabled = b; + } /** * Enables screen-space ambient occlusion in the post-process pipeline. diff --git a/libs/viewer/src/AutomationSpec.cpp b/libs/viewer/src/AutomationSpec.cpp index 4979a8fb88..ea80619268 100644 --- a/libs/viewer/src/AutomationSpec.cpp +++ b/libs/viewer/src/AutomationSpec.cpp @@ -57,7 +57,7 @@ static const char* DEFAULT_AUTOMATION = R"TXT([ "base": { }, "permute": { - "view.sampleCount": [1, 4], + "view.msaa.enabled": [false, true], "view.taa.enabled": [false, true], "view.antiAliasing": ["NONE", "FXAA"], "view.ssao.enabled": [false, true], diff --git a/libs/viewer/src/Settings.cpp b/libs/viewer/src/Settings.cpp index 3d672a69c3..12ac717dc0 100644 --- a/libs/viewer/src/Settings.cpp +++ b/libs/viewer/src/Settings.cpp @@ -241,6 +241,31 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, return i; } +static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, + MultiSampleAntiAliasingOptions* out) { + CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i++].size; + for (int j = 0; j < size; ++j) { + const jsmntok_t tok = tokens[i]; + CHECK_KEY(tok); + if (compare(tok, jsonChunk, "enabled") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->enabled); + } else if (compare(tok, jsonChunk, "sampleCount") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->sampleCount); + } else if (compare(tok, jsonChunk, "customResolve") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->customResolve); + } else { + slog.w << "Invalid msaa key: '" << STR(tok, jsonChunk) << "'" << io::endl; + i = parse(tokens, i + 1); + } + if (i < 0) { + slog.e << "Invalid msaa value: '" << STR(tok, jsonChunk) << "'" << io::endl; + return i; + } + } + return i; +} + static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, TemporalAntiAliasingOptions* out) { CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -664,10 +689,10 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, ViewSett for (int j = 0; j < size; ++j) { const jsmntok_t tok = tokens[i]; CHECK_KEY(tok); - if (compare(tok, jsonChunk, "sampleCount") == 0) { - i = parse(tokens, i + 1, jsonChunk, &out->sampleCount); - } else if (compare(tok, jsonChunk, "antiAliasing") == 0) { + if (compare(tok, jsonChunk, "antiAliasing") == 0) { i = parse(tokens, i + 1, jsonChunk, &out->antiAliasing); + } else if (compare(tok, jsonChunk, "msaa") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->msaa); } else if (compare(tok, jsonChunk, "taa") == 0) { i = parse(tokens, i + 1, jsonChunk, &out->taa); } else if (compare(tok, jsonChunk, "colorGrading") == 0) { @@ -916,9 +941,9 @@ int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, Settings* out) } void applySettings(const ViewSettings& settings, View* dest) { - dest->setSampleCount(settings.sampleCount); dest->setAntiAliasing(settings.antiAliasing); dest->setTemporalAntiAliasingOptions(settings.taa); + dest->setMultiSampleAntiAliasingOptions(settings.msaa); dest->setAmbientOcclusionOptions(settings.ssao); dest->setBloomOptions(settings.bloom); dest->setFogOptions(settings.fog); @@ -1137,6 +1162,14 @@ static std::ostream& operator<<(std::ostream& out, math::float4 v) { return writeJson(out, &v.x, 4); } +static std::ostream& operator<<(std::ostream& out, const MultiSampleAntiAliasingOptions& in) { + return out << "{\n" + << "\"enabled\": " << to_string(in.enabled) << ",\n" + << "\"sampleCount\": " << (in.sampleCount) << ",\n" + << "\"customResolve\": " << to_string(in.customResolve) << "\n" + << "}"; +} + static std::ostream& operator<<(std::ostream& out, const TemporalAntiAliasingOptions& in) { return out << "{\n" << "\"filterWidth\": " << (in.filterWidth) << ",\n" @@ -1390,8 +1423,8 @@ static std::ostream& operator<<(std::ostream& out, const VsmShadowOptions& in) { static std::ostream& operator<<(std::ostream& out, const ViewSettings& in) { return out << "{\n" - << "\"sampleCount\": " << int(in.sampleCount) << ",\n" << "\"antiAliasing\": " << in.antiAliasing << ",\n" + << "\"msaa\": " << in.msaa << ",\n" << "\"taa\": " << in.taa << ",\n" << "\"colorGrading\": " << (in.colorGrading) << ",\n" << "\"ssao\": " << (in.ssao) << ",\n" diff --git a/libs/viewer/src/SimpleViewer.cpp b/libs/viewer/src/SimpleViewer.cpp index 51d28738e7..eecf3dc25c 100644 --- a/libs/viewer/src/SimpleViewer.cpp +++ b/libs/viewer/src/SimpleViewer.cpp @@ -371,7 +371,7 @@ SimpleViewer::SimpleViewer(filament::Engine* engine, filament::Scene* scene, fil mSettings.view.vsmShadowOptions.anisotropy = 0; mSettings.view.dithering = Dithering::TEMPORAL; mSettings.view.antiAliasing = AntiAliasing::FXAA; - mSettings.view.sampleCount = 4; + mSettings.view.msaa = { .enabled = true, .sampleCount = 4 }; mSettings.view.ssao.enabled = true; mSettings.view.bloom.enabled = true; @@ -688,9 +688,7 @@ void SimpleViewer::updateUserInterface() { enableFxaa(fxaa); ImGui::Unindent(); - bool msaa = mSettings.view.sampleCount != 1; - ImGui::Checkbox("MSAA 4x", &msaa); - enableMsaa(msaa); + ImGui::Checkbox("MSAA 4x", &mSettings.view.msaa.enabled); ImGui::Checkbox("SSAO", &mSettings.view.ssao.enabled); if (ImGui::CollapsingHeader("SSAO Options")) { diff --git a/libs/viewer/tests/test_settings.cpp b/libs/viewer/tests/test_settings.cpp index 29d6d18046..b8e91826a4 100644 --- a/libs/viewer/tests/test_settings.cpp +++ b/libs/viewer/tests/test_settings.cpp @@ -159,7 +159,7 @@ static const char* JSON_TEST_AUTOMATION = R"TXT([{ TEST_F(ViewSettingsTest, JsonTestDefaults) { JsonSerializer serializer; - Settings settings1 = {0}; + Settings settings1; ASSERT_TRUE(serializer.readJson(JSON_TEST_DEFAULTS, strlen(JSON_TEST_DEFAULTS), &settings1)); ASSERT_TRUE(settings1.view.bloom.threshold); @@ -191,7 +191,7 @@ TEST_F(ViewSettingsTest, JsonTestSerialization) { TEST_F(ViewSettingsTest, JsonTestMaterial) { JsonSerializer serializer; - Settings settings = {0}; + Settings settings; std::string js = "{" + std::string(JSON_TEST_MATERIAL) + "}"; ASSERT_TRUE(serializer.readJson(js.c_str(), js.size(), &settings)); std::string serialized = serializer.writeJson(settings); diff --git a/samples/material_sandbox.cpp b/samples/material_sandbox.cpp index e9454bf739..cb25f79f1e 100644 --- a/samples/material_sandbox.cpp +++ b/samples/material_sandbox.cpp @@ -976,7 +976,10 @@ static void preRender(filament::Engine* engine, filament::View* view, filament:: view->setBloomOptions(g_params.bloomOptions); view->setFogOptions(g_params.fogOptions); view->setTemporalAntiAliasingOptions(g_params.taaOptions); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" view->setSampleCount((uint8_t) (g_params.msaa ? 4 : 1)); +#pragma clang diagnostic pop view->setAmbientOcclusionOptions(g_params.ssaoOptions); if (g_params.colorGrading) {