Settings UI: LightManager ShadowOptions now affect all lights.
This commit is contained in:
@@ -84,7 +84,13 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
|
||||
}
|
||||
}
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||
automation->tick((View*) view, ptrMaterials, materialCount, (Renderer*) renderer, deltaTime);
|
||||
AutomationEngine::ViewerContent content = {
|
||||
.view = (View*) view,
|
||||
.renderer = (Renderer*) renderer,
|
||||
.materials = ptrMaterials,
|
||||
.materialCount = (size_t) materialCount,
|
||||
};
|
||||
automation->tick(content, deltaTime);
|
||||
if (longMaterials) {
|
||||
env->ReleaseLongArrayElements(materials, longMaterials, 0);
|
||||
delete[] ptrMaterials;
|
||||
@@ -94,8 +100,9 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nApplySettings(JNIEnv* env, jclass klass,
|
||||
jlong nativeAutomation, jstring json, jlong view, jlongArray materials, jlong nativeIbl,
|
||||
jint lightEntity, jlong nativeLm, jlong scene, jlong renderer) {
|
||||
jint sunlightEntity, jintArray assetLights, jlong nativeLm, jlong scene, jlong renderer) {
|
||||
using MaterialPointer = MaterialInstance*;
|
||||
|
||||
jsize materialCount = 0;
|
||||
jlong* longMaterials = nullptr;
|
||||
MaterialPointer* ptrMaterials = nullptr;
|
||||
@@ -107,17 +114,42 @@ Java_com_google_android_filament_utils_AutomationEngine_nApplySettings(JNIEnv* e
|
||||
ptrMaterials[i] = (MaterialPointer) longMaterials[i];
|
||||
}
|
||||
}
|
||||
|
||||
jsize lightCount = 0;
|
||||
jint* intLights = nullptr;
|
||||
if (assetLights) {
|
||||
lightCount = env->GetArrayLength(assetLights);
|
||||
intLights = env->GetIntArrayElements(assetLights, nullptr);
|
||||
}
|
||||
|
||||
static_assert(sizeof(jint) == sizeof(Entity));
|
||||
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||
const char* nativeJson = env->GetStringUTFChars(json, 0);
|
||||
size_t jsonLength = env->GetStringUTFLength(json);
|
||||
automation->applySettings(nativeJson, jsonLength, (View*) view, ptrMaterials, materialCount,
|
||||
(IndirectLight*) nativeIbl, (Entity&) lightEntity, (LightManager*) nativeLm,
|
||||
(Scene*) scene, (Renderer*) renderer);
|
||||
|
||||
AutomationEngine::ViewerContent content = {
|
||||
.view = (View*) view,
|
||||
.renderer = (Renderer*) renderer,
|
||||
.materials = ptrMaterials,
|
||||
.materialCount = (size_t) materialCount,
|
||||
.lightManager = (LightManager*) nativeLm,
|
||||
.scene = (Scene*) scene,
|
||||
.indirectLight = (IndirectLight*) nativeIbl,
|
||||
.sunlight = (Entity&) sunlightEntity,
|
||||
.assetLights = (Entity*) intLights,
|
||||
.assetLightCount = (size_t) lightCount,
|
||||
};
|
||||
|
||||
automation->applySettings(nativeJson, jsonLength, content);
|
||||
env->ReleaseStringUTFChars(json, nativeJson);
|
||||
if (longMaterials) {
|
||||
env->ReleaseLongArrayElements(materials, longMaterials, 0);
|
||||
delete[] ptrMaterials;
|
||||
}
|
||||
if (intLights) {
|
||||
env->ReleaseIntArrayElements(assetLights, intLights, 0);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
||||
@@ -51,7 +51,7 @@ import com.google.android.filament.Renderer;
|
||||
* (shouldClose) that is triggered after the last test has been invoked.
|
||||
*/
|
||||
public class AutomationEngine {
|
||||
private long mNativeObject;
|
||||
private final long mNativeObject;
|
||||
private ColorGrading mColorGrading;
|
||||
|
||||
/**
|
||||
@@ -76,6 +76,20 @@ public class AutomationEngine {
|
||||
public boolean verbose = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collection of Filament objects that can be modified by the automation engine.
|
||||
*/
|
||||
public static class ViewerContent {
|
||||
public View view;
|
||||
public Renderer renderer;
|
||||
public MaterialInstance[] materials;
|
||||
public LightManager lightManager;
|
||||
public Scene scene;
|
||||
public IndirectLight indirectLight;
|
||||
public @Entity int sunlight;
|
||||
public @Entity int[] assetLights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows remote control for the viewer.
|
||||
*/
|
||||
@@ -141,22 +155,22 @@ public class AutomationEngine {
|
||||
* This is when settings get applied, screenshots are (optionally) exported, and the internal
|
||||
* test counter is potentially incremented.
|
||||
*
|
||||
* @param view The Filament View that automation pushes changes to.
|
||||
* @param materials Optional set of of materials that can receive parameter tweaks.
|
||||
* @param renderer The Filament Renderer that can be used to take screenshots.
|
||||
* @param content Contains the Filament View, Materials, and Renderer that get modified.
|
||||
* @param deltaTime The amount of time that has passed since the previous tick in seconds.
|
||||
*/
|
||||
public void tick(@NonNull View view, @Nullable MaterialInstance[] materials,
|
||||
@NonNull Renderer renderer, float deltaTime) {
|
||||
public void tick(@NonNull ViewerContent content, float deltaTime) {
|
||||
if (content.view == null || content.renderer == null) {
|
||||
throw new IllegalStateException("Must provide a View and Renderer");
|
||||
}
|
||||
long[] nativeMaterialInstances = null;
|
||||
if (materials != null) {
|
||||
nativeMaterialInstances = new long[materials.length];
|
||||
if (content.materials != null) {
|
||||
nativeMaterialInstances = new long[content.materials.length];
|
||||
for (int i = 0; i < nativeMaterialInstances.length; i++) {
|
||||
nativeMaterialInstances[i] = materials[i].getNativeObject();
|
||||
nativeMaterialInstances[i] = content.materials[i].getNativeObject();
|
||||
}
|
||||
}
|
||||
long nativeView = view.getNativeObject();
|
||||
long nativeRenderer = renderer.getNativeObject();
|
||||
long nativeView = content.view.getNativeObject();
|
||||
long nativeRenderer = content.renderer.getNativeObject();
|
||||
nTick(mNativeObject, nativeView, nativeMaterialInstances, nativeRenderer, deltaTime);
|
||||
}
|
||||
|
||||
@@ -168,24 +182,32 @@ public class AutomationEngine {
|
||||
*
|
||||
* This updates the stashed Settings object, then pushes those settings to the given
|
||||
* Filament objects. Clients can optionally call getColorGrading() after calling this method.
|
||||
*
|
||||
* @param settingsJson Contains the JSON string with a set of changes that need to be pushed.
|
||||
* @param content Contains a set of Filament objects that you want to mutate.
|
||||
*/
|
||||
public void applySettings(@NonNull String settingsJson, @NonNull View view,
|
||||
@Nullable MaterialInstance[] materials, @Nullable IndirectLight ibl, @Entity int light,
|
||||
@NonNull LightManager lm, @NonNull Scene scene, @NonNull Renderer renderer) {
|
||||
public void applySettings(@NonNull String settingsJson, @NonNull ViewerContent content) {
|
||||
if (content.view == null || content.renderer == null) {
|
||||
throw new IllegalStateException("Must provide a View and Renderer");
|
||||
}
|
||||
long[] nativeMaterialInstances = null;
|
||||
if (materials != null) {
|
||||
nativeMaterialInstances = new long[materials.length];
|
||||
if (content.lightManager == null || content.scene == null) {
|
||||
throw new IllegalStateException("Must provide a LightManager and Scene");
|
||||
}
|
||||
if (content.materials != null) {
|
||||
nativeMaterialInstances = new long[content.materials.length];
|
||||
for (int i = 0; i < nativeMaterialInstances.length; i++) {
|
||||
nativeMaterialInstances[i] = materials[i].getNativeObject();
|
||||
nativeMaterialInstances[i] = content.materials[i].getNativeObject();
|
||||
}
|
||||
}
|
||||
long nativeView = view.getNativeObject();
|
||||
long nativeIbl = ibl == null ? 0 : ibl.getNativeObject();
|
||||
long nativeLm = lm.getNativeObject();
|
||||
long nativeScene = scene.getNativeObject();
|
||||
long nativeRenderer = renderer.getNativeObject();
|
||||
long nativeView = content.view.getNativeObject();
|
||||
long nativeIbl = content.indirectLight == null ? 0 : content.indirectLight.getNativeObject();
|
||||
long nativeLm = content.lightManager.getNativeObject();
|
||||
long nativeScene = content.scene.getNativeObject();
|
||||
long nativeRenderer = content.renderer.getNativeObject();
|
||||
nApplySettings(mNativeObject, settingsJson, nativeView, nativeMaterialInstances,
|
||||
nativeIbl, light, nativeLm, nativeScene, nativeRenderer);
|
||||
nativeIbl, content.sunlight, content.assetLights, nativeLm, nativeScene,
|
||||
nativeRenderer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,7 +269,8 @@ public class AutomationEngine {
|
||||
private static native void nTick(long nativeObject, long view, long[] materials, long renderer,
|
||||
float deltaTime);
|
||||
private static native void nApplySettings(long nativeObject, String jsonSettings, long view,
|
||||
long[] materials, long ibl, int light, long lightManager, long scene, long renderer);
|
||||
long[] materials, long ibl, int sunlight, int[] assetLights, long lightManager,
|
||||
long scene, long renderer);
|
||||
private static native void nGetViewerOptions(long nativeObject, Object result);
|
||||
private static native long nGetColorGrading(long nativeObject, long nativeEngine);
|
||||
private static native void nSignalBatchMode(long nativeObject);
|
||||
|
||||
@@ -62,6 +62,7 @@ class MainActivity : Activity() {
|
||||
private val automation = AutomationEngine()
|
||||
private var loadStartTime = 0L
|
||||
private var loadStartFence: Fence? = null
|
||||
private val viewerContent = AutomationEngine.ViewerContent()
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -76,6 +77,12 @@ class MainActivity : Activity() {
|
||||
doubleTapDetector = GestureDetector(applicationContext, doubleTapListener)
|
||||
|
||||
modelViewer = ModelViewer(surfaceView)
|
||||
viewerContent.view = modelViewer.view
|
||||
viewerContent.indirectLight = modelViewer.scene.indirectLight
|
||||
viewerContent.sunlight = modelViewer.light
|
||||
viewerContent.lightManager = modelViewer.engine.lightManager
|
||||
viewerContent.scene = modelViewer.scene
|
||||
viewerContent.renderer = modelViewer.renderer
|
||||
|
||||
surfaceView.setOnTouchListener { _, event ->
|
||||
modelViewer.onTouchEvent(event)
|
||||
@@ -316,9 +323,8 @@ class MainActivity : Activity() {
|
||||
|
||||
fun loadSettings(message: RemoteServer.ReceivedMessage) {
|
||||
val json = StandardCharsets.UTF_8.decode(message.buffer).toString()
|
||||
automation.applySettings(json, modelViewer.view, null,
|
||||
modelViewer.scene.indirectLight, modelViewer.light, modelViewer.engine.lightManager,
|
||||
modelViewer.scene, modelViewer.renderer)
|
||||
viewerContent.assetLights = modelViewer.asset?.lightEntities
|
||||
automation.applySettings(json, viewerContent)
|
||||
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
|
||||
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
|
||||
updateRootTransform()
|
||||
|
||||
@@ -152,9 +152,17 @@ using namespace utils;
|
||||
}
|
||||
|
||||
- (void)loadSettings:(viewer::ReceivedMessage const*)message {
|
||||
_automation->applySettings(message->buffer, message->bufferByteCount, self.modelView.view,
|
||||
nullptr, 0u, _indirectLight, _sun, &self.modelView.engine->getLightManager(),
|
||||
self.modelView.scene, self.modelView.renderer);
|
||||
viewer::AutomationEngine::ViewerContent content = {
|
||||
.view = self.modelView.view,
|
||||
.renderer = self.modelView.renderer,
|
||||
.materials = nullptr,
|
||||
.materialCount = 0u,
|
||||
.lightManager = &self.modelView.engine->getLightManager(),
|
||||
.scene = self.modelView.scene,
|
||||
.indirectLight = _indirectLight,
|
||||
.sunlight = _sun,
|
||||
};
|
||||
_automation->applySettings(message->buffer, message->bufferByteCount, content);
|
||||
ColorGrading* const colorGrading = _automation->getColorGrading(self.modelView.engine);
|
||||
self.modelView.view->setColorGrading(colorGrading);
|
||||
self.modelView.cameraFocalLength = _automation->getViewerOptions().cameraFocalLength;
|
||||
|
||||
@@ -84,6 +84,22 @@ public:
|
||||
bool exportSettings = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Collection of Filament objects that can be modified by the automation engine.
|
||||
*/
|
||||
struct ViewerContent {
|
||||
View* view;
|
||||
Renderer* renderer;
|
||||
MaterialInstance* const* materials;
|
||||
size_t materialCount;
|
||||
LightManager* lightManager;
|
||||
Scene* scene;
|
||||
IndirectLight* indirectLight;
|
||||
utils::Entity sunlight;
|
||||
utils::Entity* assetLights;
|
||||
size_t assetLightCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an automation engine and places it in an idle state.
|
||||
*
|
||||
@@ -139,14 +155,10 @@ public:
|
||||
* This is when settings get applied, screenshots are (optionally) exported, and the internal
|
||||
* test counter is potentially incremented.
|
||||
*
|
||||
* @param view The Filament View that automation pushes changes to.
|
||||
* @param materials An optional set of of materials that can receive parameter tweaks.
|
||||
* @param materialCount The number of items in the materials array.
|
||||
* @param renderer The Filament Renderer that can be used to take screenshots.
|
||||
* @param content Contains the Filament View, Materials, and Renderer that get modified.
|
||||
* @param deltaTime The amount of time that has passed since the previous tick in seconds.
|
||||
*/
|
||||
void tick(View* view, MaterialInstance* const* materials, size_t materialCount,
|
||||
Renderer* renderer, float deltaTime);
|
||||
void tick(const ViewerContent& content, float deltaTime);
|
||||
|
||||
/**
|
||||
* Mutates a set of client-owned Filament objects according to a JSON string.
|
||||
@@ -156,10 +168,12 @@ public:
|
||||
*
|
||||
* This updates the stashed Settings object, then pushes those settings to the given
|
||||
* Filament objects. Clients can optionally call getColorGrading() after calling this method.
|
||||
*
|
||||
* @param json Contains the JSON string with a set of changes that need to be pushed.
|
||||
* @param jsonLength Number of characters in the json string.
|
||||
* @param content Contains a set of Filament objects that you want to mutate.
|
||||
*/
|
||||
void applySettings(const char* json, size_t jsonLength, View* view,
|
||||
MaterialInstance* const* materials, size_t materialCount, IndirectLight* ibl,
|
||||
utils::Entity sunlight, LightManager* lm, Scene* scene, Renderer* renderer);
|
||||
void applySettings(const char* json, size_t jsonLength, const ViewerContent& content);
|
||||
|
||||
/**
|
||||
* Gets a color grading object that corresponds to the latest settings.
|
||||
|
||||
@@ -65,7 +65,7 @@ using LightManager = filament::LightManager;
|
||||
void applySettings(const ViewSettings& settings, View* dest);
|
||||
void applySettings(const MaterialSettings& settings, MaterialInstance* dest);
|
||||
void applySettings(const LightSettings& settings, IndirectLight* ibl, utils::Entity sunlight,
|
||||
LightManager* lm, Scene* scene);
|
||||
utils::Entity* sceneLights, size_t sceneLightCount, LightManager* lm, Scene* scene);
|
||||
void applySettings(const ViewerOptions& settings, Camera* camera, Skybox* skybox,
|
||||
Renderer* renderer);
|
||||
|
||||
|
||||
@@ -137,23 +137,23 @@ void AutomationEngine::exportSettings(const Settings& settings, const char* file
|
||||
gStatus = "Exported to '" + std::string(filename) + "' in the current folder.";
|
||||
}
|
||||
|
||||
void AutomationEngine::applySettings(const char* json, size_t jsonLength, View* view,
|
||||
MaterialInstance* const* materials, size_t materialCount, IndirectLight* ibl,
|
||||
utils::Entity sunlight, LightManager* lm, Scene* scene, Renderer* renderer) {
|
||||
void AutomationEngine::applySettings(const char* json, size_t jsonLength,
|
||||
const ViewerContent& content) {
|
||||
JsonSerializer serializer;
|
||||
if (!serializer.readJson(json, jsonLength, mSettings)) {
|
||||
std::string jsonWithTerminator(json, json + jsonLength);
|
||||
slog.e << "Badly formed JSON:\n" << jsonWithTerminator.c_str() << io::endl;
|
||||
return;
|
||||
}
|
||||
viewer::applySettings(mSettings->view, view);
|
||||
for (size_t i = 0; i < materialCount; i++) {
|
||||
viewer::applySettings(mSettings->material, materials[i]);
|
||||
viewer::applySettings(mSettings->view, content.view);
|
||||
for (size_t i = 0; i < content.materialCount; i++) {
|
||||
viewer::applySettings(mSettings->material, content.materials[i]);
|
||||
}
|
||||
viewer::applySettings(mSettings->lighting, ibl, sunlight, lm, scene);
|
||||
Camera* camera = &view->getCamera();
|
||||
Skybox* skybox = scene->getSkybox();
|
||||
viewer::applySettings(mSettings->viewer, camera, skybox, renderer);
|
||||
viewer::applySettings(mSettings->lighting, content.indirectLight, content.sunlight,
|
||||
content.assetLights, content.assetLightCount, content.lightManager, content.scene);
|
||||
Camera* camera = &content.view->getCamera();
|
||||
Skybox* skybox = content.scene->getSkybox();
|
||||
viewer::applySettings(mSettings->viewer, camera, skybox, content.renderer);
|
||||
}
|
||||
|
||||
ColorGrading* AutomationEngine::getColorGrading(Engine* engine) {
|
||||
@@ -180,15 +180,14 @@ ViewerOptions AutomationEngine::getViewerOptions() const {
|
||||
return mSettings->viewer;
|
||||
}
|
||||
|
||||
void AutomationEngine::tick(View* view, MaterialInstance* const* materials, size_t materialCount,
|
||||
Renderer* renderer, float deltaTime) {
|
||||
const auto activateTest = [this, view, materials, materialCount]() {
|
||||
void AutomationEngine::tick(const ViewerContent& content, float deltaTime) {
|
||||
const auto activateTest = [this, content]() {
|
||||
mElapsedTime = 0;
|
||||
mElapsedFrames = 0;
|
||||
mSpec->get(mCurrentTest, mSettings);
|
||||
viewer::applySettings(mSettings->view, view);
|
||||
for (size_t i = 0; i < materialCount; i++) {
|
||||
viewer::applySettings(mSettings->material, materials[i]);
|
||||
viewer::applySettings(mSettings->view, content.view);
|
||||
for (size_t i = 0; i < content.materialCount; i++) {
|
||||
viewer::applySettings(mSettings->material, content.materials[i]);
|
||||
}
|
||||
if (mOptions.verbose) {
|
||||
utils::slog.i << "Running test " << mCurrentTest << utils::io::endl;
|
||||
@@ -228,7 +227,7 @@ void AutomationEngine::tick(View* view, MaterialInstance* const* materials, size
|
||||
}
|
||||
|
||||
if (mOptions.exportScreenshots) {
|
||||
exportScreenshot(view, renderer, prefix + ".ppm", isLastTest, this);
|
||||
exportScreenshot(content.view, content.renderer, prefix + ".ppm", isLastTest, this);
|
||||
}
|
||||
|
||||
if (isLastTest) {
|
||||
|
||||
@@ -906,7 +906,7 @@ void applySettings(const MaterialSettings& settings, MaterialInstance* dest) {
|
||||
}
|
||||
|
||||
void applySettings(const LightSettings& settings, IndirectLight* ibl, utils::Entity sunlight,
|
||||
LightManager* lm, Scene* scene) {
|
||||
utils::Entity* sceneLights, size_t sceneLightCount, LightManager* lm, Scene* scene) {
|
||||
auto light = lm->getInstance(sunlight);
|
||||
if (light) {
|
||||
if (settings.enableSunlight) {
|
||||
@@ -924,6 +924,13 @@ void applySettings(const LightSettings& settings, IndirectLight* ibl, utils::Ent
|
||||
ibl->setIntensity(settings.iblIntensity);
|
||||
ibl->setRotation(math::mat3f::rotation(settings.iblRotation, math::float3 { 0, 1, 0 }));
|
||||
}
|
||||
for (size_t i = 0; i < sceneLightCount; i++) {
|
||||
auto light = lm->getInstance(sceneLights[i]);
|
||||
if (lm->isSpotLight(light)) {
|
||||
lm->setShadowCaster(light, settings.enableShadows);
|
||||
}
|
||||
lm->setShadowOptions(light, settings.shadowOptions);
|
||||
}
|
||||
}
|
||||
|
||||
static LinearColor inverseTonemapSRGB(sRGBColor x) {
|
||||
|
||||
@@ -669,48 +669,54 @@ void SimpleViewer::updateUserInterface() {
|
||||
auto& light = mSettings.lighting;
|
||||
if (ImGui::CollapsingHeader("Light")) {
|
||||
ImGui::Indent();
|
||||
ImGui::SliderFloat("IBL intensity", &light.iblIntensity, 0.0f, 100000.0f);
|
||||
ImGui::SliderAngle("IBL rotation", &light.iblRotation);
|
||||
ImGui::SliderFloat("Sun intensity", &light.sunlightIntensity, 50000.0, 150000.0f);
|
||||
ImGuiExt::DirectionWidget("Sun direction", light.sunlightDirection.v);
|
||||
ImGui::Checkbox("Enable sunlight", &light.enableSunlight);
|
||||
ImGui::Checkbox("Enable shadows", &light.enableShadows);
|
||||
int mapSize = light.shadowOptions.mapSize;
|
||||
ImGui::SliderInt("Shadow map size", &mapSize, 32, 1024);
|
||||
light.shadowOptions.mapSize = mapSize;
|
||||
if (ImGui::CollapsingHeader("Indirect light")) {
|
||||
ImGui::SliderFloat("IBL intensity", &light.iblIntensity, 0.0f, 100000.0f);
|
||||
ImGui::SliderAngle("IBL rotation", &light.iblRotation);
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Sunlight")) {
|
||||
ImGui::Checkbox("Enable sunlight", &light.enableSunlight);
|
||||
ImGui::SliderFloat("Sun intensity", &light.sunlightIntensity, 50000.0, 150000.0f);
|
||||
ImGuiExt::DirectionWidget("Sun direction", light.sunlightDirection.v);
|
||||
}
|
||||
if (ImGui::CollapsingHeader("All lights")) {
|
||||
ImGui::Checkbox("Enable shadows", &light.enableShadows);
|
||||
int mapSize = light.shadowOptions.mapSize;
|
||||
ImGui::SliderInt("Shadow map size", &mapSize, 32, 1024);
|
||||
light.shadowOptions.mapSize = mapSize;
|
||||
|
||||
|
||||
bool enableVsm = mSettings.view.shadowType == ShadowType::VSM;
|
||||
ImGui::Checkbox("Enable VSM", &enableVsm);
|
||||
mSettings.view.shadowType = enableVsm ? ShadowType::VSM : ShadowType::PCF;
|
||||
bool enableVsm = mSettings.view.shadowType == ShadowType::VSM;
|
||||
ImGui::Checkbox("Enable VSM", &enableVsm);
|
||||
mSettings.view.shadowType = enableVsm ? ShadowType::VSM : ShadowType::PCF;
|
||||
|
||||
char label[32];
|
||||
snprintf(label, 32, "%d", 1 << mVsmMsaaSamplesLog2);
|
||||
ImGui::SliderInt("VSM MSAA samples", &mVsmMsaaSamplesLog2, 0, 3, label);
|
||||
light.shadowOptions.vsm.msaaSamples = static_cast<uint8_t>(1u << mVsmMsaaSamplesLog2);
|
||||
char label[32];
|
||||
snprintf(label, 32, "%d", 1 << mVsmMsaaSamplesLog2);
|
||||
ImGui::SliderInt("VSM MSAA samples", &mVsmMsaaSamplesLog2, 0, 3, label);
|
||||
light.shadowOptions.vsm.msaaSamples = static_cast<uint8_t>(1u << mVsmMsaaSamplesLog2);
|
||||
|
||||
int vsmAnisotropy = mSettings.view.vsmShadowOptions.anisotropy;
|
||||
snprintf(label, 32, "%d", 1 << vsmAnisotropy);
|
||||
ImGui::SliderInt("VSM anisotropy", &vsmAnisotropy, 0, 3, label);
|
||||
mSettings.view.vsmShadowOptions.anisotropy = vsmAnisotropy;
|
||||
ImGui::Checkbox("VSM mipmapping", &mSettings.view.vsmShadowOptions.mipmapping);
|
||||
ImGui::SliderFloat("VSM blur", &light.shadowOptions.vsm.blurWidth, 0.0f, 125.0f);
|
||||
int vsmAnisotropy = mSettings.view.vsmShadowOptions.anisotropy;
|
||||
snprintf(label, 32, "%d", 1 << vsmAnisotropy);
|
||||
ImGui::SliderInt("VSM anisotropy", &vsmAnisotropy, 0, 3, label);
|
||||
mSettings.view.vsmShadowOptions.anisotropy = vsmAnisotropy;
|
||||
ImGui::Checkbox("VSM mipmapping", &mSettings.view.vsmShadowOptions.mipmapping);
|
||||
ImGui::SliderFloat("VSM blur", &light.shadowOptions.vsm.blurWidth, 0.0f, 125.0f);
|
||||
|
||||
// These are not very useful in practice (defaults are good), but we keep them here for debugging
|
||||
//ImGui::SliderFloat("VSM exponent", &mSettings.view.vsmShadowOptions.exponent, 0.0, 6.0f);
|
||||
//ImGui::SliderFloat("VSM Light bleed", &mSettings.view.vsmShadowOptions.lightBleedReduction, 0.0, 1.0f);
|
||||
//ImGui::SliderFloat("VSM min variance scale", &mSettings.view.vsmShadowOptions.minVarianceScale, 0.0, 10.0f);
|
||||
// These are not very useful in practice (defaults are good), but we keep them here for debugging
|
||||
//ImGui::SliderFloat("VSM exponent", &mSettings.view.vsmShadowOptions.exponent, 0.0, 6.0f);
|
||||
//ImGui::SliderFloat("VSM Light bleed", &mSettings.view.vsmShadowOptions.lightBleedReduction, 0.0, 1.0f);
|
||||
//ImGui::SliderFloat("VSM min variance scale", &mSettings.view.vsmShadowOptions.minVarianceScale, 0.0, 10.0f);
|
||||
|
||||
int shadowCascades = light.shadowOptions.shadowCascades;
|
||||
ImGui::SliderInt("Cascades", &shadowCascades, 1, 4);
|
||||
ImGui::Checkbox("Debug cascades",
|
||||
debug.getPropertyAddress<bool>("d.shadowmap.visualize_cascades"));
|
||||
ImGui::Checkbox("Enable contact shadows", &light.shadowOptions.screenSpaceContactShadows);
|
||||
ImGui::SliderFloat("Split pos 0", &light.shadowOptions.cascadeSplitPositions[0], 0.0f, 1.0f);
|
||||
ImGui::SliderFloat("Split pos 1", &light.shadowOptions.cascadeSplitPositions[1], 0.0f, 1.0f);
|
||||
ImGui::SliderFloat("Split pos 2", &light.shadowOptions.cascadeSplitPositions[2], 0.0f, 1.0f);
|
||||
int shadowCascades = light.shadowOptions.shadowCascades;
|
||||
ImGui::SliderInt("Cascades", &shadowCascades, 1, 4);
|
||||
ImGui::Checkbox("Debug cascades",
|
||||
debug.getPropertyAddress<bool>("d.shadowmap.visualize_cascades"));
|
||||
ImGui::Checkbox("Enable contact shadows", &light.shadowOptions.screenSpaceContactShadows);
|
||||
ImGui::SliderFloat("Split pos 0", &light.shadowOptions.cascadeSplitPositions[0], 0.0f, 1.0f);
|
||||
ImGui::SliderFloat("Split pos 1", &light.shadowOptions.cascadeSplitPositions[1], 0.0f, 1.0f);
|
||||
ImGui::SliderFloat("Split pos 2", &light.shadowOptions.cascadeSplitPositions[2], 0.0f, 1.0f);
|
||||
light.shadowOptions.shadowCascades = shadowCascades;
|
||||
}
|
||||
ImGui::Unindent();
|
||||
light.shadowOptions.shadowCascades = shadowCascades;
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("Fog")) {
|
||||
|
||||
@@ -713,11 +713,13 @@ int main(int argc, char** argv) {
|
||||
FilamentApp::get().close();
|
||||
return;
|
||||
}
|
||||
Settings* settings = &app.viewer->getSettings();
|
||||
MaterialInstance* const* materials = app.asset->getMaterialInstances();
|
||||
size_t materialCount = app.asset->getMaterialInstanceCount();
|
||||
app.automationEngine->tick(view, materials, materialCount, renderer,
|
||||
ImGui::GetIO().DeltaTime);
|
||||
AutomationEngine::ViewerContent content = {
|
||||
.view = view,
|
||||
.renderer = renderer,
|
||||
.materials = app.asset->getMaterialInstances(),
|
||||
.materialCount = app.asset->getMaterialInstanceCount(),
|
||||
};
|
||||
app.automationEngine->tick(content, ImGui::GetIO().DeltaTime);
|
||||
};
|
||||
|
||||
FilamentApp& filamentApp = FilamentApp::get();
|
||||
|
||||
Reference in New Issue
Block a user