diff --git a/source/MaterialXView/RenderPipeline.h b/source/MaterialXView/RenderPipeline.h index 03b28c6db7..82f5990513 100644 --- a/source/MaterialXView/RenderPipeline.h +++ b/source/MaterialXView/RenderPipeline.h @@ -50,7 +50,6 @@ class RenderPipeline virtual void bakeTextures() = 0; virtual void updateAlbedoTable(int tableSize) = 0; - virtual mx::ImagePtr convolveEnvironment() = 0; virtual std::shared_ptr createTextureBaker(unsigned int width, unsigned int height, mx::Image::BaseType baseType) = 0; diff --git a/source/MaterialXView/RenderPipelineGL.cpp b/source/MaterialXView/RenderPipelineGL.cpp index 78af95047d..aec0b4097e 100644 --- a/source/MaterialXView/RenderPipelineGL.cpp +++ b/source/MaterialXView/RenderPipelineGL.cpp @@ -110,7 +110,7 @@ void GLRenderPipeline::updateAlbedoTable(int tableSize) glDrawBuffer(GL_BACK); } -mx::ImagePtr GLRenderPipeline::convolveEnvironment() +void GLRenderPipeline::convolveEnvironment() { auto& genContext = _viewer->_genContext; auto& lightHandler = _viewer->_lightHandler; @@ -128,7 +128,6 @@ mx::ImagePtr GLRenderPipeline::convolveEnvironment() catch (std::exception& e) { new ng::MessageDialog(_viewer, ng::MessageDialog::Type::Warning, "Failed to generate convolution shader", e.what()); - return nullptr; } mx::ImagePtr srcTex = lightHandler->getEnvRadianceMap(); @@ -182,7 +181,7 @@ mx::ImagePtr GLRenderPipeline::convolveEnvironment() glViewport(0, 0, _viewer->m_fbsize[0], _viewer->m_fbsize[1]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - return outTex; + lightHandler->setEnvRadianceMapPreConvolved(outTex); } mx::ImagePtr GLRenderPipeline::getShadowMap(int shadowMapSize) diff --git a/source/MaterialXView/RenderPipelineGL.h b/source/MaterialXView/RenderPipelineGL.h index 1f7cd6322c..c0e5ba9174 100644 --- a/source/MaterialXView/RenderPipelineGL.h +++ b/source/MaterialXView/RenderPipelineGL.h @@ -31,7 +31,6 @@ class GLRenderPipeline : public RenderPipeline mx::ImageHandlerPtr createImageHandler() override; mx::MaterialPtr createMaterial() override; void updateAlbedoTable(int tableSize) override; - mx::ImagePtr convolveEnvironment() override; std::shared_ptr createTextureBaker(unsigned int width, unsigned int height, mx::Image::BaseType baseType) override; @@ -44,6 +43,7 @@ class GLRenderPipeline : public RenderPipeline protected: mx::ImagePtr getShadowMap(int shadowMapSize) override; + void convolveEnvironment(); }; #endif // RENDER_PIPELINE_GL_H diff --git a/source/MaterialXView/RenderPipelineMetal.h b/source/MaterialXView/RenderPipelineMetal.h index 6510b8b4d8..1ffeec6d7d 100644 --- a/source/MaterialXView/RenderPipelineMetal.h +++ b/source/MaterialXView/RenderPipelineMetal.h @@ -40,7 +40,6 @@ class MetalRenderPipeline : public RenderPipeline mx::ImageHandlerPtr createImageHandler() override; mx::MaterialPtr createMaterial() override; void updateAlbedoTable(int tableSize) override; - mx::ImagePtr convolveEnvironment() override; void renderFrame(void* color_texture, int shadowMapSize, const char* dirLightNodeCat) override; void bakeTextures() override; mx::ImagePtr getFrameImage() override; @@ -51,7 +50,9 @@ class MetalRenderPipeline : public RenderPipeline protected: mx::ImagePtr getShadowMap(int shadowMapSize) override; mx::MetalFramebufferPtr _shadowMapFramebuffer; + mx::MetalFramebufferPtr _preConvolutionFramebuffer; mx::ImagePtr _shadowMap[SHADOWMAP_TEX_COUNT]; + void convolveEnvironment(); }; #endif // RENDER_PIPELINE_METAL_H diff --git a/source/MaterialXView/RenderPipelineMetal.mm b/source/MaterialXView/RenderPipelineMetal.mm index bc47df9b1b..1062789c52 100644 --- a/source/MaterialXView/RenderPipelineMetal.mm +++ b/source/MaterialXView/RenderPipelineMetal.mm @@ -155,13 +155,18 @@ } } -mx::ImagePtr MetalRenderPipeline::convolveEnvironment() +void MetalRenderPipeline::convolveEnvironment() { auto& genContext = _viewer->_genContext; auto& lightHandler = _viewer->_lightHandler; auto& imageHandler = _viewer->_imageHandler; mx::MetalTextureHandlerPtr mtlImageHandler = std::dynamic_pointer_cast(imageHandler); + if (lightHandler->getEnvRadianceMapPreConvolved()) + { + return; + } + mx::ImagePtr srcTex = lightHandler->getEnvRadianceMap(); int w = srcTex->getWidth(); int h = srcTex->getHeight(); @@ -172,15 +177,15 @@ // Create framebuffer. - mx::MetalFramebufferPtr framebuffer = mx::MetalFramebuffer::create( + _preConvolutionFramebuffer = mx::MetalFramebuffer::create( MTL(device), w, h, 4, - mx::Image::BaseType::UINT8, // TODO: Should this be HALF? + mx::Image::BaseType::HALF, metalTex ); - MTL_PUSH_FRAMEBUFFER(framebuffer); + MTL_PUSH_FRAMEBUFFER(_preConvolutionFramebuffer); int i = 0; @@ -192,7 +197,7 @@ [desc.colorAttachments[0] setLevel:i]; [desc.colorAttachments[0] setLoadAction:MTLLoadActionDontCare]; [desc.colorAttachments[0] setStoreAction:MTLStoreActionStore]; - [desc.depthAttachment setTexture:framebuffer->getDepthTexture()]; + [desc.depthAttachment setTexture:_preConvolutionFramebuffer->getDepthTexture()]; [desc.depthAttachment setLoadAction:MTLLoadActionDontCare]; [desc.depthAttachment setStoreAction:MTLStoreActionDontCare]; [desc setStencilAttachment:nil]; @@ -211,10 +216,9 @@ catch (std::exception& e) { new ng::MessageDialog(_viewer, ng::MessageDialog::Type::Warning, "Failed to generate convolution shader", e.what()); - return nullptr; } - framebuffer->bind(desc); + _preConvolutionFramebuffer->bind(desc); material->bindShader(); material->getProgram()->bindUniform(mx::HW::CONVOLUTION_MIP_LEVEL, mx::Value::createValue(i)); @@ -240,7 +244,7 @@ MTL_POP_FRAMEBUFFER(); - return outTex; + lightHandler->setEnvRadianceMapPreConvolved(outTex); } mx::ImagePtr MetalRenderPipeline::getShadowMap(int shadowMapSize) @@ -403,6 +407,10 @@ auto& searchPath = _viewer->_searchPath; auto& geometryHandler = _viewer->_geometryHandler; + if (lightHandler->getUsePreConvolvedEnvLighting()) + { + convolveEnvironment(); + } // Update lighting state. lightHandler->setLightTransform(mx::Matrix44::createRotationY(lightRotation / 180.0f * M_PI)); diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index 754ca7beda..ebba46e185 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -505,11 +505,11 @@ void Viewer::loadEnvironmentLight() // Release any existing environment maps and store the new ones. _imageHandler->releaseRenderResources(_lightHandler->getEnvRadianceMap()); + _lightHandler->setEnvRadianceMapPreConvolved(nullptr); + _imageHandler->releaseRenderResources(_lightHandler->getEnvRadianceMapPreConvolved()); _imageHandler->releaseRenderResources(_lightHandler->getEnvIrradianceMap()); _lightHandler->setEnvRadianceMap(envRadianceMap); - mx::ImagePtr preConvolvedEnvRadianceMap = _renderPipeline->convolveEnvironment(); - _lightHandler->setEnvRadianceMapPreConvolved(preConvolvedEnvRadianceMap); _lightHandler->setEnvIrradianceMap(envIrradianceMap); // Look for a light rig using an expected filename convention.