Resampled Importance Sampling bxdfs#1027
Resampled Importance Sampling bxdfs#1027devshgraphicsprogramming wants to merge 50 commits intosampler-conceptsfrom
Conversation
…ession reciprocation (swapping of interface order) Unfortunately I realized our THINDIELECTRIC correction is badly designed
…a, won't implement right now
… mitsuba_xml_2_material_frontend
Point Boost to the exact Wave one-line backport for emitted pragma newlines, remove the temporary local pragma workaround, and keep the remaining include-path fixes in Nabla. This leaves the Wave pragma issue fixed at the dependency level while preserving the Nabla-side fixes for Windows backslash includes and single-leading-slash virtual includes. Thanks to @Themperror for the additional pragma and include repros. Those made it straightforward to verify the dependency-level fix and drop the local workaround cleanly.
…dates Fix remaining preprocess bugs and backport Wave pragma fix
…te-nsc-windows-x64-release-master CI: Promote NSC channel to 66da590
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::scalar_type)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_pdf(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.quotient_and_weight(_sample, aniso, anisocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) |
There was a problem hiding this comment.
lets make all BxDFs have a cache type which goes from generate to quotient_and_weight but then microfacet_bxdf_common would be the weird one that puts a further constraint that the anisocache_type needs to fit some concept for Cook Torrance to be useful
and allow a 2nd cache type just for eval_and_weight (the two can obviously be identical in practice, e.g. our base impl for now)
There was a problem hiding this comment.
you could actually get rid of microfacex_bdf_common and the iso_microfacet concept (basically the entire block in namespace impl ehere)
and just check that {Isotropic}MicrofacetB{R|S}DF = {Isotropic}B{R|S}DF<T> && (Isotropic ? CreatableIsotropicMicrofacetCache<typedef T::cache_type>:AnisotropicMicrofacetCache<typedef T::cache_type>);
| if (!system || outputPath.empty()) | ||
| return false; | ||
|
|
||
| const auto parent = outputPath.parent_path(); | ||
| if (!parent.empty() && !system->isDirectory(parent)) | ||
| { | ||
| if (!system->createDirectory(parent)) | ||
| return false; | ||
| } | ||
|
|
||
| auto tempPath = outputPath; | ||
| tempPath += ".tmp"; | ||
| system->deleteFile(tempPath); | ||
|
|
||
| smart_refctd_ptr<IFile> outputFile; | ||
| { | ||
| ISystem::future_t<smart_refctd_ptr<IFile>> future; | ||
| system->createFile(future, tempPath, IFileBase::ECF_WRITE); | ||
| if (!future.wait()) | ||
| return false; | ||
|
|
||
| auto lock = future.acquire(); | ||
| if (!lock) | ||
| return false; | ||
| lock.move_into(outputFile); | ||
| } | ||
| if (!outputFile) | ||
| return false; | ||
|
|
||
| if (!content.empty()) | ||
| { | ||
| IFile::success_t success; | ||
| outputFile->write(success, content.data(), 0ull, content.size()); | ||
| if (!success) | ||
| { | ||
| outputFile = nullptr; | ||
| system->deleteFile(tempPath); | ||
| return false; | ||
| } | ||
| } | ||
| outputFile = nullptr; | ||
|
|
||
| system->deleteFile(outputPath); | ||
| const auto moveError = system->moveFileOrDirectory(tempPath, outputPath); | ||
| if (moveError) | ||
| { | ||
| system->deleteFile(tempPath); | ||
| return false; | ||
| } | ||
|
|
||
| return true; |
There was a problem hiding this comment.
@AnastaZIuk do you think you could add an option to createFile flags (or pack the path+ IFileBase flaggs into a strcut) to create all the directories needed on the way to the path ?
cold be useful
…_2_material_frontend
…cet checks cache with concept
| struct Cache {}; | ||
| using isocache_type = Cache; | ||
| using anisocache_type = Cache; | ||
| using evalcache_type = Cache; |
There was a problem hiding this comment.
there should be no evalcache_type, its still same cache as for quotient and generate
But having an evalAndWeight with an overload that takes it should be a Cook Torrance / Microfacet thing only
| ((NBL_CONCEPT_REQ_TYPE)(T::anisotropic_interaction_type)) | ||
| ((NBL_CONCEPT_REQ_TYPE)(T::sample_type)) | ||
| ((NBL_CONCEPT_REQ_TYPE)(T::anisocache_type)) | ||
| ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) |
There was a problem hiding this comment.
don't require a separate evaluation cache type
| ((NBL_CONCEPT_REQ_TYPE)(T::isotropic_interaction_type)) | ||
| ((NBL_CONCEPT_REQ_TYPE)(T::isocache_type)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.eval_and_weight(_sample, iso, isocache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, iso, evalcache)), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) |
There was a problem hiding this comment.
evalAndWeight taking the anisocache or isocache should be an extra overload in the imcrofacet BxDF concepts
| } | ||
| using g2g1_query_type = typename N::g2g1_query_type; | ||
| g2g1_query_type gq = ndf.template createG2G1Query<sample_type, Interaction>(_sample, interaction); | ||
| scalar_type G2_over_G1 = ndf.template G2_over_G1<sample_type, Interaction, MicrofacetCache>(gq, _sample, interaction, cache); |
There was a problem hiding this comment.
check how well this behaves as roughness ->0 we don't want to have NaNs
There was a problem hiding this comment.
We have a check in ndfs for a<float_min
There was a problem hiding this comment.
we're bypassing a bunch of things , so there's no check
you will in-fact assert in the constructor
of the query
I mean the HLSL compiles to C++ and we have a unit test so you can go through it with a debugger I guess 🙃
I think if you know/check the PDF not being INF before setting G2_over_G1 you can guard against that
| #define NBL_CONCEPT_PARAM_3 (evalcache, typename T::evalcache_type) | ||
| NBL_CONCEPT_BEGIN(4) | ||
| #define bxdf NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0 | ||
| #define _sample NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_1 | ||
| #define aniso NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_2 | ||
| #define evalcache NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_3 | ||
| NBL_CONCEPT_END( | ||
| ((NBL_CONCEPT_REQ_TYPE)(T::evalcache_type)) | ||
| ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(bxdf_common, T)) | ||
| ((NBL_CONCEPT_REQ_TYPE_ALIAS_CONCEPT)(AnisotropicMicrofacetCache, typename T::anisocache_type)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((bxdf.evalAndWeight(_sample, aniso, evalcache)), ::nbl::hlsl::is_same_v, typename T::value_weight_type)) |
There was a problem hiding this comment.
cool but evalcache needs to be just microfacetCache and be of type T::cache_type
There was a problem hiding this comment.
no evalcache_type
| ((NBL_CONCEPT_REQ_TYPE)(T::object_handle_type)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getSample()), ::nbl::hlsl::is_same_v, typename T::sample_type)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getQuotientPdf()), ::nbl::hlsl::is_same_v, typename T::quotient_pdf_type)) | ||
| ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((sqr.getQuotientPdf()), ::nbl::hlsl::is_same_v, typename T::quotient_weight_type)) |
There was a problem hiding this comment.
getQuotientPdf rename to getQuotientAndWeight
Description
Testing
TODO list: