From b8d4b981e0b59eb34fdb3bcdde477f34558cf398 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 6 Jan 2020 16:48:21 -0800 Subject: [PATCH] Better roughness remapping and comments We were conflating two concepts in our comments about the roughness remapping, which was confusing. Also changed the remapping so it matches a log2 mapping in our default configuration. --- docs/math/IBL Roughness Remapping.nb | 282 --------------------------- shaders/src/light_indirect.fs | 8 +- tools/cmgen/src/cmgen.cpp | 18 +- 3 files changed, 16 insertions(+), 292 deletions(-) delete mode 100644 docs/math/IBL Roughness Remapping.nb diff --git a/docs/math/IBL Roughness Remapping.nb b/docs/math/IBL Roughness Remapping.nb deleted file mode 100644 index 3849d4dfba..0000000000 --- a/docs/math/IBL Roughness Remapping.nb +++ /dev/null @@ -1,282 +0,0 @@ -(* Content-type: application/vnd.wolfram.mathematica *) - -(*** Wolfram Notebook File ***) -(* http://www.wolfram.com/nb *) - -(* CreatedBy='Mathematica 12.0' *) - -(*CacheID: 234*) -(* Internal cache information: -NotebookFileLineBreakTest -NotebookFileLineBreakTest -NotebookDataPosition[ 158, 7] -NotebookDataLength[ 10780, 274] -NotebookOptionsPosition[ 9948, 252] -NotebookOutlinePosition[ 10286, 267] -CellTagsIndexPosition[ 10243, 264] -WindowFrame->Normal*) - -(* Beginning of Notebook Content *) -Notebook[{ - -Cell[CellGroupData[{ -Cell[BoxData[{ - RowBox[{ - RowBox[{"f", "[", "x_", "]"}], ":=", - RowBox[{ - RowBox[{ - RowBox[{"(", - RowBox[{"2", "/", - RowBox[{"(", - RowBox[{ - RowBox[{ - RowBox[{"(", - RowBox[{ - RowBox[{"2", "/", - RowBox[{"(", - RowBox[{"x", "^", "4"}], ")"}]}], "-", "2"}], ")"}], "/", "4"}], - "+", "2"}], ")"}]}], ")"}], "^", - RowBox[{"(", - RowBox[{"1", "/", "4"}], ")"}]}], "/;", - RowBox[{"x", ">", "0"}]}]}], "\[IndentingNewLine]", - RowBox[{ - RowBox[{"f", "[", "x_", "]"}], ":=", " ", - RowBox[{"0", "/;", - RowBox[{"x", "==", "0"}]}]}], "\[IndentingNewLine]", - RowBox[{ - RowBox[{"data", " ", ":=", " ", - RowBox[{"Table", "[", - RowBox[{ - RowBox[{"{", - RowBox[{"x", ",", - RowBox[{"f", "[", "x", "]"}]}], "}"}], ",", - RowBox[{"{", - RowBox[{"x", ",", " ", "0", ",", "1", ",", "0.01"}], "}"}]}], "]"}]}], - ";"}], "\[IndentingNewLine]", - RowBox[{"parabola", " ", "=", " ", - RowBox[{"Normal", "[", - RowBox[{"NonlinearModelFit", "[", - RowBox[{"data", ",", " ", - RowBox[{"{", - RowBox[{ - RowBox[{ - RowBox[{"a", "*", "x"}], "+", - RowBox[{"b", "*", - RowBox[{"x", "^", "2"}]}]}], ",", " ", - RowBox[{ - RowBox[{"a", "+", "b"}], "\[Equal]", "1"}]}], "}"}], ",", " ", - RowBox[{"{", - RowBox[{"a", ",", "b"}], "}"}], ",", " ", "x"}], "]"}], - "]"}]}], "\[IndentingNewLine]", - RowBox[{"Show", "[", - RowBox[{ - RowBox[{"ListPlot", "[", - RowBox[{"data", ",", - RowBox[{"PlotStyle", "\[Rule]", "Red"}]}], "]"}], ",", - RowBox[{"Plot", "[", - RowBox[{ - RowBox[{"{", - RowBox[{"line", ",", "parabola"}], "}"}], ",", - RowBox[{"{", - RowBox[{"x", ",", "0", ",", "1"}], "}"}]}], "]"}]}], - "]"}], "\[IndentingNewLine]"}], "Input", - CellChangeTimes->{{3.7853013256245613`*^9, 3.785301390186495*^9}, { - 3.785301421642477*^9, 3.785301465776168*^9}, {3.7853017515859756`*^9, - 3.785301908525689*^9}, {3.7853020327027817`*^9, 3.785302034437195*^9}, { - 3.7853020894218187`*^9, 3.785302202204063*^9}, {3.78530224866191*^9, - 3.78530224882778*^9}, {3.785302350469426*^9, 3.785302438172524*^9}, { - 3.7853025481243563`*^9, 3.785302567825976*^9}, {3.785302633764064*^9, - 3.785302690969706*^9}, {3.785302769267284*^9, 3.785302773737165*^9}, { - 3.7853028214660187`*^9, 3.7853029304252*^9}, {3.7853030462655373`*^9, - 3.785303046432098*^9}, {3.7853031781549597`*^9, 3.785303235566655*^9}, - 3.785303564600515*^9, {3.785303597702798*^9, 3.78530363051826*^9}, { - 3.785303692790189*^9, 3.7853036993481417`*^9}, {3.7853041621306343`*^9, - 3.785304162224794*^9}, {3.785304507674033*^9, 3.78530453730317*^9}}, - CellLabel-> - "In[217]:=",ExpressionUUID->"85027ebf-eb4f-4561-8636-5abaa20a4e91"], - -Cell[BoxData[ - RowBox[{ - RowBox[{"1.6859867495347762`", " ", "x"}], "-", - RowBox[{"0.6859867495347762`", " ", - SuperscriptBox["x", "2"]}]}]], "Output", - CellChangeTimes->{3.785305622578298*^9}, - CellLabel-> - "Out[220]=",ExpressionUUID->"fed6f178-4c96-4662-aea8-90e31d064e10"], - -Cell[BoxData[ - GraphicsBox[{{{}, { - {RGBColor[1, 0, 0], PointSize[0.009166666666666668], AbsoluteThickness[ - 1.6], PointBox[CompressedData[" -1:eJxdkntMU3cUx+kUBUGHrIA8ZJHABm5hinMzTvd1i4oMBNtNicIQEabLeEiY -8nBuugCNilAHMlAhQySCCA4DoThAeYkIapFHKfLoi9L37ZQSozhn68n+2Elu -bu7jd873+/2cFTFJ3Li3rKys4l5f5vv/6yi7NlCakYnExXtCzszm4M1zAVh5 -153OzF6EwDNLyxGUYqSs2FMtqKDvlxF806b65Ow1nC82VxVeFv3Q7uh2g/6v -xY6HTT5jggboOOY3dTi8Wd1SEt5E5+uRmF7D+nq2GYtE5Yc2LmpE2rmOmYyv -blO/Jmw/3hF5y7UdfpF57SbfZrxXd3Xqb1UH9W8Fzyn0mr2gC5dfnxaV30au -6fklG143zWtD9aLA1PGdPVhjqQ6MTnLTTnj30vxO+LdePKZ+0ocOk+/rCV3w -YfMe2LQ9ID3d8Fj6bdbBQCG4loF3UTxyx9bVv5/09eDG9l0vctiPIM0wN7yH -n35kJ9x8/oj09oG7wPNwoWQAyWZ5h+6DVZXu7XRnkPQ/wAx3wXG/6iG8oSCE -qK4ioytvmPwIEdDbbRSniLDNMqAfA8+PVewKHyF//VD2f/bFyvVimKdF5j2C -Czue+6XHKPkdgGjJq7DTL0dhsSMaAKveqdQ4/pj8DyLET1MQ2TKGd81yPIfw -Suh4SnBhnPIYQr7XujFd2gQOfGeuYfxiCmNJv5mkfEQwOTb0trhIYO7GrhWh -bp/tBk6mhPIagUu114HlRglmze1MI+isSv6dHSGl/MRwHrsn9u2S4nNLw1Ew -/Bd2If4yynMUzQnxuqRCGSzysh4jdXXDyuyXMsp3DAleVunH98txv89cY4jL -dC7dcVdOeY9DL9TwVB8o4GQROIGdEclR63MVlP8EGusKCtcxCljaRU7CJ9fB -ejh0inhIkFY+Z7SumSI/EgQ7C32abZXER4Kcd67M18cqyZ8EgYJzBWdalcRL -Cpu9w2fznafJrxTNuyuOmuKniZ8UQYvL/rjaNk3+ZViz6rRfNVtFPGVwTA71 -MsapKA8ZCsQBJ1IaVMRXDkVNwIer5qkpHzk6l38/tyJMTbzlCKi8cGtLsZry -UoAbq/y0WKom/gqsDTnv6u6rofwUKH8Vs7A3XkP7MIVcj4c5Vdc1lOcUhrwj -XARGDe3HFKzlXoZnH2kpXyXmQqN9kxK0tC9KvM2WXvKs0lLeSlxaWjJjJ9fS -/kzDhlcUs8FdR/lPo8l7w0ADR0f7NI2N9iFtP2friIcKdqbL/qVNOuKhwgBH -Ueiu1REPFYpOLpf946YnHirMbvwrfEeQnniood1SeXbZET3xUOPGbyNJ0WV6 -4qGGe9NW+9W9euKhwc2Dqdfzn+rBt/DQYF4nv+usm4F4aDB/r8Pgx5sMxEOL -PX++fyg71kA8tBCzOtfyeQbioUVU8uZbEVUG4qEDf/dEyZMeA/HQIZlXy41S -G4iHDhFPU7ZVLmSIhx7WQcx9sTdDPPRIjJI6zG1iiIcekp4y12WRDPEwIHjJ -1u5PjjDEw4CtoZy+6DyGeBjQ6K6oLr3CEA8G+7r3Nz5rZYgHg4lf+fapQwzx -YBBczypYoWWIh/G/+7/CryID - "]]}, { - {RGBColor[1, 0, 0], PointSize[0.009166666666666668], AbsoluteThickness[ - 1.6]}, {}}, { - {RGBColor[1, 0, 0], PointSize[0.009166666666666668], AbsoluteThickness[ - 1.6]}, {}}}, {{}, {}}}, {{{}, {}, {}, - TagBox[ - {RGBColor[0.880722, 0.611041, 0.142051], AbsoluteThickness[1.6], - Opacity[1.], LineBox[CompressedData[" -1:eJwVkHk4FHgcxh2TDqXEplF4XB2qVTlaK71ZNqLLtbRuG8rutDr2wW7XuLaN -jCLZCEXnbAaNNqWISbLKHTLNjDGmmTEzP5IkYqc/vs/n+X6f932f9/maRvzq -Hamhpqa2UzVf6BEpaauV+m05UeW0dCo+YgvFxTCWT7XF9qxxm8iRrbApzM2/ -S3XF/QV+ZZXDe+D5orviMtUXuzwp+hkkDP77xh+dp+5Dr4yb+aMiFm+s/3Q5 -Sz2K5Zs9I9Wlp1D01e7UM9RkPIhOnfQTZII+5+7Kv6jZoGv+U6DRUoSAvVdY -wyMlMPG38+8JKof2DD3IzZgFPQdSeuRCFSy9lJL6NDZmeM6uq57UIu6lA3Lf -V8EmnJHv9okDA7YuT129BlqUMoVFbyPuCV2aWzbXoSO/9obDeDPqYi4v2yvn -oH9xHWtBXCvGVjgtvEN7Bjp/xDjerR0aE8xFyyybMP9g+JSvXSfsZ8Lu+ZSq -fI+7ZU4TXWhOtn3ZYNWCzMlcnwpmN0wyhyZuKVuxNto163hCL4bG+byu9e2I -8dDzCjfpQ4nsYZNORgcqEo6HC3hc6BjdICJRJ4wrbiY5p/OQfqAyqsjiFaza -6kxkcwX4sJUp2n+yGy9D+7fRegU4upHDXlLfA3PaE4PzOf3gl3LS2kxfI5ji -QM6FCDEZ05m3+vc+tMg2vZYZDWCN8+zpqIdcaDoXW4/+NwC3q6bR5QY8GN7U -in2SJEKcUahZfxAfbYmbcxqtBrFW7qfdvVOAY+ynDY5Ng9BbODyH80kArbal -BVGHxaDU5LHM8/uhc2jW7LZ5b/Gz7cPeuZ5ChLUWvdNnvgVze0TR4w9CdNEF -OrEuEowNGS4S5wzgc1pVjcELCSp93DSzXUU4caDoUnKwFCfdUwrZYhECpOfN -n/GlMH3j0VOcMgjmLp1FNoEyfLspOZu6UYwQZfS1H7gyBBm3TKh3iBFrIX3l -t2cIY01nhbH0t4hour3G+vkQcikhR70tJKCVJ3XS7OTQ41Ve1eBI8LHca75T -nhyzjtN9HQ5JIS4svd1NUUDtVghLuFgGeZbZY16EAocvsc4urpMhg7Gkor1e -gUdrTs/RPTiE1HSxnYaxEroeh9cm6sgxQtW6waQpwV3X2pFQLUdGFH3luhol -ygpgIQpRwNzWfahciyCYZa9rNK3AMpFQluxOcCrlCp17W4me4BVqZmkEdyRG -eTo7CNjq86obOQSnL6eE8XYRZBlabqt9SrDPW2FZ6kXwIfBYwr8NBMurq8t2 -+hNsDeD3lTQSnGEENqRHEIzaxzH+aCbYb//3yLwEgrp0ZfnSTgKzZH332dcJ -tC9NDugOEEx/c2xB902CDfV5F6ZVe69ioP06k4CrHz8sExFk+t8N3lau6rNh -8EqdmGDGyvtISjVBkte5UZpMpWtjFGh2EKSv3uDNHiG4nzr+U0cXQc/rrIt5 -7wiyHUNXF/cQFLM3piaOEnhe+5r9HY+A028RunuM4EH8i+d0qaqXWd+M6CNB -zjo7hpec4KSBCeP5BMEhYb6vKVH9za7w2Z1PBKt2/MKvfa/Kk/nY/jZFQFHv -LMkcJ5ibeHp/wGcCQaVjTJhKN+w88b3jNEF1TLH1etU90Op6s9EMwUUT7bEZ -Fd0cGVNf+D+FDYXk - "]]}, - Annotation[#, "Charting`Private`Tag$12958#2"]& ]}, {}}}, - AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], - Axes->{True, True}, - AxesLabel->{None, None}, - AxesOrigin->{0, 0}, - DisplayFunction->Identity, - Frame->{{False, False}, {False, False}}, - FrameLabel->{{None, None}, {None, None}}, - FrameTicks->{{Automatic, Automatic}, {Automatic, Automatic}}, - GridLines->{None, None}, - GridLinesStyle->Directive[ - GrayLevel[0.5, 0.4]], - Method->{ - "OptimizePlotMarkers" -> True, - "CoordinatesToolOptions" -> {"DisplayFunction" -> ({ - (Identity[#]& )[ - Part[#, 1]], - (Identity[#]& )[ - Part[#, 2]]}& ), "CopiedValueFunction" -> ({ - (Identity[#]& )[ - Part[#, 1]], - (Identity[#]& )[ - Part[#, 2]]}& )}}, - PlotRange->{{0, 1.}, {0, 1.}}, - PlotRangeClipping->True, - PlotRangePadding->{{ - Scaled[0.02], - Scaled[0.02]}, { - Scaled[0.02], - Scaled[0.05]}}, - Ticks->{Automatic, Automatic}]], "Output", - CellChangeTimes->{3.7853056226854563`*^9}, - CellLabel-> - "Out[221]=",ExpressionUUID->"f0514440-6790-4973-a178-10d605503692"] -}, Open ]], - -Cell[CellGroupData[{ - -Cell[BoxData[ - RowBox[{"InverseFunction", "[", - RowBox[{ - RowBox[{ - RowBox[{"a", "#"}], "+", - RowBox[{"b", - RowBox[{"#", "^", "2"}]}]}], " ", "&"}], "]"}]], "Input", - CellChangeTimes->{{3.785304489279614*^9, 3.785304502255611*^9}, { - 3.785304551742334*^9, 3.785304576350375*^9}, {3.7853046419918413`*^9, - 3.785304679053865*^9}}, - CellLabel-> - "In[222]:=",ExpressionUUID->"bfa1e7d7-2b86-4205-af6d-5bf1972b8f75"], - -Cell[BoxData[ - TemplateBox[{ - "InverseFunction","ifun", - "\"Inverse functions are being used. Values may be lost for multivalued \ -inverses.\"",2,222,56,28017100375262792097,"Local"}, - "MessageTemplate"]], "Message", "MSG", - CellChangeTimes->{3.7853059996502647`*^9}, - CellLabel-> - "During evaluation of \ -In[222]:=",ExpressionUUID->"b67cc035-eea8-40e8-9bf0-7511901cd5d4"], - -Cell[BoxData[ - RowBox[{ - FractionBox[ - RowBox[{ - RowBox[{"-", "a"}], "-", - SqrtBox[ - RowBox[{ - SuperscriptBox["a", "2"], "+", - RowBox[{"4", " ", "b", " ", "#1"}]}]]}], - RowBox[{"2", " ", "b"}]], "&"}]], "Output", - CellChangeTimes->{{3.785304568300682*^9, 3.785304577012412*^9}, { - 3.785304647755281*^9, 3.785304685707745*^9}, 3.785305999659697*^9}, - CellLabel-> - "Out[222]=",ExpressionUUID->"c63af4bc-f4df-419e-afb6-b17542ded991"] -}, Open ]] -}, -WindowSize->{808, 911}, -WindowMargins->{{Automatic, 166}, {47, Automatic}}, -FrontEndVersion->"12.0 for Mac OS X x86 (64-bit) (April 8, 2019)", -StyleDefinitions->"Default.nb" -] -(* End of Notebook Content *) - -(* Internal cache information *) -(*CellTagsOutline -CellTagsIndex->{} -*) -(*CellTagsIndex -CellTagsIndex->{} -*) -(*NotebookFileOutline -Notebook[{ -Cell[CellGroupData[{ -Cell[580, 22, 2816, 73, 136, "Input",ExpressionUUID->"85027ebf-eb4f-4561-8636-5abaa20a4e91"], -Cell[3399, 97, 282, 7, 34, "Output",ExpressionUUID->"fed6f178-4c96-4662-aea8-90e31d064e10"], -Cell[3684, 106, 4937, 101, 246, "Output",ExpressionUUID->"f0514440-6790-4973-a178-10d605503692"] -}, Open ]], -Cell[CellGroupData[{ -Cell[8658, 212, 430, 11, 30, "Input",ExpressionUUID->"bfa1e7d7-2b86-4205-af6d-5bf1972b8f75"], -Cell[9091, 225, 377, 9, 24, "Message",ExpressionUUID->"b67cc035-eea8-40e8-9bf0-7511901cd5d4"], -Cell[9471, 236, 461, 13, 60, "Output",ExpressionUUID->"c63af4bc-f4df-419e-afb6-b17542ded991"] -}, Open ]] -} -] -*) - diff --git a/shaders/src/light_indirect.fs b/shaders/src/light_indirect.fs index 7b7a75ffaa..1b5980e081 100644 --- a/shaders/src/light_indirect.fs +++ b/shaders/src/light_indirect.fs @@ -83,10 +83,10 @@ vec3 diffuseIrradiance(const vec3 n) { //------------------------------------------------------------------------------ float perceptualRoughnessToLod(float perceptualRoughness) { - // See: https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html - // (Pre-convolved Cube Maps vs Path Tracers) - // Below is a quadratic fit to the formula in the article above at NoV=1 - return frameUniforms.iblMaxMipLevel.x * perceptualRoughness * (1.686 - 0.686 * perceptualRoughness); + // The mapping below is a quadratic fit for log2(perceptualRoughness)+iblMaxMipLevel when + // iblMaxMipLevel is 4. We found empirically that this mapping works very well for + // a 256 cubemap with 5 levels used. But also scales well for other iblMaxMipLevel values. + return frameUniforms.iblMaxMipLevel.x * perceptualRoughness * (2.0 - perceptualRoughness); } vec3 prefilteredRadiance(const vec3 r, float perceptualRoughness) { diff --git a/tools/cmgen/src/cmgen.cpp b/tools/cmgen/src/cmgen.cpp index 96ae4406bc..3cf89f889f 100644 --- a/tools/cmgen/src/cmgen.cpp +++ b/tools/cmgen/src/cmgen.cpp @@ -895,10 +895,17 @@ void iblMipmapPrefilter(utils::JobSystem& js, const utils::Path& iname, } } -float lodToPerceptualRoughness(float lod) { - const float a = 1.686f; - const float b = -0.686f; - return saturate((std::sqrt(a * a + 4.0f * b * lod) - a) / (2.0f * b)); +static float lodToPerceptualRoughness(float lod) noexcept { + // Inverse perceptualRoughness-to-LOD mapping: + // The LOD-to-perceptualRoughness mapping is a quadratic fit for + // log2(perceptualRoughness)+iblMaxMipLevel when iblMaxMipLevel is 4. + // We found empirically that this mapping works very well for a 256 cubemap with 5 levels used, + // but also scales well for other iblMaxMipLevel values. + const float a = 2.0f; + const float b = -1.0f; + return (lod != 0) + ? saturate((std::sqrt(a * a + 4.0f * b * lod) - a) / (2.0f * b)) + : 0.0f; } void iblRoughnessPrefilter( @@ -954,8 +961,7 @@ void iblRoughnessPrefilter( } const float lod = saturate(level / (numLevels - 1.0f)); - // map the lod to a linear_roughness, here we're using ^2, but other mappings are possible. - // ==> lod = sqrt(linear_roughness) + // map the lod to a perceptualRoughness const float perceptualRoughness = lodToPerceptualRoughness(lod); const float roughness = perceptualRoughness * perceptualRoughness; if (!g_quiet) {