Merge branch 'main' into ma/descriptor-sets
This commit is contained in:
@@ -7,3 +7,5 @@ for next branch cut* header.
|
||||
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
||||
|
||||
## Release notes for next branch cut
|
||||
|
||||
- Add drag and drop support for IBL files for desktop gltf_viewer.
|
||||
|
||||
@@ -125,6 +125,11 @@ extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBu
|
||||
builder->groundPlane(a, b, c, d);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderPanning(JNIEnv*, jclass, jlong nativeBuilder, jboolean enabled) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
builder->panning(enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long Java_com_google_android_filament_utils_Manipulator_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder, jint mode) {
|
||||
Builder* builder = (Builder*) nativeBuilder;
|
||||
return (jlong) builder->build((Mode) mode);
|
||||
|
||||
+12
@@ -274,6 +274,17 @@ public class Manipulator {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether panning is enabled in the manipulator.
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder panning(Boolean enabled) {
|
||||
nBuilderPanning(mNativeBuilder, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the <code>Manipulator</code> object.
|
||||
*
|
||||
@@ -483,6 +494,7 @@ public class Manipulator {
|
||||
private static native void nBuilderFlightPanSpeed(long nativeBuilder, float x, float y);
|
||||
private static native void nBuilderFlightMoveDamping(long nativeBuilder, float damping);
|
||||
private static native void nBuilderGroundPlane(long nativeBuilder, float a, float b, float c, float d);
|
||||
private static native void nBuilderPanning(long nativeBuilder, Boolean enabled);
|
||||
private static native long nBuilderBuild(long nativeBuilder, int mode);
|
||||
|
||||
private static native void nDestroyManipulator(long nativeManip);
|
||||
|
||||
@@ -64,14 +64,15 @@ First determine the Filament material and variant that causes the problem.
|
||||
What we want is the "raw" GLSL version of the shader, before any optimizations / cross-compilation
|
||||
happens.
|
||||
|
||||
The easiest way I've found to do this is by adding a `std::cout` statement inside `MaterialBuilder`,
|
||||
right after `sg.createFragmentProgram` or `sg.createVertexProgram` is called. For example,
|
||||
We can use the `--save-raw-variants` debug flag in matc to export each GLSL
|
||||
shader to a file. For example:
|
||||
|
||||
```
|
||||
if (v.variant.key == 8u) { std::cout << shader << std::endl; }
|
||||
matc --save-raw-variants --optimize-size --variant-filter fog,ssr,vsm,stereo \
|
||||
-a all -p all -o mymaterial.filamat mymaterial.mat
|
||||
```
|
||||
|
||||
Then, I invoke `matc` and redirect stdout to a .frag or .vert file.
|
||||
Files will be named like `mymaterial_0x05.frag` or `mymaterial_0x05.vert`.
|
||||
|
||||
Note that gltfio material "templates" first go through a build step. After building gltfio, the
|
||||
gltfio Filament materials are output to:
|
||||
|
||||
@@ -109,6 +109,7 @@ public:
|
||||
vec4 groundPlane;
|
||||
RayCallback raycastCallback;
|
||||
void* raycastUserdata;
|
||||
bool panning = true;
|
||||
};
|
||||
|
||||
struct Builder {
|
||||
@@ -143,6 +144,8 @@ public:
|
||||
Builder& groundPlane(FLOAT a, FLOAT b, FLOAT c, FLOAT d); //! Plane equation used as a raycast fallback
|
||||
Builder& raycastCallback(RayCallback cb, void* userdata); //! Raycast function for accurate grab-and-pan
|
||||
|
||||
Builder& panning(bool enabled); //! Sets whether panning is enabled
|
||||
|
||||
/**
|
||||
* Creates a new camera manipulator, either ORBIT, MAP, or FREE_FLIGHT.
|
||||
*
|
||||
|
||||
@@ -144,6 +144,14 @@ Manipulator<FLOAT>::Builder& Manipulator<FLOAT>::Builder::raycastCallback(RayCal
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename FLOAT> typename
|
||||
Manipulator<FLOAT>::Builder& Manipulator<FLOAT>::Builder::panning(bool enabled) {
|
||||
details.panning = enabled;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename FLOAT>
|
||||
Manipulator<FLOAT>* Manipulator<FLOAT>::Builder::build(Mode mode) {
|
||||
switch (mode) {
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
}
|
||||
|
||||
void grabBegin(int x, int y, bool strafe) override {
|
||||
mGrabState = strafe ? PANNING : ORBITING;
|
||||
mGrabState = strafe && Base::mProps.panning ? PANNING : ORBITING;
|
||||
mGrabPivot = mPivot;
|
||||
mGrabEye = Base::mEye;
|
||||
mGrabTarget = Base::mTarget;
|
||||
|
||||
@@ -134,6 +134,7 @@ protected:
|
||||
TargetApi mTargetApi = (TargetApi) 0;
|
||||
Optimization mOptimization = Optimization::PERFORMANCE;
|
||||
bool mPrintShaders = false;
|
||||
bool mSaveRawVariants = false;
|
||||
bool mGenerateDebugInfo = false;
|
||||
bool mIncludeEssl1 = true;
|
||||
utils::bitset32 mShaderModels;
|
||||
@@ -586,6 +587,14 @@ public:
|
||||
//! If true, will output the generated GLSL shader code to stdout.
|
||||
MaterialBuilder& printShaders(bool printShaders) noexcept;
|
||||
|
||||
/**
|
||||
* If true, this will write the raw generated GLSL for each variant to a text file in the
|
||||
* current directory. The file will be named after the material name and the variant name. Its
|
||||
* extension will be derived from the shader stage. For example, mymaterial_0x0e.frag,
|
||||
* mymaterial_0x18.vert, etc.
|
||||
*/
|
||||
MaterialBuilder& saveRawVariants(bool saveVariants) noexcept;
|
||||
|
||||
//! If true, will include debugging information in generated SPIRV.
|
||||
MaterialBuilder& generateDebugInfo(bool generateDebugInfo) noexcept;
|
||||
|
||||
|
||||
@@ -65,11 +65,11 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
namespace filamat {
|
||||
|
||||
using namespace utils;
|
||||
@@ -558,6 +558,11 @@ MaterialBuilder& MaterialBuilder::printShaders(bool printShaders) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::saveRawVariants(bool saveRawVariants) noexcept {
|
||||
mSaveRawVariants = saveRawVariants;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::generateDebugInfo(bool generateDebugInfo) noexcept {
|
||||
mGenerateDebugInfo = generateDebugInfo;
|
||||
return *this;
|
||||
@@ -931,6 +936,30 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
|
||||
info);
|
||||
}
|
||||
|
||||
// Write the variant to a file.
|
||||
if (mSaveRawVariants) {
|
||||
int variantKey = v.variant.key;
|
||||
auto getExtension = [](backend::ShaderStage stage) {
|
||||
switch (stage) {
|
||||
case backend::ShaderStage::VERTEX:
|
||||
return "vert";
|
||||
case backend::ShaderStage::FRAGMENT:
|
||||
return "frag";
|
||||
case backend::ShaderStage::COMPUTE:
|
||||
return "comp";
|
||||
}
|
||||
};
|
||||
char filename[256];
|
||||
snprintf(filename, sizeof(filename), "%s_0x%02x.%s", mMaterialName.c_str_safe(),
|
||||
variantKey, getExtension(v.stage));
|
||||
printf("Writing variant 0x%02x to %s\n", variantKey, filename);
|
||||
std::ofstream file(filename);
|
||||
if (file.is_open()) {
|
||||
file << shader;
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
std::string* pGlsl = nullptr;
|
||||
if (targetApiNeedsGlsl) {
|
||||
pGlsl = &shader;
|
||||
|
||||
@@ -104,6 +104,8 @@ public:
|
||||
|
||||
size_t getSkippedFrameCount() const { return mSkippedFrames; }
|
||||
|
||||
void loadIBL(std::string_view path);
|
||||
|
||||
FilamentApp(const FilamentApp& rhs) = delete;
|
||||
FilamentApp(FilamentApp&& rhs) = delete;
|
||||
FilamentApp& operator=(const FilamentApp& rhs) = delete;
|
||||
|
||||
@@ -174,11 +174,6 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback,
|
||||
|
||||
loadDirt(config);
|
||||
loadIBL(config);
|
||||
if (mIBL != nullptr) {
|
||||
mIBL->getSkybox()->setLayerMask(0x7, 0x4);
|
||||
mScene->setSkybox(mIBL->getSkybox());
|
||||
mScene->setIndirectLight(mIBL->getIndirectLight());
|
||||
}
|
||||
|
||||
for (auto& view : window->mViews) {
|
||||
if (view.get() != window->mUiView) {
|
||||
@@ -519,31 +514,41 @@ const utils::Path& FilamentApp::getRootAssetsPath() {
|
||||
return root;
|
||||
}
|
||||
|
||||
void FilamentApp::loadIBL(const Config& config) {
|
||||
if (!config.iblDirectory.empty()) {
|
||||
Path iblPath(config.iblDirectory);
|
||||
void FilamentApp::loadIBL(std::string_view path) {
|
||||
Path iblPath(path);
|
||||
if (!iblPath.exists()) {
|
||||
std::cerr << "The specified IBL path does not exist: " << iblPath << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!iblPath.exists()) {
|
||||
std::cerr << "The specified IBL path does not exist: " << iblPath << std::endl;
|
||||
mIBL = std::make_unique<IBL>(*mEngine);
|
||||
|
||||
if (!iblPath.isDirectory()) {
|
||||
if (!mIBL->loadFromEquirect(iblPath)) {
|
||||
std::cerr << "Could not load the specified IBL: " << iblPath << std::endl;
|
||||
mIBL.reset(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
mIBL = std::make_unique<IBL>(*mEngine);
|
||||
|
||||
if (!iblPath.isDirectory()) {
|
||||
if (!mIBL->loadFromEquirect(iblPath)) {
|
||||
std::cerr << "Could not load the specified IBL: " << iblPath << std::endl;
|
||||
mIBL.reset(nullptr);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!mIBL->loadFromDirectory(iblPath)) {
|
||||
std::cerr << "Could not load the specified IBL: " << iblPath << std::endl;
|
||||
mIBL.reset(nullptr);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!mIBL->loadFromDirectory(iblPath)) {
|
||||
std::cerr << "Could not load the specified IBL: " << iblPath << std::endl;
|
||||
mIBL.reset(nullptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mIBL != nullptr) {
|
||||
mIBL->getSkybox()->setLayerMask(0x7, 0x4);
|
||||
mScene->setSkybox(mIBL->getSkybox());
|
||||
mScene->setIndirectLight(mIBL->getIndirectLight());
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentApp::loadIBL(const Config& config) {
|
||||
if (config.iblDirectory.empty()) {
|
||||
return;
|
||||
}
|
||||
loadIBL(config.iblDirectory);
|
||||
}
|
||||
|
||||
void FilamentApp::loadDirt(const Config& config) {
|
||||
|
||||
+48
-14
@@ -58,6 +58,7 @@
|
||||
|
||||
#include <cgltf.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -508,30 +509,55 @@ static void onClick(App& app, View* view, ImVec2 pos) {
|
||||
});
|
||||
}
|
||||
|
||||
static utils::Path getPathForAsset(std::string_view string) {
|
||||
static utils::Path getPathForIBLAsset(std::string_view string) {
|
||||
auto isIBL = [] (utils::Path file) -> bool {
|
||||
return file.getExtension() == "ktx" || file.getExtension() == "hdr";
|
||||
};
|
||||
|
||||
utils::Path filename{ string };
|
||||
if (!filename.exists()) {
|
||||
std::cerr << "file " << filename << " not found!" << std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (filename.isDirectory()) {
|
||||
auto files = filename.listContents();
|
||||
for (const auto& file: files) {
|
||||
if (file.getExtension() == "gltf" || file.getExtension() == "glb") {
|
||||
filename = file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (filename.isDirectory()) {
|
||||
std::cerr << "no glTF file found in " << filename << std::endl;
|
||||
std::vector<Path> files = filename.listContents();
|
||||
if (std::none_of(files.cbegin(), files.cend(), isIBL)) {
|
||||
return {};
|
||||
}
|
||||
} else if (!isIBL(filename)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
static utils::Path getPathForGLTFAsset(std::string_view string) {
|
||||
auto isGLTF = [] (utils::Path file) -> bool {
|
||||
return file.getExtension() == "gltf" || file.getExtension() == "glb";
|
||||
};
|
||||
|
||||
static bool checkAsset(const utils::Path& filename) {
|
||||
utils::Path filename{ string };
|
||||
if (!filename.exists()) {
|
||||
std::cerr << "file " << filename << " not found!" << std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (filename.isDirectory()) {
|
||||
std::vector<Path> files = filename.listContents();
|
||||
auto it = std::find_if(files.cbegin(), files.cend(), isGLTF);
|
||||
if (it == files.end()) {
|
||||
return {};
|
||||
}
|
||||
filename = *it;
|
||||
} else if (!isGLTF(filename)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
static bool checkGLTFAsset(const utils::Path& filename) {
|
||||
// Peek at the file size to allow pre-allocation.
|
||||
long const contentSize = static_cast<long>(getFileSize(filename.c_str()));
|
||||
if (contentSize <= 0) {
|
||||
@@ -571,8 +597,9 @@ int main(int argc, char** argv) {
|
||||
utils::Path filename;
|
||||
int const num_args = argc - optionIndex;
|
||||
if (num_args >= 1) {
|
||||
filename = getPathForAsset(argv[optionIndex]);
|
||||
filename = getPathForGLTFAsset(argv[optionIndex]);
|
||||
if (filename.isEmpty()) {
|
||||
std::cerr << "no glTF file found in " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1125,9 +1152,9 @@ int main(int argc, char** argv) {
|
||||
filamentApp.resize(resize);
|
||||
|
||||
filamentApp.setDropHandler([&](std::string_view path) {
|
||||
utils::Path const filename = getPathForAsset(path);
|
||||
utils::Path filename = getPathForGLTFAsset(path);
|
||||
if (!filename.isEmpty()) {
|
||||
if (checkAsset(filename)) {
|
||||
if (checkGLTFAsset(filename)) {
|
||||
app.resourceLoader->asyncCancelLoad();
|
||||
app.resourceLoader->evictResourceData();
|
||||
app.viewer->removeAsset();
|
||||
@@ -1136,6 +1163,13 @@ int main(int argc, char** argv) {
|
||||
loadResources(filename);
|
||||
app.viewer->setAsset(app.asset, app.instance);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
filename = getPathForIBLAsset(path);
|
||||
if (!filename.isEmpty()) {
|
||||
FilamentApp::get().loadIBL(path);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -103,6 +103,8 @@ static void usage(char* name) {
|
||||
" Skip validation of number of sampler used\n\n"
|
||||
" --print, -t\n"
|
||||
" Print generated shaders for debugging\n\n"
|
||||
" --save-raw-variants, -R\n"
|
||||
" Write the raw generated GLSL for each variant to a text file in the current directory.\n\n"
|
||||
);
|
||||
const std::string from("MATC");
|
||||
for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) {
|
||||
@@ -179,7 +181,7 @@ static void parseDefine(std::string defineString, Config::StringReplacementMap&
|
||||
}
|
||||
|
||||
bool CommandlineConfig::parse() {
|
||||
static constexpr const char* OPTSTR = "hLxo:f:dm:a:l:p:D:T:P:OSEr:vV:gtwF1";
|
||||
static constexpr const char* OPTSTR = "hLxo:f:dm:a:l:p:D:T:P:OSEr:vV:gtwF1R";
|
||||
static const struct option OPTIONS[] = {
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "license", no_argument, nullptr, 'L' },
|
||||
@@ -204,6 +206,7 @@ bool CommandlineConfig::parse() {
|
||||
{ "version", no_argument, nullptr, 'v' },
|
||||
{ "raw", no_argument, nullptr, 'w' },
|
||||
{ "no-sampler-validation", no_argument, nullptr, 'F' },
|
||||
{ "save-raw-variants", no_argument, nullptr, 'R' },
|
||||
{ nullptr, 0, nullptr, 0 } // termination of the option list
|
||||
};
|
||||
|
||||
@@ -326,6 +329,8 @@ bool CommandlineConfig::parse() {
|
||||
break;
|
||||
case 'F':
|
||||
mNoSamplerValidation = true;
|
||||
case 'R':
|
||||
mSaveRawVariants = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,10 @@ public:
|
||||
return mPrintShaders;
|
||||
}
|
||||
|
||||
bool saveRawVariants() const noexcept {
|
||||
return mSaveRawVariants;
|
||||
}
|
||||
|
||||
bool rawShaderMode() const noexcept {
|
||||
return mRawShaderMode;
|
||||
}
|
||||
@@ -149,6 +153,7 @@ protected:
|
||||
bool mPrintShaders = false;
|
||||
bool mRawShaderMode = false;
|
||||
bool mNoSamplerValidation = false;
|
||||
bool mSaveRawVariants = false;
|
||||
Optimization mOptimizationLevel = Optimization::PERFORMANCE;
|
||||
Metadata mReflectionTarget = Metadata::NONE;
|
||||
Platform mPlatform = Platform::ALL;
|
||||
|
||||
@@ -408,6 +408,7 @@ bool MaterialCompiler::run(const Config& config) {
|
||||
.targetApi(config.getTargetApi())
|
||||
.optimization(config.getOptimizationLevel())
|
||||
.printShaders(config.printShaders())
|
||||
.saveRawVariants(config.saveRawVariants())
|
||||
.generateDebugInfo(config.isDebug())
|
||||
.variantFilter(config.getVariantFilter() | builder.getVariantFilter());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user