diff --git a/CMakeLists.txt b/CMakeLists.txt index 62d09c25..10aa5f8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,8 +137,8 @@ target_compile_options ( # python3 (for building python binding) ############################################################################### list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/ext/pybind11/tools") -set(KRR_PYTHON_EXECUTABLE "" CACHE STRING "Path to selected python executable") -set(Python_ROOT_DIR ${KRR_PYTHON_EXECUTABLE}) +set(KRR_PYTHON_PATH "" CACHE STRING "Path to selected python executable") +set(Python_ROOT_DIR ${KRR_PYTHON_PATH}) find_package(Python COMPONENTS Interpreter Development) if (Python_FOUND) set(KRR_ENABLE_PYTHON ON) diff --git a/README.md b/README.md index 1db84b8f..03898511 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,13 @@ git clone --recursive https://github.com/cuteday/KiRaRay.git #### Building -This project uses cmake to build, Make sure cuda is installed and added to PATH, and `OptiX_INSTALL_DIR` environment variable points to the OptiX installation directory. +This project uses cmake to build, make sure CUDA is installed and added to PATH. Several optional variables are available for building configuration. + +| Variable | Default | Description | +| ----------------------- | ----------- | ------------------------------------------------------------ | +| `OptiX_INSTALL_DIR` | auto-detect | When auto-detection failed to find the correct OptiX path, this variable needs to be manually specified to point to the OptiX installation. | +| `KRR_RENDER_SPECTRAL` | ON | Whether to build spectral render. If turned OFF, the RGB renderer is build. | +| `KRR_PYTHON_PATH` | auto-detect | Manually specify this to enable Python binding for a specific version of Python. | #### Running @@ -54,8 +60,6 @@ build/src/kiraray.exe common/configs/example_cbox.json > The two necessary entries in the configuration are `model` (specifying the relative path to the scene file) and `passes` (describing the render pipeline). Once compiled, directly run `kiraray` without specifying configuration (this [example configuration](common/configs/example_cbox.json) will be used) to get a feel for this toy renderer. - - #### Usage **Camera controlling.** Dragging `LeftMouse` for orbiting, dragging `Scroll` or `Shift+LeftMouse` for panning. `Scroll` for zooming in/out. diff --git a/common/scripts/README.md b/common/scripts/README.md index 023d0024..b373d2ca 100644 --- a/common/scripts/README.md +++ b/common/scripts/README.md @@ -1,6 +1,6 @@ # KiRaRay Python Binding -The python binding should be compiled with the same version of Python as the binding is intended to be used. To specify the python version, set the `KRR_PYTHON_EXECUTABLE` variable to the folder that containing the python executable. +The python binding should be compiled with the same version of Python as the binding is intended to be used. To specify the python version, set the `KRR_PYTHON_PATH` variable to the folder that containing the python executable. > After Python 3.8, the search paths of DLL dependencies has been reset. Only the system paths, the directory containing the DLL or PYD file are searched for load-time dependencies. Instead, a new function os.add_dll_directory() was added to supply additional search paths. Necessary DLL paths are exported from `pykrr_common`, see [krr.py](krr.py) for details. diff --git a/src/main/kiraray.cpp b/src/main/kiraray.cpp index 41068800..fd2872f8 100644 --- a/src/main/kiraray.cpp +++ b/src/main/kiraray.cpp @@ -14,7 +14,7 @@ extern "C" int main(int argc, char *argv[]) { "Switch to Release build for normal performance!"); #endif - string configFile = "common/configs/test/cboxexplosion.json"; + string configFile = "common/configs/example_cbox.json"; if (argc < 2){ Log(Warning, "No config file specified, using default config file: %s", configFile.c_str()); } else { diff --git a/src/render/materials/disney.h b/src/render/materials/disney.h index 8f38c278..70d9dead 100644 --- a/src/render/materials/disney.h +++ b/src/render/materials/disney.h @@ -4,6 +4,7 @@ #include "common.h" #include "render/shared.h" +#include "render/sampling.h" #include "util/math_utils.h" @@ -301,26 +302,31 @@ class DisneyBsdf { KRR_CALLABLE BSDFSample sample(Vector3f wo, Sampler &sg, TransportMode mode = TransportMode::Radiance) const { BSDFSample sample; - float comp = sg.get1D(); - if (comp < pDiffuse) { - Vector3f wi = cosineSampleHemisphere(sg.get2D()); - if (wo[2] < 0) wi[2] *= -1; - sample.pdf = pdf(wo, wi); - sample.f = f(wo, wi); - sample.wi = wi; - sample.flags = BSDF_DIFFUSE_REFLECTION; - } else if (comp < pDiffuse + pSpecRefl) { - sample = microfacetBrdf.sample(wo, sg, mode); - sample.pdf *= pSpecRefl; - if (pDiffuse && sample.isNonSpecular()) { - // TODO: validate if you should disable other components when sampled an delta component. - sample.f += disneyDiffuse.f(wo, sample.wi); - sample.f += disneyRetro.f(wo, sample.wi); - sample.pdf += pDiffuse * AbsCosTheta(sample.wi) * M_INV_PI; + int comp = sampleDiscrete({pDiffuse, pSpecRefl, pSpecTrans}, sg.get1D()); + switch (comp) { + case 0: { + Vector3f wi = cosineSampleHemisphere(sg.get2D()); + if (wo[2] < 0) wi[2] *= -1; + sample.pdf = pdf(wo, wi); + sample.f = f(wo, wi); + sample.wi = wi; + sample.flags = BSDF_DIFFUSE_REFLECTION; + break; + } case 1: { + sample = microfacetBrdf.sample(wo, sg, mode); + sample.pdf *= pSpecRefl; + if (pDiffuse && sample.isNonSpecular()) { + // NOTE: disable other components when sampled an delta component. + sample.f += disneyDiffuse.f(wo, sample.wi); + sample.f += disneyRetro.f(wo, sample.wi); + sample.pdf += pDiffuse * AbsCosTheta(sample.wi) * M_INV_PI; + } + break; + } case 2: { + sample = microfacetBtdf.sample(wo, sg, mode); + sample.pdf *= pSpecTrans; + break; } - } else if (pSpecTrans > 0) { - sample = microfacetBtdf.sample(wo, sg, mode); - sample.pdf *= pSpecTrans; } return sample; } diff --git a/src/render/materials/principled.h b/src/render/materials/principled.h index c651f2e5..ced3b1ab 100644 --- a/src/render/materials/principled.h +++ b/src/render/materials/principled.h @@ -157,42 +157,45 @@ class PrincipledBsdf { KRR_CALLABLE BSDFSample sample(Vector3f wo, Sampler &sg, TransportMode mode = TransportMode::Radiance) const { BSDFSample sample{}; - float comp = sg.get1D(); - if (comp < pDiffuse) { - Vector3f wi = cosineSampleHemisphere(sg.get2D()); - if (wo[2] < 0) - wi[2] *= -1; - sample.pdf = pdf(wo, wi, mode); - sample.f = f(wo, wi, mode); - sample.wi = wi; - sample.flags = BSDF_DIFFUSE_REFLECTION; - } else if (comp < pDiffuse + pMetal) { - sample = metalBrdf.sample(wo, sg, mode); - sample.pdf *= pMetal; - if (pDiffuse > 0) { - sample.f += weightDiffuse * disneyDiffuse.f(wo, sample.wi); - sample.f += weightDiffuse * disneyRetro.f(wo, sample.wi); - sample.pdf += pDiffuse * AbsCosTheta(sample.wi) * M_INV_PI; - } - if (pGlass > 0) { - sample.f += weightGlass * glassBsdf.f(wo, sample.wi, mode); - sample.pdf += pGlass * glassBsdf.pdf(wo, sample.wi, mode); - } - } else if (pGlass > 0) { - sample = glassBsdf.sample(wo, sg); - if (!sample.f.any() || sample.pdf == 0) - return {}; - sample.pdf *= pGlass; - if (SameHemisphere(wo, sample.wi)) { + int comp = sampleDiscrete({pDiffuse, pMetal, pGlass}, sg.get1D()); + switch (comp) { + case 0: { + Vector3f wi = cosineSampleHemisphere(sg.get2D()); + if (wo[2] < 0) wi[2] *= -1; + sample.pdf = pdf(wo, wi, mode); + sample.f = f(wo, wi, mode); + sample.wi = wi; + sample.flags = BSDF_DIFFUSE_REFLECTION; + break; + } case 1: { + sample = metalBrdf.sample(wo, sg, mode); + sample.pdf *= pMetal; if (pDiffuse > 0) { sample.f += weightDiffuse * disneyDiffuse.f(wo, sample.wi); sample.f += weightDiffuse * disneyRetro.f(wo, sample.wi); sample.pdf += pDiffuse * AbsCosTheta(sample.wi) * M_INV_PI; } - if (pMetal > 0) { - sample.f += weightMetal * metalBrdf.f(wo, sample.wi, mode); - sample.pdf += pMetal * metalBrdf.pdf(wo, sample.wi, mode); + if (pGlass > 0) { + sample.f += weightGlass * glassBsdf.f(wo, sample.wi, mode); + sample.pdf += pGlass * glassBsdf.pdf(wo, sample.wi, mode); + } + break; + } case 2: { + sample = glassBsdf.sample(wo, sg); + if (!sample.f.any() || sample.pdf == 0) return {}; + sample.pdf *= pGlass; + if (SameHemisphere(wo, sample.wi)) { + if (pDiffuse > 0) { + sample.f += weightDiffuse * disneyDiffuse.f(wo, sample.wi); + sample.f += weightDiffuse * disneyRetro.f(wo, sample.wi); + sample.pdf += pDiffuse * AbsCosTheta(sample.wi) * M_INV_PI; + } + if (pMetal > 0) { + sample.f += weightMetal * metalBrdf.f(wo, sample.wi, mode); + sample.pdf += pMetal * metalBrdf.pdf(wo, sample.wi, mode); + } } + break; } } return sample;