diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 7017f2a083..c1d7c05f79 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -540,7 +540,7 @@ Menu::Menu() { action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::MaterialProceduralShaders, 0, false); connect(action, &QAction::triggered, [action] { - ModelMeshPartPayload::enableMaterialProceduralShaders = action->isChecked(); + Procedural::enableProceduralShaders = action->isChecked(); }); { diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index 91b949e280..5a27d393bc 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -28,6 +28,8 @@ Q_LOGGING_CATEGORY(proceduralLog, "hifi.gpu.procedural") +bool Procedural::enableProceduralShaders = false; + // User-data parsing constants static const QString PROCEDURAL_USER_DATA_KEY = "ProceduralEntity"; static const QString VERTEX_URL_KEY = "vertexShaderURL"; @@ -377,16 +379,27 @@ void Procedural::prepare(gpu::Batch& batch, _proceduralPipelines[key] = gpu::Pipeline::create(program, key.isTransparent() ? _transparentState : _opaqueState); + // Error falllback: pink checkerboard if (_errorFallbackFragmentSource.isEmpty()) { QFile file(_errorFallbackFragmentPath); file.open(QIODevice::ReadOnly); _errorFallbackFragmentSource = QTextStream(&file).readAll(); } + vertexSource.replacements.erase(PROCEDURAL_BLOCK); fragmentSource.replacements[PROCEDURAL_BLOCK] = _errorFallbackFragmentSource.toStdString(); + gpu::ShaderPointer errorVertexShader = gpu::Shader::createVertex(vertexSource); gpu::ShaderPointer errorFragmentShader = gpu::Shader::createPixel(fragmentSource); - gpu::ShaderPointer errorProgram = gpu::Shader::createProgram(vertexShader, errorFragmentShader); + gpu::ShaderPointer errorProgram = gpu::Shader::createProgram(errorVertexShader, errorFragmentShader); _errorPipelines[key] = gpu::Pipeline::create(errorProgram, _opaqueState); + // Disabled falllback: nothing + vertexSource.replacements.erase(PROCEDURAL_BLOCK); + fragmentSource.replacements.erase(PROCEDURAL_BLOCK); + gpu::ShaderPointer disabledVertexShader = gpu::Shader::createVertex(vertexSource); + gpu::ShaderPointer disabledFragmentShader = gpu::Shader::createPixel(fragmentSource); + gpu::ShaderPointer disabledProgram = gpu::Shader::createProgram(disabledVertexShader, disabledFragmentShader); + _disabledPipelines[key] = gpu::Pipeline::create(disabledProgram, _opaqueState); + _lastCompile = usecTimestampNow(); if (_firstCompile == 0) { _firstCompile = _lastCompile; @@ -396,7 +409,9 @@ void Procedural::prepare(gpu::Batch& batch, } gpu::PipelinePointer finalPipeline = recompiledShader ? _proceduralPipelines[key] : pipeline->second; - if (!finalPipeline || finalPipeline->getProgram()->compilationHasFailed()) { + if (!enableProceduralShaders) { + finalPipeline = _disabledPipelines[key]; + } else if (!finalPipeline || finalPipeline->getProgram()->compilationHasFailed()) { finalPipeline = _errorPipelines[key]; } diff --git a/libraries/procedural/src/procedural/Procedural.h b/libraries/procedural/src/procedural/Procedural.h index 3b78563b40..9e6f102e36 100644 --- a/libraries/procedural/src/procedural/Procedural.h +++ b/libraries/procedural/src/procedural/Procedural.h @@ -124,7 +124,7 @@ public: gpu::Shader::Source _opaqueFragmentSource; gpu::Shader::Source _transparentFragmentSource; - QString _errorFallbackFragmentSource; + QString _errorFallbackFragmentPath; gpu::StatePointer _opaqueState { std::make_shared() }; gpu::StatePointer _transparentState { std::make_shared() }; @@ -132,6 +132,8 @@ public: static std::function opaqueStencil; static std::function transparentStencil; + static bool enableProceduralShaders; + protected: // DO NOT TOUCH // We have to pack these in a particular way to match the ProceduralCommon.slh @@ -178,7 +180,7 @@ protected: bool _shaderDirty { true }; bool _uniformsDirty { true }; - QString _errorFallbackFragmentPath; + QString _errorFallbackFragmentSource; // Rendering objects UniformLambdas _uniforms; @@ -186,6 +188,7 @@ protected: std::unordered_map _proceduralPipelines; std::unordered_map _errorPipelines; + std::unordered_map _disabledPipelines; StandardInputs _standardInputs; gpu::BufferPointer _standardInputsBuffer; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index e095d9b15d..a77dc6b160 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -25,8 +25,6 @@ using namespace render; -bool ModelMeshPartPayload::enableMaterialProceduralShaders = false; - ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, int partIndex, int shapeIndex, const Transform& transform, const uint64_t& created) : _meshIndex(meshIndex), @@ -345,9 +343,6 @@ void ModelMeshPartPayload::render(RenderArgs* args) { } if (_shapeKey.hasOwnPipeline()) { - if (!(enableMaterialProceduralShaders)) { - return; - } auto procedural = std::static_pointer_cast(_drawMaterials.top().material); auto& schema = _drawMaterials.getSchemaBuffer().get(); glm::vec4 outColor = glm::vec4(ColorUtils::tosRGBVec3(schema._albedo), schema._opacity); diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index b502865f94..0818340981 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -68,8 +68,6 @@ public: void setBlendshapeBuffer(const std::unordered_map& blendshapeBuffers, const QVector& blendedMeshSizes); - static bool enableMaterialProceduralShaders; - private: void initCache(const ModelPointer& model, int shapeID);