├── .gitignore ├── LICENSE ├── README.md ├── Report.pdf ├── pic └── sample.png ├── results ├── result-1.bmp ├── result-2.bmp ├── result-3.bmp ├── result-4.bmp └── samples │ ├── 1 │ ├── my.json │ └── result.bmp │ ├── 2 │ ├── my.json │ └── result.bmp │ ├── 3 │ ├── my.json │ └── result.bmp │ ├── 4 │ ├── my.json │ └── result.bmp │ ├── 5 │ ├── my.json │ └── result.bmp │ ├── 6 │ ├── my.json │ └── result.bmp │ ├── 7 │ ├── my.json │ └── result.bmp │ ├── 8 │ ├── my.json │ └── result.bmp │ ├── 9 │ ├── my.json │ └── result.bmp │ ├── 10 │ ├── my.json │ └── result.bmp │ ├── 11 │ ├── my.json │ └── result.bmp │ ├── 12 │ ├── my.json │ └── result.bmp │ ├── 13 │ ├── my.json │ └── result.bmp │ ├── 14 │ ├── my.json │ └── result.bmp │ ├── 15 │ ├── my.json │ └── result.bmp │ ├── 16 │ ├── my.json │ └── result.bmp │ └── 17 │ ├── my.json │ └── result.bmp └── src ├── core.cpp ├── core.h ├── main.cpp ├── object.cpp ├── object.h ├── paint.cpp ├── paint.h ├── ppm.cpp ├── ppm.h ├── render.cpp ├── render.h ├── scene.cpp └── scene.h /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 使用渐进式光子映射算法进行三维造型与渲染 2 | 三维造型与渲染-清华大学计算机科学与技术系计算机图形学课程项目 3 | 4 | ## 渐进式光子映射算法 5 | 6 | 在本次实验中,我详细地学习了光线投射(Ray Casting)、光线跟踪(Ray Tracing)、光子映射(Photon Mapping)、渐进式光子映射(Progressive Photon Mapping)以及其升级版 SPPM 等算法,最终实现了 PPM 算法。 7 | 8 | 在 PM 算法中,全局光照 = 直接光照 + 间接光照。从光源向场景发射光子,并在它们碰到漫反射物体时将他们保存在一个光子图中。由于其“光子”的算法特性,可以很好的渲染出由间接光照所造成的“辉映”和“焦散”等效果,这是光线追踪算法所不能达到的。 9 | 10 | 之所以能形成间接光照,是因为光子在处理漫反射时,按照Cos的概率分布随机选取一个方向继续传播,而且光子衰减也采用了特殊处理,即按物体材质反射、折射、漫反射还有被吸收的比例随机选择一种。 11 | 12 | 在 PM 算法中,使用 KDTree 组织光子图,在光子图被组织好以后,对场景进行一次光线追踪。再遇到漫反射的物体时,不直接通过光源计算色光,而是通过光子图来估算。以碰撞点为球心,找到最小的包含 K 个光子的球, 其半径为 R 。该碰撞点的漫反射亮度应与 R 的平方成反比。再将这 K 个光子类比成光源,结合 Phong 模型计算这些光子赋予碰撞点的平均色光,在除以 PiR^2 ,即可得到这次漫反射所要返回的颜色值。 13 | 14 | 在 PM 算法中,通过估算漫反射时获得的色光,光子图越大,估算越精确。然而计算机内存大小有限,渲染不能做到任意精确,PPM 解决了这一问题。 15 | 16 | 在 PPM 算法中,反转了 Photon Tracing 和 Ray Tracing 的顺序。首先将 Ray Tracing 时检测到的碰撞点组织成一棵 KDTree ,而后一轮轮的发射光子,每一轮的光子半径减小、能量减小,每一轮渲染一张图片。随着轮数的增多,光子数量越来越多,半径越来越小,最终结果也越来越精确,这样 PPM 算法也使得光子映射能够形成任意精准度的图片,只要时间允许。 17 | 18 | 在 SPPM 算法中,只是在每一轮光子映射前重新进行了一次 Ray Tracing ,并加以微小的扰动,以获取更优质的渲染结果。因为时间的原因,我没有再进行算法的升级,仅实现了 PPM 算法 19 | 20 | ## 参数曲面求交 21 | 22 | ![avatar](./results/result-3.bmp) 23 | 24 | 如图所示,其中玻璃质地的碗为六条四阶贝塞尔曲线经 Z 轴旋转而形成。这个旋转体曲面即为待渲染的参数曲面。 25 | 26 | 在实验中,我试用了牛顿迭代法进行了参数曲面与光线求交。 27 | 28 | 具体计算过程详见PDF文件。 29 | 30 | 31 | ## 算法型加速 32 | 33 | 在实验中 PPM 算法组织视点形成基于维度分割 KDTree 结构可以大大提升算法效率。KD树建树期间,按照指定维度分割出较小的一半和较大的一半。KD树通过对子树维护视点集包围盒,实现快速判断一个询问点是否在包围盒中。 34 | 包围盒用 maxX , minX , maxY , minY , maxZ , minZ 定义,询问点 ( X , Y , Z ) : 35 | dx = max(0,|X-maxX|,|X-minX|), 36 | dy = max(0,|Y-maxY|,|Y-minY|), 37 | dz = max(0,|Z-maxZ|,|Z-minZ|) 38 | 答案dist满足:dist = \sqrt{dx^2+dy^2+dz^2} 39 | 40 | 41 | ## OpenMP的使用 42 | 43 | 为了加快渲染速度,实验中使用了 OpenMP 进行多线程渲染。 44 | 45 | 46 | 47 | ## 景深效果 48 | 49 | ![avatar](./results/result-1.bmp) 50 | 51 | 普通的相机模型中,有一个人眼位置和一个屏幕,对于屏幕中每一个像素,连接人眼和该像素位置得到一条射出光线。 52 | 53 | 首先,已知屏幕像素坐标,以及屏幕本身在场景中的位置,我们可以计算出该像素的位置,如图中红点所述。接着,连接人眼和像素的光线就可以用于计算该光线的颜色。在普通相机模型的屏幕和人眼位置之外,带景深的相机模型额外存在一个焦平面。 54 | 55 | 通过普通的相机模型,我们可以求得普通相机的光线的方向。 56 | 57 | 普通相机的光线一定会和焦平面在某个位置碰撞,为了达到景深效果,一方面,我们需要保证同一个像素对应的光线一定会击打到焦平面上的同一个点,另一方面,在焦平面之外的其他位置,同一个像素对应的光线应该击打到不同的点。 58 | 59 | 我们对光线的起始位置做一个微小扰动,并且修改光线方向使得光线恒定过焦平面上的点。这样,无论初始光线如何扰动,焦平面上的点都可以最清晰的表现出来。而不在焦平面上的点,会产生随机的模糊效果。 60 | 61 | 62 | 63 | ## 贴图效果 64 | 65 | 在实验中,我分别将地板和部分球体进行了贴图。 66 | 67 | ![avatar](./pic/sample.png) 68 | 69 | -------------------------------------------------------------------------------- /Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/Report.pdf -------------------------------------------------------------------------------- /pic/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/pic/sample.png -------------------------------------------------------------------------------- /results/result-1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/result-1.bmp -------------------------------------------------------------------------------- /results/result-2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/result-2.bmp -------------------------------------------------------------------------------- /results/result-3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/result-3.bmp -------------------------------------------------------------------------------- /results/result-4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/result-4.bmp -------------------------------------------------------------------------------- /results/samples/1/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 500, "ry": 500, 3 | 4 | "photon_num": 40000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": 0, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1.0} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.1, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.3} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.1, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.3} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1.0, "spec": 0.0, "refr": 0.0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } -------------------------------------------------------------------------------- /results/samples/1/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/1/result.bmp -------------------------------------------------------------------------------- /results/samples/10/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 700, "ry": 700, 3 | 4 | "photon_num": 20000, 5 | "total_round": 5, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20,"y": -10,"z": 0}, 14 | "dx": {"x": -20,"y": 0,"z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 20, "y": -5, "z": -40}, 17 | "fdepth": 0.02 18 | }, 19 | "lights": [ 20 | { 21 | "type": "point_light", 22 | "name": "light", 23 | "brightness": 1, 24 | "position": {"x": 25, "y": 15,"z": 10}, 25 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 26 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 27 | } 28 | ], 29 | "objects": [ 30 | { 31 | "type":"sphere", 32 | "name":"ball_right", 33 | "center":{"x":3,"y":6,"z":20}, 34 | "radius":3, 35 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 36 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.55} 37 | }, 38 | { 39 | "type": "bazier_curves", 40 | "name": "cup", 41 | "position": {"x": 0, "y": -2, "z": 7}, 42 | "ctrl_pts": [ 43 | [[0.0, 1.1, 1.2, 2.0], [0.04, 0.04, -0.0, -0.0]], 44 | [[2.0, 2.2, 2.0, 1.9], [-0.0, -0.0, 0.1, 0.15]], 45 | [[1.9, 1.73, 0.4, 0.2], [0.15, 0.23, -0.2, 0.4]], 46 | [[0.2, -0.1, 3.8, 3.8], [0.4, 1.3, 1.4, 2.0]], 47 | [[3.8, 3.8, 3.6, 3.6], [2.0, 2.2, 2.2, 2.0]], 48 | [[3.6, 3.6, 0.25, 0.0], [2.0, 1.9, 1.3, 1.3]] 49 | ], 50 | "texture": {"type": "pure", "r": 0.01, "g": 0.01, "b": 0.01}, 51 | "absorb": {"type": "pure", "r": 0.01, "g": 0.01, "b": 0.01 }, 52 | "material": {"refl": 0.0, "diff": 0.0, "spec": 0.0, "refr": 0.9, "refr_k": 1.55} 53 | }, 54 | { 55 | "type": "plane", 56 | "name": "floor", 57 | "position": {"x": 0, "y": -10, "z": 25}, 58 | "dx": {"x": 0, "y": 0, "z": 30}, 59 | "dy": {"x": 0, "y": 20, "z": 0}, 60 | "texture": {"type": "picture", "filename": "materials/wood.jpg", "rx": 40, "ry": 40}, 61 | "material": {"refl": 0.0, "diff": 1.0, "spec": 0.0, "refr": 0.0, "refr_k": 0.0}, 62 | "border": false 63 | } 64 | ], 65 | "bg_color": { 66 | "type": "pure", 67 | "r": 0.0, 68 | "g": 0.0, 69 | "b": 0.0 70 | }, 71 | "max_depth": 20, 72 | "max_jump": 20, 73 | "start_rows": 0, 74 | "start_cols": 0 75 | } -------------------------------------------------------------------------------- /results/samples/10/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/10/result.bmp -------------------------------------------------------------------------------- /results/samples/11/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 300, "ry": 300, 3 | 4 | "photon_num": 20000, 5 | "total_round": 5, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20,"y": -10,"z": 0}, 14 | "dx": {"x": -20,"y": 0,"z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 20, "y": -5, "z": -40}, 17 | "fdepth": 0.02 18 | }, 19 | "lights": [ 20 | { 21 | "type": "point_light", 22 | "name": "light", 23 | "brightness": 1, 24 | "position": {"x": 25, "y": 15,"z": 10}, 25 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 26 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 27 | } 28 | ], 29 | "objects": [ 30 | { 31 | "type":"sphere", 32 | "name":"ball", 33 | "center":{"x":3,"y":6,"z":15}, 34 | "radius":3, 35 | "texture":{"type":"picture","filename":"materials/dirt.jpg","rx":2,"ry":3.14}, 36 | "absorb": {"type":"pure","r":0.2,"g":0.7,"b":0.2}, 37 | "material":{"refl":0.05,"diff":1.0,"spec":0.6,"refr":0.0,"refr_k":1.0} 38 | }, 39 | { 40 | "type": "bazier_curves", 41 | "name": "cup", 42 | "position": {"x": 0, "y": -2, "z": 7}, 43 | "ctrl_pts": [ 44 | [[0.0, 1.1, 1.2, 2.0], [0.04, 0.04, -0.0, -0.0]], 45 | [[2.0, 2.2, 2.0, 1.9], [-0.0, -0.0, 0.1, 0.15]], 46 | [[1.9, 1.73, 0.4, 0.2], [0.15, 0.23, -0.2, 0.4]], 47 | [[0.2, -0.1, 3.8, 3.8], [0.4, 1.3, 1.4, 2.0]], 48 | [[3.8, 3.8, 3.6, 3.6], [2.0, 2.2, 2.2, 2.0]], 49 | [[3.6, 3.6, 0.25, 0.0], [2.0, 1.9, 1.3, 1.3]] 50 | ], 51 | "texture": {"type": "pure", "r": 0.01, "g": 0.01, "b": 0.01}, 52 | "absorb": {"type": "pure", "r": 0.01, "g": 0.01, "b": 0.01 }, 53 | "material": {"refl": 0.0, "diff": 0.0, "spec": 0.0, "refr": 0.9, "refr_k": 1.55} 54 | }, 55 | { 56 | "type": "plane", 57 | "name": "floor", 58 | "position": {"x": 0, "y": -10, "z": 25}, 59 | "dx": {"x": 0, "y": 0, "z": 30}, 60 | "dy": {"x": 0, "y": 20, "z": 0}, 61 | "texture": {"type": "picture", "filename": "materials/tile.jpg", "rx": 10, "ry": 10}, 62 | "material": {"refl": 0.0, "diff": 1.0, "spec": 0.0, "refr": 0.0, "refr_k": 0.0}, 63 | "border": false 64 | } 65 | ], 66 | "bg_color": { 67 | "type": "pure", 68 | "r": 0.0, 69 | "g": 0.0, 70 | "b": 0.0 71 | }, 72 | "max_depth": 20, 73 | "max_jump": 20, 74 | "start_rows": 0, 75 | "start_cols": 0 76 | } 77 | -------------------------------------------------------------------------------- /results/samples/11/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/11/result.bmp -------------------------------------------------------------------------------- /results/samples/12/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 800, "ry": 800, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20,"y": -10,"z": 0}, 14 | "dx": {"x": -20,"y": 0,"z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 20, "y": -5, "z": -40}, 17 | "fdepth": 0.02 18 | }, 19 | "lights": [ 20 | { 21 | "type": "point_light", 22 | "name": "light", 23 | "brightness": 1, 24 | "position": {"x": 25, "y": 15,"z": 10}, 25 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 26 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 27 | } 28 | ], 29 | "objects": [ 30 | { 31 | "type":"sphere", 32 | "name":"ball", 33 | "center":{"x":3,"y":6,"z":15}, 34 | "radius":3, 35 | "texture":{"type":"picture","filename":"materials/dirt.jpg","rx":2,"ry":3.14}, 36 | "absorb": {"type":"pure","r":0.2,"g":0.7,"b":0.2}, 37 | "material":{"refl":0.05,"diff":1.0,"spec":0.6,"refr":0.0,"refr_k":1.0} 38 | }, 39 | { 40 | "type": "bazier_curves", 41 | "name": "cup", 42 | "position": {"x": 0, "y": -2, "z": 7}, 43 | "ctrl_pts": [ 44 | [[0.0, 1.1, 1.2, 2.0], [0.04, 0.04, -0.0, -0.0]], 45 | [[2.0, 2.2, 2.0, 1.9], [-0.0, -0.0, 0.1, 0.15]], 46 | [[1.9, 1.73, 0.4, 0.2], [0.15, 0.23, -0.2, 0.4]], 47 | [[0.2, -0.1, 3.8, 3.8], [0.4, 1.3, 1.4, 2.0]], 48 | [[3.8, 3.8, 3.6, 3.6], [2.0, 2.2, 2.2, 2.0]], 49 | [[3.6, 3.6, 0.25, 0.0], [2.0, 1.9, 1.3, 1.3]] 50 | ], 51 | "texture": {"type": "pure", "r": 0.01, "g": 0.01, "b": 0.01}, 52 | "absorb": {"type": "pure", "r": 0.01, "g": 0.01, "b": 0.01 }, 53 | "material": {"refl": 0.0, "diff": 0.0, "spec": 0.0, "refr": 0.9, "refr_k": 1.55} 54 | }, 55 | { 56 | "type": "plane", 57 | "name": "floor", 58 | "position": {"x": 0, "y": -10, "z": 25}, 59 | "dx": {"x": 0, "y": 0, "z": 30}, 60 | "dy": {"x": 0, "y": 20, "z": 0}, 61 | "texture": {"type": "picture", "filename": "materials/tile.jpg", "rx": 10, "ry": 10}, 62 | "material": {"refl": 0.0, "diff": 1.0, "spec": 0.0, "refr": 0.0, "refr_k": 0.0}, 63 | "border": false 64 | } 65 | ], 66 | "bg_color": { 67 | "type": "pure", 68 | "r": 0.0, 69 | "g": 0.0, 70 | "b": 0.0 71 | }, 72 | "max_depth": 20, 73 | "max_jump": 20, 74 | "start_rows": 0, 75 | "start_cols": 0 76 | } 77 | -------------------------------------------------------------------------------- /results/samples/12/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/12/result.bmp -------------------------------------------------------------------------------- /results/samples/13/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 800, "ry": 800, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.55} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.55} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } 65 | -------------------------------------------------------------------------------- /results/samples/13/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/13/result.bmp -------------------------------------------------------------------------------- /results/samples/14/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 800, "ry": 800, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000.0, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 10, "y": -5, "z": 0}, 14 | "dx": {"x": -10, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 10, "z": 0}, 16 | "origin": {"x": 10, "y": 0, "z": -20}, 17 | "fdepth": 0.075 18 | }, 19 | "lights": [ 20 | { 21 | "type": "point_light", 22 | "name": "light", 23 | "brightness": 1, 24 | "position": {"x": 25, "y": 10,"z": 20}, 25 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 26 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 27 | }, 28 | { 29 | "type": "point_light", 30 | "name": "light", 31 | "brightness": 1, 32 | "position": {"x": 15, "y": 0,"z": -20}, 33 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 34 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 35 | } 36 | ], 37 | "objects": [ 38 | { 39 | "type": "sphere", 40 | "name": "marble_ball", 41 | "center": {"x": 3, "y": -1.5, "z": 30}, 42 | "radius": 3, 43 | "texture": {"type": "picture", "filename": "materials/timg-2.jpeg", "rx": 2, "ry": 3.14}, 44 | "absorb": {"type": "pure", "r": 0.5, "g": 0.7, "b": 0.5}, 45 | "material": {"refl": 0.05, "diff": 1, "spec": 0, "refr": 0.0, "refr_k": 0} 46 | }, 47 | { 48 | "type": "sphere", 49 | "name": "marble_ball", 50 | "center": {"x": 1.5, "y": -4, "z": 15}, 51 | "radius": 1.5, 52 | "texture": {"type": "picture", "filename": "materials/timg-2.jpeg", "rx": 2, "ry": 3.14}, 53 | "absorb": {"type": "pure", "r": 0.5, "g": 0.7, "b": 0.5}, 54 | "material": {"refl": 0.05, "diff": 1, "spec": 0, "refr": 0.0, "refr_k": 0} 55 | }, 56 | { 57 | "type": "sphere", 58 | "name": "lost_focus_ball", 59 | "center": {"x": 7, "y": 1, "z": -8}, 60 | "radius": 1, 61 | "texture": {"type": "picture", "filename": "materials/timg-2.jpeg", "rx": 2, "ry": 3.14}, 62 | "absorb": {"type": "pure", "r": 0.5, "g": 0.7, "b": 0.5}, 63 | "material": {"refl": 0.05, "diff": 1.0, "spec": 0.0, "refr": 0, "refr_k": 0} 64 | }, 65 | { 66 | "type": "plane", 67 | "name": "floor", 68 | "position": {"x": 0, "y": -10, "z": 25}, 69 | "dx": {"x": 0, "y": 0, "z": 30}, 70 | "dy": {"x": 0, "y": 20, "z": 0}, 71 | "texture": {"type": "picture", "filename": "materials/tile-2.jpg", "rx": 8, "ry": 8}, 72 | "material": {"refl": 0.0, "diff": 1, "spec": 0.0, "refr": 0.0, "refr_k": 0.0}, 73 | "border": false 74 | } 75 | ], 76 | "bg_color": { 77 | "type": "pure", 78 | "r": 0.0, 79 | "g": 0.0, 80 | "b": 0.0 81 | }, 82 | "max_depth": 20, 83 | "max_jump": 20, 84 | "start_rows": 0, 85 | "start_cols": 0 86 | } -------------------------------------------------------------------------------- /results/samples/14/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/14/result.bmp -------------------------------------------------------------------------------- /results/samples/15/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 800, "ry": 800, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000.0, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 10, "y": -5, "z": 0}, 14 | "dx": {"x": -10, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 10, "z": 0}, 16 | "origin": {"x": 10, "y": 0, "z": -20}, 17 | "fdepth": 0.04 18 | }, 19 | "lights": [ 20 | { 21 | "type": "point_light", 22 | "name": "light", 23 | "brightness": 1, 24 | "position": {"x": 25, "y": 10,"z": 20}, 25 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 26 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 27 | }, 28 | { 29 | "type": "point_light", 30 | "name": "light", 31 | "brightness": 1, 32 | "position": {"x": 15, "y": 0,"z": -20}, 33 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 34 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 35 | } 36 | ], 37 | "objects": [ 38 | { 39 | "type": "sphere", 40 | "name": "marble_ball", 41 | "center": {"x": 3, "y": -1.5, "z": 30}, 42 | "radius": 3, 43 | "texture": {"type": "picture", "filename": "materials/timg-2.jpeg", "rx": 2, "ry": 3.14}, 44 | "absorb": {"type": "pure", "r": 0.5, "g": 0.7, "b": 0.5}, 45 | "material": {"refl": 0.05, "diff": 1, "spec": 0, "refr": 0.0, "refr_k": 0} 46 | }, 47 | { 48 | "type": "sphere", 49 | "name": "marble_ball", 50 | "center": {"x": 1.5, "y": -4, "z": 21}, 51 | "radius": 1.5, 52 | "texture": {"type": "picture", "filename": "materials/timg-2.jpeg", "rx": 2, "ry": 3.14}, 53 | "absorb": {"type": "pure", "r": 0.5, "g": 0.7, "b": 0.5}, 54 | "material": {"refl": 0.05, "diff": 1, "spec": 0, "refr": 0.0, "refr_k": 0} 55 | }, 56 | { 57 | "type": "sphere", 58 | "name": "lost_focus_ball", 59 | "center": {"x": 7, "y": 0.8, "z": -10}, 60 | "radius": 0.9, 61 | "texture": {"type": "picture", "filename": "materials/timg-2.jpeg", "rx": 2, "ry": 3.14}, 62 | "absorb": {"type": "pure", "r": 0.5, "g": 0.7, "b": 0.5}, 63 | "material": {"refl": 0.05, "diff": 1.0, "spec": 0.0, "refr": 0, "refr_k": 0} 64 | }, 65 | { 66 | "type": "plane", 67 | "name": "floor", 68 | "position": {"x": 0, "y": -10, "z": 25}, 69 | "dx": {"x": 0, "y": 0, "z": 30}, 70 | "dy": {"x": 0, "y": 20, "z": 0}, 71 | "texture": {"type": "picture", "filename": "materials/tile-2.jpg", "rx": 8, "ry": 8}, 72 | "material": {"refl": 0.0, "diff": 1, "spec": 0.0, "refr": 0.0, "refr_k": 0.0}, 73 | "border": false 74 | } 75 | ], 76 | "bg_color": { 77 | "type": "pure", 78 | "r": 0.0, 79 | "g": 0.0, 80 | "b": 0.0 81 | }, 82 | "max_depth": 20, 83 | "max_jump": 20, 84 | "start_rows": 0, 85 | "start_cols": 0 86 | } -------------------------------------------------------------------------------- /results/samples/15/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/15/result.bmp -------------------------------------------------------------------------------- /results/samples/16/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 800, "ry": 800, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20,"y": -10,"z": 0}, 14 | "dx": {"x": -20,"y": 0,"z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 20, "y": -5, "z": -40}, 17 | "fdepth": 0.02 18 | }, 19 | "lights": [ 20 | { 21 | "type": "point_light", 22 | "name": "light", 23 | "brightness": 1, 24 | "position": {"x": 25, "y": 15,"z": 10}, 25 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 26 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 27 | } 28 | ], 29 | "objects": [ 30 | { 31 | "type":"sphere", 32 | "name":"ball", 33 | "center":{"x":3,"y":4,"z":15}, 34 | "radius":3, 35 | "texture":{"type":"pure","r":0.18,"g":0.18,"b":0.96}, 36 | "material":{"refl":0,"diff":1.0,"spec":0.6,"refr":0,"refr_k":0} 37 | }, 38 | { 39 | "type": "plane", 40 | "name": "floor", 41 | "position": {"x": 0, "y": -10, "z": 25}, 42 | "dx": {"x": 0, "y": 0, "z": 30}, 43 | "dy": {"x": 0, "y": 20, "z": 0}, 44 | "texture": {"type":"pure","r":0.156,"g":0.156,"b":0.156}, 45 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 46 | "border": false 47 | } 48 | ], 49 | "bg_color": { 50 | "type": "pure", 51 | "r": 0.0, 52 | "g": 0.0, 53 | "b": 0.0 54 | }, 55 | "max_depth": 20, 56 | "max_jump": 20, 57 | "start_rows": 0, 58 | "start_cols": 0 59 | } 60 | -------------------------------------------------------------------------------- /results/samples/16/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/16/result.bmp -------------------------------------------------------------------------------- /results/samples/17/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 800, "ry": 800, 3 | 4 | "photon_num": 20000, 5 | "total_round": 5, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.5, "diff": 0, "spec": 0.7, "refr": 0.9, "refr_k": 1.5} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.5, "diff": 0, "spec": 0.7, "refr": 0.9, "refr_k": 1.5} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type": "pure","r": 0.4,"g": 0.4,"b": 0.4}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } -------------------------------------------------------------------------------- /results/samples/17/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/17/result.bmp -------------------------------------------------------------------------------- /results/samples/2/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 500, "ry": 500, 3 | 4 | "photon_num": 40000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1.0} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.3, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.3} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.3, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.3} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } -------------------------------------------------------------------------------- /results/samples/2/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/2/result.bmp -------------------------------------------------------------------------------- /results/samples/3/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 800, "ry": 800, 3 | 4 | "photon_num": 20000, 5 | "total_round": 100, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1.0} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.3, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.3} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.3, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.3} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } -------------------------------------------------------------------------------- /results/samples/3/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/3/result.bmp -------------------------------------------------------------------------------- /results/samples/4/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 500, "ry": 500, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1.0} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.3} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.3} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } -------------------------------------------------------------------------------- /results/samples/4/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/4/result.bmp -------------------------------------------------------------------------------- /results/samples/5/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 300, "ry": 300, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.1} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } 65 | -------------------------------------------------------------------------------- /results/samples/5/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/5/result.bmp -------------------------------------------------------------------------------- /results/samples/6/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 300, "ry": 300, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.5} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.4} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } 65 | -------------------------------------------------------------------------------- /results/samples/6/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/6/result.bmp -------------------------------------------------------------------------------- /results/samples/7/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 300, "ry": 300, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.6} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.7} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } -------------------------------------------------------------------------------- /results/samples/7/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/7/result.bmp -------------------------------------------------------------------------------- /results/samples/8/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 300, "ry": 300, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.8} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.9} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } -------------------------------------------------------------------------------- /results/samples/8/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/8/result.bmp -------------------------------------------------------------------------------- /results/samples/9/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "rx": 300, "ry": 300, 3 | 4 | "photon_num": 20000, 5 | "total_round": 10, 6 | "total_brightness": 1000, 7 | "round_decay": 0.95, 8 | "initial_r": 5, 9 | "r_decay": 0.8, 10 | 11 | "camera": { 12 | "type": "default", 13 | "position": {"x": 20, "y": -10, "z": 0}, 14 | "dx": {"x": -20, "y": 0, "z": 0}, 15 | "dy": {"x": 0, "y": 20, "z": 0}, 16 | "origin": {"x": 21, "y": -8, "z": -50}, 17 | "fdepth": 0.02 18 | }, 19 | 20 | "lights": [ 21 | { 22 | "type": "point_light", 23 | "name": "light", 24 | "brightness": 1, 25 | "position": {"x": 25, "y": 15,"z": 10}, 26 | "texture": {"type": "pure", "r": 1, "g": 1, "b": 1}, 27 | "material": {"refl": 0, "diff": 0, "spec": 0, "refr": 0.0, "refr_k": 1} 28 | } 29 | ], 30 | 31 | "objects": [ 32 | { 33 | "type":"sphere", 34 | "name":"ball_right", 35 | "center":{"x":3,"y":6,"z":10}, 36 | "radius":3, 37 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 38 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.55} 39 | }, 40 | { 41 | "type":"sphere", 42 | "name":"ball_left", 43 | "center":{"x":3,"y":-2,"z":7}, 44 | "radius":3, 45 | "texture": {"type": "pure","r": 0.99,"g": 0.99,"b": 0.99}, 46 | "material":{"refl": 0.5, "diff": 0, "spec": 0.6, "refr": 0.9, "refr_k": 1.55} 47 | }, 48 | { 49 | "type": "plane", 50 | "name": "bottom", 51 | "position": {"x": 0, "y": 0, "z": 0}, 52 | "dx": {"x": 0, "y": 0, "z": 1}, 53 | "dy": {"x": 0, "y": 1, "z": 0}, 54 | "texture": {"type":"picture", "filename":"materials/wood.jpg", "rx":40, "ry":40}, 55 | "material": {"refl": 0, "diff": 1, "spec": 0, "refr": 0, "refr_k": 0}, 56 | "border": false 57 | } 58 | ], 59 | 60 | "bg_color": {"type": "pure", "r": 0, "g": 0, "b": 0}, 61 | 62 | "max_depth": 20, "max_jump": 20, 63 | "start_rows": 0, "start_cols": 0 64 | } 65 | -------------------------------------------------------------------------------- /results/samples/9/result.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZhaohengLi/progressive-photon-mapping/c029233f7510c3c1214e1bd5bf2c9c79775e9eb3/results/samples/9/result.bmp -------------------------------------------------------------------------------- /src/core.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | #include "core.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace cv; 15 | 16 | 17 | Vector :: Vector() { 18 | x = 0 , y = 0, z = 0; 19 | } 20 | 21 | Vector :: Vector(double x,double y,double z) : x(x), y(y), z(z){ 22 | } 23 | 24 | Vector :: Vector(const Eigen::Vector3d vec) : x(vec(0,0)),y(vec(1,0)),z(vec(2,0)) { 25 | } 26 | 27 | void Vector :: accept(const Json::Value& val) { 28 | if (!val.isMember("x") || !val.isMember("y") || !val.isMember("z")) 29 | std::cout<<"The vector not found..."<"; 99 | ss>>res; 100 | return res; 101 | } 102 | Eigen::Vector3d Vector::eigen()const { 103 | return Eigen::Vector3d(x,y,z); 104 | } 105 | 106 | Vector Vector::randomVectorOnSphere() { 107 | double theta = rand()*1.0/RAND_MAX*M_PI*2; 108 | double phi = rand()*1.0/RAND_MAX*M_PI*2 - M_PI; 109 | return Vector(cos(phi)*sin(theta),cos(phi)*cos(theta),sin(phi)); 110 | } 111 | 112 | 113 | Texture::Texture() { 114 | } 115 | Texture::~Texture() { 116 | } 117 | 118 | PureColorTexture::PureColorTexture() { 119 | } 120 | PureColorTexture::~PureColorTexture() { 121 | } 122 | 123 | Color PureColorTexture::getColor(double,double)const { 124 | return color; 125 | } 126 | 127 | void PureColorTexture::accept(const Json::Value& val) { 128 | color.accept(val); 129 | } 130 | 131 | PictureTexture::PictureTexture() { 132 | } 133 | PictureTexture::~PictureTexture() { 134 | } 135 | 136 | Color PictureTexture::getColor(double x,double y)const { 137 | int ix = (int(floor(fmod(x,rx)/rx * image.rows)) + image.rows)%image.rows; 138 | int iy = (int(floor(fmod(y,ry)/ry * image.cols)) + image.cols)%image.cols; 139 | assert(ix(ix, iy)[0]/255.0; 141 | double g = image.at(ix, iy)[1]/255.0; 142 | double b = image.at(ix, iy)[2]/255.0; 143 | return Color(r,g,b); 144 | } 145 | 146 | void PictureTexture::accept(const Json::Value& val) { 147 | filename = val["filename"].asString(); 148 | rx = val["rx"].asDouble(); 149 | ry = val["ry"].asDouble(); 150 | image = cv::imread(filename.c_str()); 151 | std::cout<<"Imaged <"< read "<getMaterial().refr_k : belongs->getMaterial().refr_k; 168 | double cosT2 = 1 - (n*n)*(1-cosI*cosI); 169 | if (cosT2 > feps) { 170 | resO = getBackfaceC(); 171 | resD = I*n + N*(n*cosI - sqrt(cosT2)); 172 | }else { 173 | reflection(resO,resD); 174 | } 175 | } 176 | 177 | void Collision::reflection(Vector& resO, Vector& resD)const { 178 | Vector _N = N*(N^I.reverse()); 179 | resD = (_N*2-I.reverse()); 180 | resO = getSurfaceC(); 181 | } 182 | 183 | void Collision::diffusion(Vector& resO, Vector& resD)const { 184 | Vector DD = (N*Vector::randomVectorOnSphere()).unit(); 185 | assert(DD.isUnit()); 186 | double phi = acos(rand()*1.0/RAND_MAX); 187 | resO = getSurfaceC(); 188 | resD = DD*sin(phi) + N*cos(phi); 189 | assert(resD.isUnit()); 190 | } 191 | 192 | void Collision::diffusion_hl(Vector& resO, Vector& resD)const { 193 | } 194 | 195 | Vector Collision::getSurfaceC()const { 196 | return C+N*(feps*2); 197 | } 198 | Vector Collision::getBackfaceC()const { 199 | return C-N*(feps*2); 200 | } 201 | 202 | void Material::accept(const Json::Value& val) { 203 | if (!val.isMember("refl")) 204 | std::cout<<"No refl found in material..."<accept(val["texture"]); 232 | material.accept(val["material"]); 233 | if (material.refr>feps) 234 | { 235 | absorb = new PureColorTexture(); 236 | absorb->accept(val["absorb"]); 237 | } 238 | } 239 | 240 | std::string Collision::description()const { 241 | static char buf[20]; 242 | sprintf(buf,"%f",dist); 243 | return std::string("Collision : \n") + 244 | "C = "+C.description() +"\n" + 245 | "N = " + N.description() + "\n" + 246 | "I = " + I.description() + "\n" + 247 | "dist = " + std::string(buf) + "\n" + 248 | "face = " + (face?"true":"false"); 249 | } 250 | 251 | const Texture& Object::getAbsorb()const { 252 | if (!absorb) { 253 | std::cout<<"The absorb not defined yet."<getType() != TEXTURE_PURE_COLOR) 270 | std::cout<<"The getColor of Light only support PURE_COLOR_MODE"<getColor(); 272 | } 273 | 274 | Color::Color() { 275 | r = g = b = 0; 276 | } 277 | 278 | Color::Color(double r,double g,double b) : r(r),g(g),b(b) { 279 | } 280 | 281 | Color Color::adjust()const { 282 | return Color(min(r,1.0),min(g,1.0),min(b,1.0)); 283 | } 284 | 285 | 286 | Color operator +(const Color& a,const Color &b) { 287 | return Color(a.r+b.r,a.g+b.g,a.b+b.b); 288 | } 289 | 290 | Color operator *(const Color& a,const Color &b) { 291 | return Color(a.r*b.r,a.g*b.g,a.b*b.b); 292 | } 293 | 294 | Color operator *(const Color& a,double k) { 295 | return Color(a.r*k,a.g*k,a.b*k); 296 | } 297 | 298 | Color Color::exp()const { 299 | return Color(::exp(r),::exp(g),::exp(b)); 300 | } 301 | 302 | Color Color::operator +=(const Color& a) { 303 | r += a.r; 304 | g += a.g; 305 | b += a.b; 306 | return (*this); 307 | } 308 | void Color::accept(const Json::Value& val) { 309 | r = val["r"].asDouble(); 310 | g = val["g"].asDouble(); 311 | b = val["b"].asDouble(); 312 | } 313 | std::string Color::description()const { 314 | std::stringstream ss; 315 | ss<<"Color<"<"<>res; 318 | return res; 319 | } 320 | 321 | 322 | 323 | Camera::Camera(int rx,int ry):rx(rx),ry(ry) { 324 | } 325 | Camera::~Camera() { 326 | } 327 | 328 | void Camera :: accept(const Json::Value& val) { 329 | position.accept(val["position"]); 330 | dx.accept(val["dx"]); 331 | dy.accept(val["dy"]); 332 | origin.accept(val["origin"]); 333 | fdepth = val["fdepth"].asDouble(); 334 | } 335 | 336 | void Camera::getRay(double scanX,double scanY, Vector& rayO, Vector& rayD) { 337 | Vector _rayO,_rayD; 338 | _rayO = origin; 339 | _rayD = ((position + scanX*dx/(rx-1) + scanY*dy/(ry-1))-origin).unit(); 340 | addDepth(_rayO,_rayD,rayO,rayD); 341 | } 342 | 343 | void Camera::addDepth(const Vector& rayO,const Vector& rayD,Vector& resO,Vector& resD) { 344 | Vector FocalPlanePoint = rayO + rayD*fdepth; 345 | resO = rayO + Vector::randomVectorOnSphere()*fdepth; 346 | resD = (FocalPlanePoint - rayO).unit(); 347 | } 348 | -------------------------------------------------------------------------------- /src/core.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | #ifndef CODE_CORE_H 6 | #define CODE_CORE_H 7 | 8 | #include "json/json.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define TEXTURE_PURE_COLOR 1 15 | #define TEXTURE_PICTURE 2 16 | #define INF 0x3f3f3f3f 17 | #define inf 1e100 18 | #define feps 1e-7 19 | 20 | class Vector 21 | { 22 | double x,y,z; 23 | public: 24 | Vector(); 25 | Vector(double x,double y,double z); 26 | Vector(const Eigen::Vector3d vec); 27 | double getX() const {return x;} 28 | double getY() const {return y;} 29 | double getZ() const {return z;} 30 | virtual void accept(const Json::Value &sl); 31 | friend Vector operator * (const Vector &a,const Vector &b); 32 | friend double operator ^ (const Vector &a,const Vector &b); 33 | friend Vector operator + (const Vector &a,const Vector &b); 34 | friend Vector operator - (const Vector &a,const Vector &b); 35 | friend Vector operator - (const Vector &a); 36 | friend Vector operator * (double k,const Vector &a); 37 | friend Vector operator * (const Vector &a,double k); 38 | friend bool operator == (const Vector &a,const Vector &b); 39 | friend Vector operator /(const Vector& a,double k); 40 | friend Vector each_min(const Vector& v1,const Vector& v2); 41 | friend Vector each_max(const Vector& v1,const Vector& v2); 42 | Vector unit()const; 43 | Vector reverse()const; 44 | double len()const; 45 | double sqrlen()const; 46 | bool isUnit()const; 47 | std::string description()const; 48 | Eigen::Vector3d eigen()const; 49 | static Vector randomVectorOnSphere(); 50 | }; 51 | 52 | 53 | 54 | class Texture 55 | { 56 | public: 57 | Texture(); 58 | virtual ~Texture(); 59 | virtual Color getColor(double dx=0,double dy=0)const = 0; 60 | virtual void accept(const Json::Value& val) = 0; 61 | virtual int getType() = 0; 62 | }; 63 | 64 | class PureColorTexture : public Texture { 65 | private: 66 | Color color; 67 | public: 68 | PureColorTexture(); 69 | ~PureColorTexture(); 70 | Color getColor(double,double)const; 71 | int getType(){return TEXTURE_PURE_COLOR;} 72 | void accept(const Json::Value& val); 73 | }; 74 | 75 | class PictureTexture : public Texture { 76 | private: 77 | std::string filename; 78 | double rx,ry; 79 | cv::Mat image; 80 | public: 81 | PictureTexture(); 82 | ~PictureTexture(); 83 | Color getColor(double,double)const; 84 | int getType(){return TEXTURE_PICTURE;} 85 | void accept(const Json::Value& val); 86 | }; 87 | 88 | class Object; 89 | 90 | struct Collision { 91 | Vector C;//The Center of Collision 92 | Vector N;//The normal of the plane 93 | Vector I;//The direction of reflaction 94 | double dist; 95 | bool face; 96 | Object* belongs; 97 | std::string description()const; 98 | void refraction(Vector& resO, Vector& resD)const; 99 | void reflection(Vector& resO, Vector& resD)const; 100 | void diffusion(Vector& resO, Vector& resD)const; 101 | void diffusion_hl(Vector& resO, Vector& resD)const; 102 | Vector getSurfaceC()const; 103 | Vector getBackfaceC()const; 104 | }; 105 | 106 | struct Material { 107 | double refl;//reflection ratio 108 | double diff;//diffusion ratio 109 | double spec;//high light diffusion 110 | double refr;//refraction ratio 111 | double refr_k; 112 | void accept(const Json::Value& val); 113 | }; 114 | 115 | class Object { 116 | protected: 117 | unsigned hash; 118 | Material material; 119 | std::string name; 120 | Texture* texture; 121 | Texture* absorb; 122 | public: 123 | Object(); 124 | virtual ~Object(); 125 | virtual void accept(const Json::Value& val); 126 | unsigned getHash()const {return hash;} 127 | 128 | const Material& getMaterial()const {return material;} 129 | 130 | virtual bool collideWith(const Vector& rayO, const Vector& rayD,Collision& coll) = 0; 131 | virtual Color getColor(const Vector &pos)const = 0; 132 | std::string getName()const{return name;} 133 | const Texture& getAbsorb()const; 134 | }; 135 | 136 | 137 | class Light : public Object { 138 | protected: 139 | double brightness; 140 | public: 141 | Light(); 142 | virtual ~Light(); 143 | virtual void accept(const Json::Value& val); 144 | virtual Vector getCenter()const = 0; 145 | virtual double getShade(const Vector& rayO,std::vector olist,int shade_quality)const = 0; 146 | virtual void randomlyEmit(Vector& rayO,Vector& rayD)const = 0; 147 | double getBrightness()const {return brightness;} 148 | Color getColor(const Vector&)const; 149 | }; 150 | 151 | 152 | class Color { 153 | private: 154 | double r,g,b; 155 | public: 156 | Color(); 157 | Color(double r,double g,double b); 158 | Color operator += (const Color&a); 159 | void accept(const Json::Value& val); 160 | double getR()const {return r;} 161 | double getG()const {return g;} 162 | double getB()const {return b;} 163 | friend Color operator +(const Color& a,const Color &b); 164 | friend Color operator *(const Color& a,double k); 165 | friend Color operator *(const Color& a,const Color& b); 166 | Color exp()const; 167 | std::string description()const; 168 | Color adjust()const; 169 | }; 170 | 171 | class Camera { 172 | private: 173 | Vector position; 174 | Vector dx,dy; 175 | Vector origin; 176 | int rx,ry; 177 | double fdepth; 178 | public: 179 | Camera(int rx,int ry); 180 | ~Camera(); 181 | void accept(const Json::Value& val); 182 | void getRay(double scanX, double scanY, Vector &rayO, Vector &rayD); 183 | void addDepth(const Vector& rayO,const Vector& rayD,Vector& resO,Vector& resD); 184 | }; 185 | 186 | 187 | #endif //CODE_CORE_H 188 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | #include 5 | #include "paint.h" 6 | #include "json/json.h" 7 | #include "ppm.h" 8 | #include 9 | #include 10 | #include 11 | 12 | int main(int argc, char** args) 13 | { 14 | std::ifstream ifs("configures/my.json"); 15 | Json::CharReaderBuilder reader; 16 | Json::Value root; 17 | JSONCPP_STRING errs; 18 | Json::parseFromStream(reader, ifs, &root, &errs); 19 | 20 | Render *PPM = new ProgressivePhotonMapping(); 21 | 22 | PaintBoard PB; 23 | PPM->accept(root); 24 | PPM->registerPaintBoard(&PB); 25 | PPM->run(); 26 | PB.update(); 27 | PB.save(); 28 | } 29 | -------------------------------------------------------------------------------- /src/object.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | #include "object.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | BazierCurve::BazierCurve(int id) : id(id) { 11 | } 12 | 13 | void BazierCurve::accept(const Json::Value& val) { 14 | Object::accept(val); 15 | Vector _Q; 16 | _Q.accept(val["position"]); 17 | Q = _Q.eigen(); 18 | for (int i=0;i<4;i++) { 19 | px[i] = val["ctrl_pts"][id][0][i].asDouble(); 20 | py[i] = val["ctrl_pts"][id][1][i].asDouble(); 21 | } 22 | std::cout<getType() != TEXTURE_PURE_COLOR) 37 | std::cout<<"The getColor of BazierCurve only support PURE_COLOR_MODE"<getColor(); 39 | } 40 | int BazierCurve::cylinderCollision(const Vector& _rayO,const Vector& rayD,double r) { 41 | Vector rayO = _rayO - Q; 42 | double ox,oy,dx,dy; 43 | ox = rayO.getY(); 44 | oy = rayO.getZ(); 45 | dx = rayD.getY(); 46 | dy = rayD.getZ(); 47 | double a,b,c; 48 | a = dx*dx+dy*dy; 49 | b = 2*(dx*ox+oy*dy); 50 | c = ox*ox+oy*oy - r*r; 51 | double delta = b*b-4*a*c; 52 | if (delta<=0) 53 | return 0; 54 | double k1 = (-b-sqrt(delta))/(2*a); 55 | double k2 = (-b+sqrt(delta))/(2*a); 56 | double x1 = rayO.getX() + k1 * rayD.getX(); 57 | double x2 = rayO.getX() + k2 * rayD.getX(); 58 | if (x1>x2)std::swap(x1,x2); 59 | if (x2maxX) { 60 | return 0; 61 | } 62 | if (x1maxX) 63 | return 2;//竖直射入 64 | if (x1>minX && x2=0) 77 | u = _u; 78 | else 79 | u = rand()*1.0/RAND_MAX; 80 | double h = rand()*1.0/RAND_MAX *(maxX-minX)+maxX; 81 | t = ((Q.x() + h) - rayO.getX()) / rayD.getX(); 82 | Vector C = rayO + t*rayD; 83 | Vector V = (Q+Vector(h,0,0) - C); 84 | assert(abs(V.getX()) maxR*maxR) 87 | return true; 88 | return true; 89 | } 90 | 91 | bool BazierCurve::collideWith(const Vector& rayO,const Vector& rayD,Collision& collision) { 92 | Eigen::Vector3d O = rayO.eigen(); 93 | Eigen::Vector3d D = rayD.eigen(); 94 | collision.dist = 1e100; 95 | if (!checkCollision(rayO,rayD)) 96 | return false; 97 | for (int cnt=0;cnt<35 ;cnt++){ 98 | double lr = .7; 99 | double t; 100 | double u; 101 | double theta; 102 | if (!initArgs(t,u,theta,rayO,rayD,cnt<2?cnt:-1)) { 103 | continue; 104 | } 105 | Eigen::Vector3d args(t,u,theta); 106 | bool flag = false; 107 | for (int iter=0;iter<20;iter++) { 108 | t = args.x(); 109 | u = args.y(); 110 | theta = args.z(); 111 | if (u<-.5 || u>1.5)break; 112 | Eigen::Vector3d F = getF(t,u,theta,O,D); 113 | Eigen::Matrix3d dF = getdF(t,u,theta,O,D); 114 | if (std::max(std::max(std::abs(F.x()),std::abs(F.y())),std::abs(F.z())) < 1e-7) { 115 | flag = true; 116 | break; 117 | } 118 | args = args - (dF.inverse()*F)*lr; 119 | } 120 | if (!flag)continue; 121 | if (t<0)continue; 122 | if (u<0 || u>1)continue; 123 | if (t > collision.dist)continue; 124 | collision.C = rayO + t*rayD; 125 | collision.dist = t; 126 | Eigen::Vector3d pspu(getdP(py,u), sin(theta)*getdP(px,u),cos(theta)*getdP(px,u)); 127 | Eigen::Vector3d pspt(0, cos(theta)*getP(px,u) , -sin(theta)*getP(px,u)); 128 | Eigen::Vector3d _N = pspu.cross(pspt); 129 | collision.N = Vector(_N).unit(); 130 | collision.face = (collision.N ^ rayD.reverse()) > 0; 131 | if (!collision.face) 132 | collision.N = collision.N.reverse(); 133 | collision.I = rayD; 134 | collision.belongs = this; 135 | } 136 | if (collision.dist < 1e90){return true;} 137 | return false; 138 | } 139 | 140 | inline double BazierCurve::getP(double* p,double t) { 141 | return 1*p[0]*(1-t)*(1-t)*(1-t) + 142 | 3*p[1]*t*(1-t)*(1-t) + 143 | 3*p[2]*t*t*(1-t) + 144 | 1*p[3]*t*t*t; 145 | } 146 | 147 | inline double BazierCurve::getdP(double* p,double t) { 148 | return -3*p[0]*(1-t)*(1-t) + 149 | 3*p[1]*(1-t)*(1-t) + 150 | -6*p[1]*t*(1-t) + 151 | 6*p[2]*(1-t)*t + 152 | -3*p[2]*t*t + 153 | 3*p[3]*t*t; 154 | } 155 | 156 | Eigen::Vector3d BazierCurve::getC(double t,const Eigen::Vector3d& O,const Eigen::Vector3d& D) { 157 | return O + D*t; 158 | } 159 | 160 | Eigen::Vector3d BazierCurve::getS(double u,double theta) { 161 | return Q + Eigen::Vector3d( getP(py,u), sin(theta)*getP(px,u), cos(theta)*getP(px,u)); 162 | } 163 | 164 | Eigen::Vector3d BazierCurve::getF(double t,double u,double theta, const Eigen::Vector3d& O,const Eigen::Vector3d& D) { 165 | return getC(t,O,D) - getS(u,theta); 166 | } 167 | 168 | Eigen::Matrix3d BazierCurve::getdF(double t,double u,double theta, const Eigen::Vector3d& O,const Eigen::Vector3d& D) { 169 | Eigen::Matrix3d res; 170 | res << 171 | D.x() , -getdP(py,u) , 0, 172 | D.y() , -sin(theta)*getdP(px,u) , -cos(theta)*getP(px,u) , 173 | D.z() , -cos(theta)*getdP(px,u) , +sin(theta)*getP(px,u) ; 174 | return res; 175 | } 176 | 177 | 178 | 179 | Sphere::Sphere() { 180 | } 181 | 182 | void Sphere::accept(const Json::Value& val) { 183 | Object::accept(val); 184 | O.accept(val["center"]); 185 | radius = val["radius"].asDouble(); 186 | } 187 | 188 | Color Sphere::getColor(const Vector&v)const { 189 | if (texture->getType() == TEXTURE_PURE_COLOR) 190 | { 191 | return texture->getColor(); 192 | }else if (texture->getType() == TEXTURE_PICTURE) { 193 | Vector tmp = (v - O)/radius; 194 | if (!tmp.isUnit()) 195 | std::cout<<"The vector is not on the surface!"<getColor(x,y); 199 | return res; 200 | } 201 | assert(false); 202 | } 203 | 204 | bool Sphere::collideWith(const Vector& rayO,const Vector& rayD,Collision& collision) { 205 | assert(rayD.isUnit()); 206 | Vector V = O-rayO; 207 | double c = V.sqrlen()-radius*radius; 208 | double b = -(V^rayD)*2; 209 | double a = rayD.sqrlen(); 210 | double delta = b*b-4*a*c; 211 | if (delta > feps) { 212 | double d1 = (-b-sqrt(delta)) / (2*a); 213 | double d2 = (-b+sqrt(delta)) / (2*a); 214 | collision.dist = d1; 215 | if (d1 < 0 && d2 < 0){ 216 | return false; 217 | }else if (d1 < 0 && d2 >= 0) { 218 | collision.dist = d2; 219 | collision.face = false; 220 | }else { 221 | collision.dist = d1; 222 | collision.face = true; 223 | } 224 | collision.belongs = this; 225 | collision.C = rayO + rayD * collision.dist; 226 | if (collision.face) 227 | collision.N = (collision.C - O).unit(); 228 | else 229 | collision.N = (O-collision.C).unit(); 230 | Vector NN = collision.N * (collision.N ^ rayD.reverse()); 231 | collision.I = rayD; 232 | return true; 233 | }else { 234 | return false; 235 | } 236 | } 237 | 238 | Plane::Plane() { 239 | } 240 | Plane::Plane(Vector O,Vector dx,Vector dy):O(O),dx(dx),dy(dy) { 241 | } 242 | 243 | void Plane::accept(const Json::Value& val) { 244 | Object::accept(val); 245 | O.accept(val["position"]); 246 | dx.accept(val["dx"]); 247 | dy.accept(val["dy"]); 248 | border = val["border"].asBool(); 249 | } 250 | 251 | Color Plane::getColor(const Vector& pos)const { 252 | if (texture->getType() == TEXTURE_PURE_COLOR) { 253 | return texture->getColor(); 254 | }else if (texture->getType() == TEXTURE_PICTURE) { 255 | double tx = ((pos - O)^dx)/dx.len(); 256 | double ty = ((pos - O)^dy)/dy.len(); 257 | return texture->getColor(tx,ty); 258 | }else 259 | { 260 | std::cout<<"The getColor of Plane only support PURE_COLOR_MODE"<1-feps || r2>1-feps || r1 olist, int shade_quality)const { 303 | Vector rayO = _rayO; 304 | int success_count = 0; 305 | Vector checkO = rayO; 306 | Vector checkT = O; 307 | Vector checkD = (checkT - rayO).unit(); 308 | double dist = (checkT - rayO).len(); 309 | bool flag = true; 310 | for (auto &w: olist) 311 | { 312 | bool flg; 313 | Collision obj_coll; 314 | if ((flg = w->collideWith(checkO,checkD,obj_coll)) && obj_coll.dist < dist) { 315 | return 0; 316 | } 317 | } 318 | return 1; 319 | } 320 | void PointLight::randomlyEmit(Vector& rayO,Vector& rayD)const{ 321 | rayO = O; 322 | rayD = Vector::randomVectorOnSphere(); 323 | } 324 | -------------------------------------------------------------------------------- /src/object.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | #ifndef CODE_OBJECT_H 6 | #define CODE_OBJECT_H 7 | 8 | #include "core.h" 9 | #include "Eigen/Dense" 10 | 11 | class BazierCurve : public Object { 12 | private: 13 | Eigen::Vector3d Q; 14 | Color color; 15 | int id; 16 | double px[4]; 17 | double py[4]; 18 | double maxX,minX; 19 | double maxR,minR; 20 | public: 21 | BazierCurve(int id); 22 | virtual void accept(const Json::Value& val); 23 | Color getColor(const Vector&)const; 24 | bool collideWith(const Vector& rayO,const Vector& rayD,Collision& collision); 25 | double getP(double* p,double t); 26 | double getdP(double* p,double t); 27 | Eigen::Vector3d getC(double t,const Eigen::Vector3d& O,const Eigen::Vector3d& D); 28 | Eigen::Vector3d getdC(double t); 29 | Eigen::Vector3d getS(double u,double theta); 30 | Eigen::Vector3d getF(double t,double u,double theta,const Eigen::Vector3d& O,const Eigen::Vector3d& D); 31 | Eigen::Matrix3d getdF(double t,double u,double theta,const Eigen::Vector3d& O,const Eigen::Vector3d& D); 32 | bool initArgs(double &t,double &u,double &theta,Vector rayO,Vector rayD,double _u); 33 | bool checkCollision(const Vector& rayO,const Vector& rayD); 34 | int cylinderCollision(const Vector& rayO,const Vector& rayD,double r); 35 | }; 36 | 37 | class Sphere : public Object { 38 | private: 39 | Vector O; 40 | double radius; 41 | public: 42 | Sphere(); 43 | virtual void accept(const Json::Value& val); 44 | Color getColor(const Vector&)const; 45 | bool collideWith(const Vector& rayO,const Vector& rayD,Collision& collision); 46 | }; 47 | 48 | class Plane : public Object { 49 | private: 50 | Vector O; 51 | Vector dx,dy; 52 | bool border; 53 | public: 54 | Plane(); 55 | Plane(Vector O,Vector dx,Vector dy); 56 | void accept(const Json::Value& val); 57 | Color getColor(const Vector&)const; 58 | bool collideWith(const Vector& rayO,const Vector& rayD,Collision& collision); 59 | }; 60 | 61 | 62 | class PointLight : public Light { 63 | private: 64 | Vector O; 65 | public: 66 | PointLight(){} 67 | void accept(const Json::Value& val); 68 | bool collideWith(const Vector& rayO, const Vector& rayD, Collision& collision); 69 | Vector getCenter()const; 70 | double getShade(const Vector& rayO,std::vector olist,int shade_quality)const; 71 | void randomlyEmit(Vector& rayO,Vector& rayD)const; 72 | }; 73 | 74 | 75 | #endif //CODE_OBJECT_H 76 | -------------------------------------------------------------------------------- /src/paint.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | #include "paint.h" 6 | #include 7 | using namespace cv; 8 | 9 | PaintBoard::PaintBoard() { 10 | sizX = -1,sizY = -1; 11 | image = NULL; 12 | } 13 | PaintBoard::~PaintBoard() { 14 | } 15 | 16 | void PaintBoard::init(int sizX,int sizY,Color** _board) { 17 | this->sizX = sizX; 18 | this->sizY = sizY; 19 | image = new Mat(this->sizX,this->sizY,CV_64FC3,Scalar(1.0,1.0,1.0)); 20 | board = _board; 21 | } 22 | 23 | void PaintBoard::update() { 24 | assert(image); 25 | for (int i=0;iat(i,j) = v; 31 | } 32 | } 33 | } 34 | void PaintBoard::display() { 35 | imshow("picture", *image); 36 | waitKey(0); 37 | } 38 | void PaintBoard::save_raw() { 39 | FILE* fout = fopen("result.ppm","w"); 40 | fprintf(fout,"P3 %d %d\n",sizY,sizX); 41 | fprintf(fout,"255\n"); 42 | for (int i=0;icompression_params; 55 | compression_params.push_back(IMWRITE_PNG_COMPRESSION); 56 | compression_params.push_back(9); 57 | imwrite("result.bmp", (*image)*255); 58 | } 59 | -------------------------------------------------------------------------------- /src/paint.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | #ifndef PAINT_BOARD_H 6 | #define PAINT_BOARD_H 7 | #include 8 | #include 9 | 10 | #include "core.h" 11 | using namespace std; 12 | 13 | class PaintBoard { 14 | private: 15 | cv::Mat *image; 16 | Color **board; 17 | int sizX,sizY; 18 | public: 19 | PaintBoard(); 20 | ~PaintBoard(); 21 | void init(int sizX,int sizY,Color** _board); 22 | void update(); 23 | void display(); 24 | void save(); 25 | void save_raw(); 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/ppm.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | #include "ppm.h" 6 | #include 7 | #include "core.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | ViewPoint::ViewPoint(Vector pos,Vector N,Color color,double stgh,int x,int y) : C(pos),N(N),color(color),strength(stgh),x(x),y(y) {} 16 | 17 | ProgressivePhotonMapping::ProgressivePhotonMapping() { 18 | view_root = NULL; 19 | } 20 | 21 | ProgressivePhotonMapping::~ProgressivePhotonMapping() { 22 | } 23 | 24 | 25 | void ProgressivePhotonMapping::accept(const Json::Value& val) { 26 | Render::accept(val); 27 | Scene::accept(val,rx,ry); 28 | max_depth = val["max_depth"].asInt(); 29 | start_rows = val["start_rows"].asInt(); 30 | start_cols = val["start_cols"].asInt(); 31 | bazier_quality = val["bazier_quality"].asInt(); 32 | total_round = val["total_round"].asInt(); 33 | photon_num = val["photon_num"].asInt(); 34 | total_brightness = val["total_brightness"].asDouble(); 35 | round_decay = val["round_decay"].asDouble(); 36 | initial_r = val["initial_r"].asDouble(); 37 | max_jump = val["max_jump"].asInt(); 38 | board = new Color[rx*ry]; 39 | for (int i=0;igetRay(_i,_j,rayO,rayD); 70 | if (i == 0 && j == 0) 71 | cout<getBrightness(); 82 | for (auto &lgt : lights) { 83 | int lgt_emit_count = photon_num*lgt->getBrightness()/brightness; 84 | #pragma omp for 85 | for (int i=0;irandomlyEmit(rayO,rayD); 88 | photonTracing(rayO,rayD,lgt->getColor(lgt->getCenter()),0,current_r,total_brightness/photon_num,0,0); 89 | } 90 | } 91 | releaseKDTree(view_root); 92 | for (int i=0;i max_jump) 102 | return ; 103 | Collision obj_coll; 104 | const Object* obj; 105 | obj = findCollidedObject(rayO,rayD,obj_coll); 106 | if (!obj)return; 107 | dist += obj_coll.dist; 108 | if (obj->getMaterial().refl > feps) { 109 | Vector resO,resD; 110 | obj_coll.reflection(resO,resD); 111 | photonTracing(resO,resD,rayC,depth+1,r,lambda*obj->getMaterial().refl,dist,diff_count); 112 | } 113 | if (obj->getMaterial().refr > feps) { 114 | Color acol; 115 | if (!obj_coll.face) 116 | acol = (obj->getAbsorb().getColor(0,0)*-obj_coll.dist).exp(); 117 | else 118 | acol = Color(1,1,1); 119 | Vector resO,resD; 120 | obj_coll.refraction(resO,resD); 121 | photonTracing(resO,resD,rayC*acol,depth+1,r,lambda*obj->getMaterial().refr,dist,diff_count); 122 | } 123 | if (obj->getMaterial().diff > feps) { 124 | vector vps; 125 | queryKDTree(view_root,vps,obj_coll.getSurfaceC(),r); 126 | for (auto&w : vps) { 127 | if ((w->N ^ rayD)<-feps) { 128 | Color res = rayC * w->color 129 | * pow(((r-(w->C-obj_coll.getSurfaceC()).len())/r),2) 130 | * lambda 131 | * (1.0/(diff_count+1)) 132 | * w->strength; 133 | #pragma omp critical 134 | bg_pic[w->x * ry + w->y] += res; 135 | } 136 | } 137 | Vector resO,resD; 138 | obj_coll.diffusion(resO,resD); 139 | photonTracing(resO,resD,rayC*obj->getColor(obj_coll.C),depth+1,r,lambda*obj->getMaterial().diff,dist+obj_coll.dist,diff_count+1); 140 | } 141 | } 142 | 143 | void ProgressivePhotonMapping::RayTracing(const Vector& rayO,const Vector& rayD,Color rayC,int xx,int yy,int depth,double lambda,double dist) { 144 | if (lambda < 1e-9 || depth > max_depth) 145 | return ; 146 | Collision obj_coll,lgt_coll; 147 | const Object* obj = findCollidedObject(rayO,rayD,obj_coll); 148 | const Light* lgt = findCollidedLight(rayO,rayD,lgt_coll); 149 | if ((!obj && !lgt)) { 150 | bg_pic[xx*ry+yy] += bg_color*lambda; 151 | }else if ((!obj && lgt) || (obj && lgt && obj_coll.dist > lgt_coll.dist)) { 152 | bg_pic[xx*ry+yy] += lgt->getColor(lgt_coll.C)*lambda; 153 | }else { 154 | if (obj->getMaterial().refr > feps) { 155 | Color acol; 156 | if (!obj_coll.face) 157 | acol = (obj->getAbsorb().getColor(0,0)*-obj_coll.dist).exp(); 158 | else 159 | acol = Color(1,1,1); 160 | Vector resO,resD; 161 | obj_coll.refraction(resO,resD); 162 | RayTracing(resO,resD,rayC*acol,xx,yy,depth+1,lambda*obj->getMaterial().refr,dist+obj_coll.dist); 163 | } 164 | if (obj->getMaterial().refl > feps) { 165 | Vector resO,resD; 166 | obj_coll.reflection(resO,resD); 167 | RayTracing(resO,resD,rayC,xx,yy,depth+1,lambda*obj->getMaterial().refl,dist+obj_coll.dist); 168 | } 169 | if (obj->getMaterial().diff > feps) { 170 | #pragma omp critical 171 | view_pts.push_back( 172 | ViewPoint( 173 | obj_coll.getSurfaceC(), 174 | obj_coll.N, 175 | rayC*obj->getColor(obj_coll.C), 176 | lambda*obj->getMaterial().diff, 177 | xx,yy 178 | ) 179 | ); 180 | } 181 | } 182 | } 183 | 184 | void ProgressivePhotonMapping::buildKDTree(KDTreeNode* &node, std::vector &lst, int l,int r,int dim) { 185 | if (l == -1 && r == -1) 186 | l = 0, r = lst.size(); 187 | if (l >= r) 188 | return; 189 | int mid = (l+r)>>1; 190 | switch(dim) { 191 | case 0: nth_element(lst.begin()+l,lst.begin()+mid,lst.begin()+r,ViewPointComparer<0>()); 192 | case 1: nth_element(lst.begin()+l,lst.begin()+mid,lst.begin()+r,ViewPointComparer<1>()); 193 | case 2: nth_element(lst.begin()+l,lst.begin()+mid,lst.begin()+r,ViewPointComparer<2>()); 194 | } 195 | node = new KDTreeNode(); 196 | node->value = lst[mid]; 197 | node->lch = node->rch = NULL; 198 | node->split_dim = dim; 199 | node->bd_max = node->value.C; 200 | node->bd_min = node->value.C; 201 | buildKDTree(node->lch,lst,l,mid,(dim+1)%3); 202 | if (node->lch) { 203 | node->bd_max = each_max(node->bd_max,node->lch->bd_max); 204 | node->bd_min = each_min(node->bd_min,node->lch->bd_min); 205 | } 206 | buildKDTree(node->rch,lst,mid+1,r,(dim+1)%3); 207 | if (node->rch) { 208 | node->bd_max = each_max(node->bd_max,node->rch->bd_max); 209 | node->bd_min = each_min(node->bd_min,node->rch->bd_min); 210 | } 211 | } 212 | 213 | void ProgressivePhotonMapping::queryKDTree(KDTreeNode* node, vector &result, const Vector& pos, double r) { 214 | double dx,dy,dz; 215 | if (pos.getX() <= node->bd_max.getX() && pos.getX() >= node->bd_min.getX()) 216 | dx = 0; 217 | else 218 | dx = min(abs(pos.getX()-node->bd_max.getX()),abs(pos.getX()-node->bd_min.getX())); 219 | if (pos.getY() <= node->bd_max.getY() && pos.getY() >= node->bd_min.getY()) 220 | dy = 0; 221 | else 222 | dy = min(abs(pos.getY()-node->bd_max.getY()),abs(pos.getY()-node->bd_min.getY())); 223 | if (pos.getZ() <= node->bd_max.getZ() && pos.getZ() >= node->bd_min.getZ()) 224 | dz = 0; 225 | else 226 | dz = min(abs(pos.getZ()-node->bd_max.getZ()),abs(pos.getZ()-node->bd_min.getZ())); 227 | 228 | if (dx*dx + dy*dy + dz*dz >r*r) 229 | return ; 230 | 231 | if ((node->value.C-pos).len()<=r) 232 | result.push_back(&(node->value)); 233 | if (node->lch)queryKDTree(node->lch,result,pos,r); 234 | if (node->rch)queryKDTree(node->rch,result,pos,r); 235 | } 236 | 237 | void ProgressivePhotonMapping::releaseKDTree(KDTreeNode* &node) { 238 | if (!node)return; 239 | releaseKDTree(node->lch); 240 | releaseKDTree(node->rch); 241 | delete node; 242 | } 243 | -------------------------------------------------------------------------------- /src/ppm.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | #ifndef PROGRESSIVE_PHOTON_MAPPING_H 6 | #define PROGRESSIVE_PHOTON_MAPPING_H 7 | 8 | #include 9 | #include "core.h" 10 | #include "scene.h" 11 | #include "json/json.h" 12 | #include "render.h" 13 | 14 | class ViewPoint { 15 | private: 16 | Vector C,N; 17 | Color color; 18 | double strength; 19 | int x,y; 20 | public: 21 | ViewPoint(){} 22 | ViewPoint(Vector pos,Vector N,Color color,double stgh,int x,int y); 23 | friend class ProgressivePhotonMapping; 24 | }; 25 | 26 | class ProgressivePhotonMapping : private Scene, public Render{ 27 | private: 28 | struct KDTreeNode { 29 | public: 30 | ViewPoint value; 31 | KDTreeNode* lch; 32 | KDTreeNode* rch; 33 | int split_dim; 34 | Vector bd_max,bd_min; 35 | }; 36 | template 37 | class ViewPointComparer { 38 | public: 39 | bool operator()(const ViewPoint& p1,const ViewPoint& p2) { 40 | if (dim == 0) 41 | return p1.C.getX() < p2.C.getX(); 42 | if (dim == 1) 43 | return p1.C.getY() < p2.C.getY(); 44 | if (dim == 2) 45 | return p1.C.getZ() < p2.C.getZ(); 46 | } 47 | }; 48 | KDTreeNode* view_root; 49 | 50 | int max_depth; 51 | int start_rows; 52 | int start_cols; 53 | int bazier_quality; 54 | int total_round; 55 | int photon_num; 56 | double total_brightness; 57 | double round_decay; 58 | double initial_r; 59 | int max_jump; 60 | std::vector view_pts; 61 | Color* bg_pic; 62 | public: 63 | //INIT 64 | ProgressivePhotonMapping(); 65 | ~ProgressivePhotonMapping(); 66 | virtual void accept(const Json::Value& val); 67 | 68 | void run(); 69 | void RayTracing(const Vector& rayO, const Vector& rayD,Color rayC,int xx,int yy,int depth,double lambda,double dist); 70 | void photonTracing(const Vector& rayO, const Vector& rayD, const Color& rayC,int depth, double r, double lambda, double dist,int diff_count); 71 | 72 | void buildKDTree(KDTreeNode* &now,std::vector &lst,int l = -1,int r = -1,int dim = 0); 73 | void releaseKDTree(KDTreeNode* &node); 74 | void queryKDTree(KDTreeNode* node, vector &result, const Vector& pos, double r); 75 | }; 76 | 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/render.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | #include "render.h" 6 | #include "paint.h" 7 | #include 8 | 9 | Render::Render(){ 10 | } 11 | 12 | Render::~Render() { 13 | } 14 | 15 | void Render::accept(const Json::Value& val) { 16 | rx = val["rx"].asInt(); 17 | ry = val["ry"].asInt(); 18 | std::cout<<"Reander created <"<"<paint_board->update(); 23 | } 24 | 25 | void Render::registerPaintBoard(PaintBoard* pb) { 26 | paint_board = pb; 27 | paint_board->init(rx,ry,&board); 28 | } 29 | -------------------------------------------------------------------------------- /src/render.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | 6 | #ifndef RENDER_H 7 | #define RENDER_H 8 | #include "json/json.h" 9 | #include "paint.h" 10 | #include "core.h" 11 | 12 | class Render { 13 | protected: 14 | PaintBoard* paint_board; 15 | Color *board; 16 | int rx,ry; 17 | public: 18 | Render(); 19 | ~Render(); 20 | virtual void accept(const Json::Value &val) = 0; 21 | virtual void run() = 0; 22 | void registerPaintBoard(PaintBoard* pb) ; 23 | void update(); 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/scene.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | 6 | #include "scene.h" 7 | #include "core.h" 8 | #include "object.h" 9 | 10 | 11 | Scene::Scene() { 12 | camera = NULL; 13 | } 14 | 15 | Scene::~Scene() { 16 | if (camera) 17 | delete camera; 18 | } 19 | 20 | void Scene::accept(const Json::Value& val,int _rx,int _ry) { 21 | if (val["camera"]["type"].asString() == "default") { 22 | camera = new Camera(_rx,_ry); 23 | camera->accept(val["camera"]); 24 | } 25 | 26 | for (int i=0;iaccept(v); 32 | }else if (tag == "plane") { 33 | objects.push_back(new Plane()); 34 | objects.back()->accept(v); 35 | }else if (tag == "bazier_curves") { 36 | int n = v["ctrl_pts"].size(); 37 | for (int i=0;iaccept(v); 41 | } 42 | }else if(tag[0] == '#') { 43 | }else { 44 | } 45 | } 46 | 47 | for (int i=0;iaccept(v); 54 | }else if (tag == "point_light") { 55 | lights.push_back(new PointLight()); 56 | lights.back()->accept(v); 57 | }else if (tag[0] == '#') { 58 | 59 | }else { 60 | } 61 | } 62 | bg_color.accept(val["bg_color"]); 63 | } 64 | 65 | const Object* Scene::findCollidedObject(const Vector& _rayO,const Vector& _rayD,Collision& resColl) { 66 | Vector rayO = _rayO; 67 | Vector rayD = _rayD; 68 | Object* ret = NULL; 69 | resColl.dist = inf; 70 | for (auto obj : objects) { 71 | Collision obj_coll; 72 | if (obj->collideWith(rayO,rayD,obj_coll)) { 73 | if (obj_coll.dist < resColl.dist) { 74 | ret = obj; 75 | resColl = obj_coll; 76 | } 77 | } 78 | } 79 | return ret; 80 | } 81 | 82 | const Light* Scene::findCollidedLight(const Vector& _rayO, const Vector& _rayD,Collision& resColl) { 83 | Vector rayO = _rayO; 84 | Vector rayD = _rayD; 85 | Light* ret = NULL; 86 | resColl.dist = inf; 87 | for (auto &lgt : lights) { 88 | Collision lgt_coll; 89 | if (lgt->collideWith(rayO,rayD,lgt_coll)) { 90 | if (lgt_coll.dist < resColl.dist) { 91 | resColl = lgt_coll; 92 | ret = lgt; 93 | } 94 | } 95 | } 96 | return ret; 97 | } 98 | 99 | -------------------------------------------------------------------------------- /src/scene.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 李曌珩 on 2019-06-23. 3 | // 4 | 5 | 6 | #ifndef SCENE_H 7 | #define SCENE_H 8 | #include "core.h" 9 | 10 | class Scene { 11 | protected: 12 | Camera *camera; 13 | std::vector lights; 14 | std::vector objects; 15 | Color bg_color; 16 | public: 17 | Scene(); 18 | ~Scene(); 19 | void accept(const Json::Value& val,int _rx,int _ry); 20 | const Object* findCollidedObject(const Vector &rayO,const Vector& rayD,Collision& coll); 21 | const Light* findCollidedLight(const Vector& rayO,const Vector& rayD, Collision& coll); 22 | }; 23 | 24 | #endif 25 | --------------------------------------------------------------------------------