joonsrenderer 1.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +53 -0
  3. data/.mvn/extensions.xml +8 -0
  4. data/CHANGELOG.md +2 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE +674 -0
  7. data/README.md +2 -0
  8. data/Rakefile +43 -0
  9. data/docs/.gitignore +6 -0
  10. data/docs/_config.yml +20 -0
  11. data/docs/_includes/footer.html +38 -0
  12. data/docs/_includes/head.html +15 -0
  13. data/docs/_includes/header.html +27 -0
  14. data/docs/_includes/icon-github.html +1 -0
  15. data/docs/_includes/icon-github.svg +1 -0
  16. data/docs/_includes/icon-twitter.html +1 -0
  17. data/docs/_includes/icon-twitter.svg +1 -0
  18. data/docs/_layouts/default.html +20 -0
  19. data/docs/_layouts/page.html +14 -0
  20. data/docs/_layouts/post.html +15 -0
  21. data/docs/_posts/2017-01-08-animated_ray_tracing.md +72 -0
  22. data/docs/_posts/2017-01-08-welcome.md +78 -0
  23. data/docs/_sass/_base.scss +206 -0
  24. data/docs/_sass/_layout.scss +242 -0
  25. data/docs/_sass/_syntax-highlighting.scss +71 -0
  26. data/docs/about.md +12 -0
  27. data/docs/assets/Animation.ogv +0 -0
  28. data/docs/assets/Animation.png +0 -0
  29. data/docs/assets/basic.png +0 -0
  30. data/docs/assets/basic_traced.png +0 -0
  31. data/docs/css/main.scss +38 -0
  32. data/docs/favicon.ico +0 -0
  33. data/docs/feed.xml +30 -0
  34. data/docs/index.html +38 -0
  35. data/joonsrenderer.gemspec +23 -0
  36. data/lib/joonsrenderer.rb +12 -0
  37. data/lib/joonsrenderer/version.rb +3 -0
  38. data/pom.rb +75 -0
  39. data/pom.xml +163 -0
  40. data/src/main/java/SunflowGUI.java +1354 -0
  41. data/src/main/java/joons/JRFiller.java +79 -0
  42. data/src/main/java/joons/JRImagePanel.java +141 -0
  43. data/src/main/java/joons/JRRecorder.java +183 -0
  44. data/src/main/java/joons/JRStatics.java +199 -0
  45. data/src/main/java/joons/JoonsRenderer.java +837 -0
  46. data/src/main/java/org/sunflow/AsciiFileSunflowAPI.java +98 -0
  47. data/src/main/java/org/sunflow/Benchmark.java +313 -0
  48. data/src/main/java/org/sunflow/BinaryFileSunflowAPI.java +228 -0
  49. data/src/main/java/org/sunflow/FileSunflowAPI.java +354 -0
  50. data/src/main/java/org/sunflow/PluginRegistry.java +322 -0
  51. data/src/main/java/org/sunflow/RealtimeBenchmark.java +125 -0
  52. data/src/main/java/org/sunflow/RenderObjectMap.java +344 -0
  53. data/src/main/java/org/sunflow/SunflowAPI.java +762 -0
  54. data/src/main/java/org/sunflow/SunflowAPIInterface.java +277 -0
  55. data/src/main/java/org/sunflow/core/AccelerationStructure.java +20 -0
  56. data/src/main/java/org/sunflow/core/AccelerationStructureFactory.java +36 -0
  57. data/src/main/java/org/sunflow/core/BucketOrder.java +21 -0
  58. data/src/main/java/org/sunflow/core/Camera.java +125 -0
  59. data/src/main/java/org/sunflow/core/CameraLens.java +29 -0
  60. data/src/main/java/org/sunflow/core/CausticPhotonMapInterface.java +15 -0
  61. data/src/main/java/org/sunflow/core/Display.java +78 -0
  62. data/src/main/java/org/sunflow/core/Filter.java +27 -0
  63. data/src/main/java/org/sunflow/core/GIEngine.java +42 -0
  64. data/src/main/java/org/sunflow/core/Geometry.java +157 -0
  65. data/src/main/java/org/sunflow/core/GlobalPhotonMapInterface.java +21 -0
  66. data/src/main/java/org/sunflow/core/ImageSampler.java +26 -0
  67. data/src/main/java/org/sunflow/core/Instance.java +224 -0
  68. data/src/main/java/org/sunflow/core/InstanceList.java +83 -0
  69. data/src/main/java/org/sunflow/core/IntersectionState.java +120 -0
  70. data/src/main/java/org/sunflow/core/LightSample.java +104 -0
  71. data/src/main/java/org/sunflow/core/LightServer.java +382 -0
  72. data/src/main/java/org/sunflow/core/LightSource.java +67 -0
  73. data/src/main/java/org/sunflow/core/Modifier.java +16 -0
  74. data/src/main/java/org/sunflow/core/Options.java +20 -0
  75. data/src/main/java/org/sunflow/core/ParameterList.java +758 -0
  76. data/src/main/java/org/sunflow/core/PhotonStore.java +62 -0
  77. data/src/main/java/org/sunflow/core/PrimitiveList.java +70 -0
  78. data/src/main/java/org/sunflow/core/Ray.java +219 -0
  79. data/src/main/java/org/sunflow/core/RenderObject.java +25 -0
  80. data/src/main/java/org/sunflow/core/Scene.java +377 -0
  81. data/src/main/java/org/sunflow/core/SceneParser.java +58 -0
  82. data/src/main/java/org/sunflow/core/Shader.java +30 -0
  83. data/src/main/java/org/sunflow/core/ShadingCache.java +84 -0
  84. data/src/main/java/org/sunflow/core/ShadingState.java +939 -0
  85. data/src/main/java/org/sunflow/core/Statistics.java +85 -0
  86. data/src/main/java/org/sunflow/core/Tesselatable.java +36 -0
  87. data/src/main/java/org/sunflow/core/Texture.java +128 -0
  88. data/src/main/java/org/sunflow/core/TextureCache.java +48 -0
  89. data/src/main/java/org/sunflow/core/accel/BoundingIntervalHierarchy.java +652 -0
  90. data/src/main/java/org/sunflow/core/accel/KDTree.java +833 -0
  91. data/src/main/java/org/sunflow/core/accel/NullAccelerator.java +30 -0
  92. data/src/main/java/org/sunflow/core/accel/UniformGrid.java +329 -0
  93. data/src/main/java/org/sunflow/core/bucket/BucketOrderFactory.java +26 -0
  94. data/src/main/java/org/sunflow/core/bucket/ColumnBucketOrder.java +21 -0
  95. data/src/main/java/org/sunflow/core/bucket/DiagonalBucketOrder.java +28 -0
  96. data/src/main/java/org/sunflow/core/bucket/HilbertBucketOrder.java +65 -0
  97. data/src/main/java/org/sunflow/core/bucket/InvertedBucketOrder.java +28 -0
  98. data/src/main/java/org/sunflow/core/bucket/RandomBucketOrder.java +49 -0
  99. data/src/main/java/org/sunflow/core/bucket/RowBucketOrder.java +21 -0
  100. data/src/main/java/org/sunflow/core/bucket/SpiralBucketOrder.java +43 -0
  101. data/src/main/java/org/sunflow/core/camera/FisheyeLens.java +25 -0
  102. data/src/main/java/org/sunflow/core/camera/PinholeLens.java +43 -0
  103. data/src/main/java/org/sunflow/core/camera/SphericalLens.java +22 -0
  104. data/src/main/java/org/sunflow/core/camera/ThinLens.java +107 -0
  105. data/src/main/java/org/sunflow/core/display/FastDisplay.java +119 -0
  106. data/src/main/java/org/sunflow/core/display/FileDisplay.java +83 -0
  107. data/src/main/java/org/sunflow/core/display/FrameDisplay.java +97 -0
  108. data/src/main/java/org/sunflow/core/display/ImgPipeDisplay.java +109 -0
  109. data/src/main/java/org/sunflow/core/filter/BlackmanHarrisFilter.java +28 -0
  110. data/src/main/java/org/sunflow/core/filter/BoxFilter.java +16 -0
  111. data/src/main/java/org/sunflow/core/filter/CatmullRomFilter.java +29 -0
  112. data/src/main/java/org/sunflow/core/filter/CubicBSpline.java +32 -0
  113. data/src/main/java/org/sunflow/core/filter/GaussianFilter.java +24 -0
  114. data/src/main/java/org/sunflow/core/filter/LanczosFilter.java +30 -0
  115. data/src/main/java/org/sunflow/core/filter/MitchellFilter.java +28 -0
  116. data/src/main/java/org/sunflow/core/filter/SincFilter.java +25 -0
  117. data/src/main/java/org/sunflow/core/filter/TriangleFilter.java +16 -0
  118. data/src/main/java/org/sunflow/core/gi/AmbientOcclusionGIEngine.java +57 -0
  119. data/src/main/java/org/sunflow/core/gi/FakeGIEngine.java +48 -0
  120. data/src/main/java/org/sunflow/core/gi/InstantGI.java +194 -0
  121. data/src/main/java/org/sunflow/core/gi/IrradianceCacheGIEngine.java +268 -0
  122. data/src/main/java/org/sunflow/core/gi/PathTracingGIEngine.java +65 -0
  123. data/src/main/java/org/sunflow/core/light/DirectionalSpotlight.java +103 -0
  124. data/src/main/java/org/sunflow/core/light/ImageBasedLight.java +303 -0
  125. data/src/main/java/org/sunflow/core/light/PointLight.java +72 -0
  126. data/src/main/java/org/sunflow/core/light/SphereLight.java +166 -0
  127. data/src/main/java/org/sunflow/core/light/SunSkyLight.java +362 -0
  128. data/src/main/java/org/sunflow/core/light/TriangleMeshLight.java +296 -0
  129. data/src/main/java/org/sunflow/core/modifiers/BumpMappingModifier.java +37 -0
  130. data/src/main/java/org/sunflow/core/modifiers/NormalMapModifier.java +34 -0
  131. data/src/main/java/org/sunflow/core/modifiers/PerlinModifier.java +80 -0
  132. data/src/main/java/org/sunflow/core/parser/Keyword.java +39 -0
  133. data/src/main/java/org/sunflow/core/parser/RA2Parser.java +107 -0
  134. data/src/main/java/org/sunflow/core/parser/RA3Parser.java +68 -0
  135. data/src/main/java/org/sunflow/core/parser/SCAbstractParser.java +299 -0
  136. data/src/main/java/org/sunflow/core/parser/SCAsciiParser.java +251 -0
  137. data/src/main/java/org/sunflow/core/parser/SCBinaryParser.java +156 -0
  138. data/src/main/java/org/sunflow/core/parser/SCParser.java +1403 -0
  139. data/src/main/java/org/sunflow/core/parser/ShaveRibParser.java +174 -0
  140. data/src/main/java/org/sunflow/core/parser/TriParser.java +79 -0
  141. data/src/main/java/org/sunflow/core/photonmap/CausticPhotonMap.java +429 -0
  142. data/src/main/java/org/sunflow/core/photonmap/GlobalPhotonMap.java +530 -0
  143. data/src/main/java/org/sunflow/core/photonmap/GridPhotonMap.java +308 -0
  144. data/src/main/java/org/sunflow/core/primitive/Background.java +55 -0
  145. data/src/main/java/org/sunflow/core/primitive/BanchoffSurface.java +100 -0
  146. data/src/main/java/org/sunflow/core/primitive/Box.java +210 -0
  147. data/src/main/java/org/sunflow/core/primitive/CornellBox.java +476 -0
  148. data/src/main/java/org/sunflow/core/primitive/CubeGrid.java +318 -0
  149. data/src/main/java/org/sunflow/core/primitive/Cylinder.java +104 -0
  150. data/src/main/java/org/sunflow/core/primitive/Hair.java +275 -0
  151. data/src/main/java/org/sunflow/core/primitive/JuliaFractal.java +266 -0
  152. data/src/main/java/org/sunflow/core/primitive/ParticleSurface.java +114 -0
  153. data/src/main/java/org/sunflow/core/primitive/Plane.java +163 -0
  154. data/src/main/java/org/sunflow/core/primitive/QuadMesh.java +413 -0
  155. data/src/main/java/org/sunflow/core/primitive/Sphere.java +101 -0
  156. data/src/main/java/org/sunflow/core/primitive/SphereFlake.java +234 -0
  157. data/src/main/java/org/sunflow/core/primitive/Torus.java +145 -0
  158. data/src/main/java/org/sunflow/core/primitive/TriangleMesh.java +849 -0
  159. data/src/main/java/org/sunflow/core/renderer/BucketRenderer.java +491 -0
  160. data/src/main/java/org/sunflow/core/renderer/MultipassRenderer.java +237 -0
  161. data/src/main/java/org/sunflow/core/renderer/ProgressiveRenderer.java +171 -0
  162. data/src/main/java/org/sunflow/core/renderer/SimpleRenderer.java +106 -0
  163. data/src/main/java/org/sunflow/core/shader/AmbientOcclusionShader.java +53 -0
  164. data/src/main/java/org/sunflow/core/shader/AnisotropicWardShader.java +216 -0
  165. data/src/main/java/org/sunflow/core/shader/ConstantShader.java +31 -0
  166. data/src/main/java/org/sunflow/core/shader/DiffuseShader.java +65 -0
  167. data/src/main/java/org/sunflow/core/shader/GlassShader.java +147 -0
  168. data/src/main/java/org/sunflow/core/shader/IDShader.java +27 -0
  169. data/src/main/java/org/sunflow/core/shader/MirrorShader.java +68 -0
  170. data/src/main/java/org/sunflow/core/shader/NormalShader.java +32 -0
  171. data/src/main/java/org/sunflow/core/shader/PhongShader.java +89 -0
  172. data/src/main/java/org/sunflow/core/shader/PrimIDShader.java +30 -0
  173. data/src/main/java/org/sunflow/core/shader/QuickGrayShader.java +63 -0
  174. data/src/main/java/org/sunflow/core/shader/ShinyDiffuseShader.java +98 -0
  175. data/src/main/java/org/sunflow/core/shader/SimpleShader.java +24 -0
  176. data/src/main/java/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java +31 -0
  177. data/src/main/java/org/sunflow/core/shader/TexturedDiffuseShader.java +31 -0
  178. data/src/main/java/org/sunflow/core/shader/TexturedPhongShader.java +31 -0
  179. data/src/main/java/org/sunflow/core/shader/TexturedShinyDiffuseShader.java +31 -0
  180. data/src/main/java/org/sunflow/core/shader/TexturedWardShader.java +31 -0
  181. data/src/main/java/org/sunflow/core/shader/UVShader.java +27 -0
  182. data/src/main/java/org/sunflow/core/shader/UberShader.java +149 -0
  183. data/src/main/java/org/sunflow/core/shader/ViewCausticsShader.java +33 -0
  184. data/src/main/java/org/sunflow/core/shader/ViewGlobalPhotonsShader.java +25 -0
  185. data/src/main/java/org/sunflow/core/shader/ViewIrradianceShader.java +25 -0
  186. data/src/main/java/org/sunflow/core/shader/WireframeShader.java +83 -0
  187. data/src/main/java/org/sunflow/core/tesselatable/BezierMesh.java +254 -0
  188. data/src/main/java/org/sunflow/core/tesselatable/FileMesh.java +251 -0
  189. data/src/main/java/org/sunflow/core/tesselatable/Gumbo.java +1147 -0
  190. data/src/main/java/org/sunflow/core/tesselatable/Teapot.java +237 -0
  191. data/src/main/java/org/sunflow/image/Bitmap.java +15 -0
  192. data/src/main/java/org/sunflow/image/BitmapReader.java +39 -0
  193. data/src/main/java/org/sunflow/image/BitmapWriter.java +79 -0
  194. data/src/main/java/org/sunflow/image/BlackbodySpectrum.java +16 -0
  195. data/src/main/java/org/sunflow/image/ChromaticitySpectrum.java +55 -0
  196. data/src/main/java/org/sunflow/image/Color.java +374 -0
  197. data/src/main/java/org/sunflow/image/ColorEncoder.java +94 -0
  198. data/src/main/java/org/sunflow/image/ColorFactory.java +122 -0
  199. data/src/main/java/org/sunflow/image/ConstantSpectralCurve.java +21 -0
  200. data/src/main/java/org/sunflow/image/IrregularSpectralCurve.java +57 -0
  201. data/src/main/java/org/sunflow/image/RGBSpace.java +207 -0
  202. data/src/main/java/org/sunflow/image/RegularSpectralCurve.java +30 -0
  203. data/src/main/java/org/sunflow/image/SpectralCurve.java +118 -0
  204. data/src/main/java/org/sunflow/image/XYZColor.java +50 -0
  205. data/src/main/java/org/sunflow/image/formats/BitmapBlack.java +27 -0
  206. data/src/main/java/org/sunflow/image/formats/BitmapG8.java +36 -0
  207. data/src/main/java/org/sunflow/image/formats/BitmapGA8.java +30 -0
  208. data/src/main/java/org/sunflow/image/formats/BitmapRGB8.java +40 -0
  209. data/src/main/java/org/sunflow/image/formats/BitmapRGBA8.java +40 -0
  210. data/src/main/java/org/sunflow/image/formats/BitmapRGBE.java +60 -0
  211. data/src/main/java/org/sunflow/image/formats/BitmapXYZ.java +38 -0
  212. data/src/main/java/org/sunflow/image/formats/GenericBitmap.java +73 -0
  213. data/src/main/java/org/sunflow/image/readers/BMPBitmapReader.java +39 -0
  214. data/src/main/java/org/sunflow/image/readers/HDRBitmapReader.java +155 -0
  215. data/src/main/java/org/sunflow/image/readers/IGIBitmapReader.java +104 -0
  216. data/src/main/java/org/sunflow/image/readers/JPGBitmapReader.java +39 -0
  217. data/src/main/java/org/sunflow/image/readers/PNGBitmapReader.java +40 -0
  218. data/src/main/java/org/sunflow/image/readers/TGABitmapReader.java +141 -0
  219. data/src/main/java/org/sunflow/image/writers/EXRBitmapWriter.java +395 -0
  220. data/src/main/java/org/sunflow/image/writers/HDRBitmapWriter.java +54 -0
  221. data/src/main/java/org/sunflow/image/writers/IGIBitmapWriter.java +75 -0
  222. data/src/main/java/org/sunflow/image/writers/PNGBitmapWriter.java +39 -0
  223. data/src/main/java/org/sunflow/image/writers/TGABitmapWriter.java +63 -0
  224. data/src/main/java/org/sunflow/math/BoundingBox.java +340 -0
  225. data/src/main/java/org/sunflow/math/MathUtils.java +159 -0
  226. data/src/main/java/org/sunflow/math/Matrix4.java +573 -0
  227. data/src/main/java/org/sunflow/math/MovingMatrix4.java +119 -0
  228. data/src/main/java/org/sunflow/math/OrthoNormalBasis.java +110 -0
  229. data/src/main/java/org/sunflow/math/PerlinScalar.java +331 -0
  230. data/src/main/java/org/sunflow/math/PerlinVector.java +132 -0
  231. data/src/main/java/org/sunflow/math/Point2.java +36 -0
  232. data/src/main/java/org/sunflow/math/Point3.java +133 -0
  233. data/src/main/java/org/sunflow/math/QMC.java +209 -0
  234. data/src/main/java/org/sunflow/math/Solvers.java +142 -0
  235. data/src/main/java/org/sunflow/math/Vector3.java +197 -0
  236. data/src/main/java/org/sunflow/system/BenchmarkFramework.java +73 -0
  237. data/src/main/java/org/sunflow/system/BenchmarkTest.java +17 -0
  238. data/src/main/java/org/sunflow/system/ByteUtil.java +119 -0
  239. data/src/main/java/org/sunflow/system/FileUtils.java +27 -0
  240. data/src/main/java/org/sunflow/system/ImagePanel.java +282 -0
  241. data/src/main/java/org/sunflow/system/Memory.java +18 -0
  242. data/src/main/java/org/sunflow/system/Parser.java +162 -0
  243. data/src/main/java/org/sunflow/system/Plugins.java +142 -0
  244. data/src/main/java/org/sunflow/system/RenderGlobalsPanel.java +209 -0
  245. data/src/main/java/org/sunflow/system/SearchPath.java +67 -0
  246. data/src/main/java/org/sunflow/system/Timer.java +53 -0
  247. data/src/main/java/org/sunflow/system/UI.java +112 -0
  248. data/src/main/java/org/sunflow/system/UserInterface.java +46 -0
  249. data/src/main/java/org/sunflow/system/ui/ConsoleInterface.java +48 -0
  250. data/src/main/java/org/sunflow/system/ui/SilentInterface.java +28 -0
  251. data/src/main/java/org/sunflow/util/FastHashMap.java +220 -0
  252. data/src/main/java/org/sunflow/util/FloatArray.java +77 -0
  253. data/src/main/java/org/sunflow/util/IntArray.java +77 -0
  254. data/src/test/java/a_maintest.java +129 -0
  255. metadata +300 -0
@@ -0,0 +1,28 @@
1
+ package org.sunflow.core.filter;
2
+
3
+ import org.sunflow.core.Filter;
4
+
5
+ public class MitchellFilter implements Filter {
6
+
7
+ @Override
8
+ public float getSize() {
9
+ return 4.0f;
10
+ }
11
+
12
+ @Override
13
+ public float get(float x, float y) {
14
+ return mitchell(x) * mitchell(y);
15
+ }
16
+
17
+ private float mitchell(float x) {
18
+ final float B = 1 / 3.0f;
19
+ final float C = 1 / 3.0f;
20
+ final float SIXTH = 1 / 6.0f;
21
+ x = Math.abs(x);
22
+ float x2 = x * x;
23
+ if (x > 1.0f) {
24
+ return ((-B - 6 * C) * x * x2 + (6 * B + 30 * C) * x2 + (-12 * B - 48 * C) * x + (8 * B + 24 * C)) * SIXTH;
25
+ }
26
+ return ((12 - 9 * B - 6 * C) * x * x2 + (-18 + 12 * B + 6 * C) * x2 + (6 - 2 * B)) * SIXTH;
27
+ }
28
+ }
@@ -0,0 +1,25 @@
1
+ package org.sunflow.core.filter;
2
+
3
+ import org.sunflow.core.Filter;
4
+
5
+ public class SincFilter implements Filter {
6
+
7
+ @Override
8
+ public float getSize() {
9
+ return 4.0f;
10
+ }
11
+
12
+ @Override
13
+ public float get(float x, float y) {
14
+ return sinc1d(x) * sinc1d(y);
15
+ }
16
+
17
+ private float sinc1d(float x) {
18
+ x = Math.abs(x);
19
+ if (x < 0.0001f) {
20
+ return 1.0f;
21
+ }
22
+ x *= Math.PI;
23
+ return (float) Math.sin(x) / x;
24
+ }
25
+ }
@@ -0,0 +1,16 @@
1
+ package org.sunflow.core.filter;
2
+
3
+ import org.sunflow.core.Filter;
4
+
5
+ public class TriangleFilter implements Filter {
6
+
7
+ @Override
8
+ public float getSize() {
9
+ return 2.0f;
10
+ }
11
+
12
+ @Override
13
+ public float get(float x, float y) {
14
+ return (1.0f - Math.abs(x)) * (1.0f - Math.abs(y));
15
+ }
16
+ }
@@ -0,0 +1,57 @@
1
+ package org.sunflow.core.gi;
2
+
3
+ import org.sunflow.core.GIEngine;
4
+ import org.sunflow.core.Options;
5
+ import org.sunflow.core.Ray;
6
+ import org.sunflow.core.Scene;
7
+ import org.sunflow.core.ShadingState;
8
+ import org.sunflow.image.Color;
9
+ import org.sunflow.math.OrthoNormalBasis;
10
+ import org.sunflow.math.Vector3;
11
+
12
+ public class AmbientOcclusionGIEngine implements GIEngine {
13
+
14
+ private Color bright;
15
+ private Color dark;
16
+ private int samples;
17
+ private float maxDist;
18
+
19
+ @Override
20
+ public Color getGlobalRadiance(ShadingState state) {
21
+ return Color.BLACK;
22
+ }
23
+
24
+ @Override
25
+ public boolean init(Options options, Scene scene) {
26
+ bright = options.getColor("gi.ambocc.bright", Color.WHITE);
27
+ dark = options.getColor("gi.ambocc.dark", Color.BLACK);
28
+ samples = options.getInt("gi.ambocc.samples", 32);
29
+ maxDist = options.getFloat("gi.ambocc.maxdist", 0);
30
+ maxDist = (maxDist <= 0) ? Float.POSITIVE_INFINITY : maxDist;
31
+ return true;
32
+ }
33
+
34
+ @Override
35
+ public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
36
+ OrthoNormalBasis onb = state.getBasis();
37
+ Vector3 w = new Vector3();
38
+ Color result = Color.black();
39
+ for (int i = 0; i < samples; i++) {
40
+ float xi = (float) state.getRandom(i, 0, samples);
41
+ float xj = (float) state.getRandom(i, 1, samples);
42
+ float phi = (float) (2 * Math.PI * xi);
43
+ float cosPhi = (float) Math.cos(phi);
44
+ float sinPhi = (float) Math.sin(phi);
45
+ float sinTheta = (float) Math.sqrt(xj);
46
+ float cosTheta = (float) Math.sqrt(1.0f - xj);
47
+ w.x = cosPhi * sinTheta;
48
+ w.y = sinPhi * sinTheta;
49
+ w.z = cosTheta;
50
+ onb.transform(w);
51
+ Ray r = new Ray(state.getPoint(), w);
52
+ r.setMax(maxDist);
53
+ result.add(Color.blend(bright, dark, state.traceShadow(r)));
54
+ }
55
+ return result.mul((float) Math.PI / samples);
56
+ }
57
+ }
@@ -0,0 +1,48 @@
1
+ package org.sunflow.core.gi;
2
+
3
+ import org.sunflow.core.GIEngine;
4
+ import org.sunflow.core.Options;
5
+ import org.sunflow.core.Scene;
6
+ import org.sunflow.core.ShadingState;
7
+ import org.sunflow.image.Color;
8
+ import org.sunflow.math.Vector3;
9
+
10
+ /**
11
+ * This is a quick way to get a bit of ambient lighting into your scene with
12
+ * hardly any overhead. It's based on the formula found here:
13
+ *
14
+ * @link http://www.cs.utah.edu/~shirley/papers/rtrt/node7.html#SECTION00031100000000000000
15
+ */
16
+ public class FakeGIEngine implements GIEngine {
17
+
18
+ private Vector3 up;
19
+ private Color sky;
20
+ private Color ground;
21
+
22
+ @Override
23
+ public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
24
+ float cosTheta = Vector3.dot(up, state.getNormal());
25
+ float sin2 = (1 - cosTheta * cosTheta);
26
+ float sine = sin2 > 0 ? (float) Math.sqrt(sin2) * 0.5f : 0;
27
+ if (cosTheta > 0) {
28
+ return Color.blend(sky, ground, sine);
29
+ } else {
30
+ return Color.blend(ground, sky, sine);
31
+ }
32
+ }
33
+
34
+ @Override
35
+ public Color getGlobalRadiance(ShadingState state) {
36
+ return Color.BLACK;
37
+ }
38
+
39
+ @Override
40
+ public boolean init(Options options, Scene scene) {
41
+ up = options.getVector("gi.fake.up", new Vector3(0, 1, 0)).normalize();
42
+ sky = options.getColor("gi.fake.sky", Color.WHITE).copy();
43
+ ground = options.getColor("gi.fake.ground", Color.BLACK).copy();
44
+ sky.mul((float) Math.PI);
45
+ ground.mul((float) Math.PI);
46
+ return true;
47
+ }
48
+ }
@@ -0,0 +1,194 @@
1
+ package org.sunflow.core.gi;
2
+
3
+ import java.util.ArrayList;
4
+
5
+ import org.sunflow.core.GIEngine;
6
+ import org.sunflow.core.Options;
7
+ import org.sunflow.core.PhotonStore;
8
+ import org.sunflow.core.Ray;
9
+ import org.sunflow.core.Scene;
10
+ import org.sunflow.core.ShadingState;
11
+ import org.sunflow.image.Color;
12
+ import org.sunflow.math.BoundingBox;
13
+ import org.sunflow.math.OrthoNormalBasis;
14
+ import org.sunflow.math.Point3;
15
+ import org.sunflow.math.Vector3;
16
+ import org.sunflow.system.UI;
17
+ import org.sunflow.system.UI.Module;
18
+
19
+ public class InstantGI implements GIEngine {
20
+
21
+ private int numPhotons;
22
+ private int numSets;
23
+ private float c;
24
+ private int numBias;
25
+ private PointLight[][] virtualLights;
26
+
27
+ @Override
28
+ public Color getGlobalRadiance(ShadingState state) {
29
+ Point3 p = state.getPoint();
30
+ Vector3 n = state.getNormal();
31
+ int set = (int) (state.getRandom(0, 1, 1) * numSets);
32
+ float maxAvgPow = 0;
33
+ float minDist = 1;
34
+ Color pow = null;
35
+ for (PointLight vpl : virtualLights[set]) {
36
+ maxAvgPow = Math.max(maxAvgPow, vpl.power.getAverage());
37
+ if (Vector3.dot(n, vpl.n) > 0.9f) {
38
+ float d = vpl.p.distanceToSquared(p);
39
+ if (d < minDist) {
40
+ pow = vpl.power;
41
+ minDist = d;
42
+ }
43
+ }
44
+ }
45
+ return pow == null ? Color.BLACK : pow.copy().mul(1.0f / maxAvgPow);
46
+ }
47
+
48
+ @Override
49
+ public boolean init(Options options, Scene scene) {
50
+ numPhotons = options.getInt("gi.igi.samples", 64);
51
+ numSets = options.getInt("gi.igi.sets", 1);
52
+ c = options.getFloat("gi.igi.c", 0.00003f);
53
+ numBias = options.getInt("gi.igi.bias_samples", 0);
54
+ virtualLights = null;
55
+ if (numSets < 1) {
56
+ numSets = 1;
57
+ }
58
+ UI.printInfo(Module.LIGHT, "Instant Global Illumination settings:");
59
+ UI.printInfo(Module.LIGHT, " * Samples: %d", numPhotons);
60
+ UI.printInfo(Module.LIGHT, " * Sets: %d", numSets);
61
+ UI.printInfo(Module.LIGHT, " * Bias bound: %f", c);
62
+ UI.printInfo(Module.LIGHT, " * Bias rays: %d", numBias);
63
+ virtualLights = new PointLight[numSets][];
64
+ if (numPhotons > 0) {
65
+ for (int i = 0, seed = 0; i < virtualLights.length; i++, seed += numPhotons) {
66
+ PointLightStore map = new PointLightStore();
67
+ if (!scene.calculatePhotons(map, "virtual", seed, options)) {
68
+ return false;
69
+ }
70
+ virtualLights[i] = map.virtualLights.toArray(new PointLight[map.virtualLights.size()]);
71
+ UI.printInfo(Module.LIGHT, "Stored %d virtual point lights for set %d of %d", virtualLights[i].length, i + 1, numSets);
72
+ }
73
+ } else {
74
+ // create an empty array
75
+ for (int i = 0; i < virtualLights.length; i++) {
76
+ virtualLights[i] = new PointLight[0];
77
+ }
78
+ }
79
+ return true;
80
+ }
81
+
82
+ @Override
83
+ public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
84
+ float b = (float) Math.PI * c / diffuseReflectance.getMax();
85
+ Color irr = Color.black();
86
+ Point3 p = state.getPoint();
87
+ Vector3 n = state.getNormal();
88
+ int set = (int) (state.getRandom(0, 1, 1) * numSets);
89
+ for (PointLight vpl : virtualLights[set]) {
90
+ Ray r = new Ray(p, vpl.p);
91
+ float dotNlD = -(r.dx * vpl.n.x + r.dy * vpl.n.y + r.dz * vpl.n.z);
92
+ float dotND = r.dx * n.x + r.dy * n.y + r.dz * n.z;
93
+ if (dotNlD > 0 && dotND > 0) {
94
+ float r2 = r.getMax() * r.getMax();
95
+ Color opacity = state.traceShadow(r);
96
+ Color power = Color.blend(vpl.power, Color.BLACK, opacity);
97
+ float g = (dotND * dotNlD) / r2;
98
+ irr.madd(0.25f * Math.min(g, b), power);
99
+ }
100
+ }
101
+ // bias compensation
102
+ int nb = (state.getDiffuseDepth() == 0 || numBias <= 0) ? numBias : 1;
103
+ if (nb <= 0) {
104
+ return irr;
105
+ }
106
+ OrthoNormalBasis onb = state.getBasis();
107
+ Vector3 w = new Vector3();
108
+ float scale = (float) Math.PI / nb;
109
+ for (int i = 0; i < nb; i++) {
110
+ float xi = (float) state.getRandom(i, 0, nb);
111
+ float xj = (float) state.getRandom(i, 1, nb);
112
+ float phi = (float) (xi * 2 * Math.PI);
113
+ float cosPhi = (float) Math.cos(phi);
114
+ float sinPhi = (float) Math.sin(phi);
115
+ float sinTheta = (float) Math.sqrt(xj);
116
+ float cosTheta = (float) Math.sqrt(1.0f - xj);
117
+ w.x = cosPhi * sinTheta;
118
+ w.y = sinPhi * sinTheta;
119
+ w.z = cosTheta;
120
+ onb.transform(w);
121
+ Ray r = new Ray(state.getPoint(), w);
122
+ r.setMax((float) Math.sqrt(cosTheta / b));
123
+ ShadingState temp = state.traceFinalGather(r, i);
124
+ if (temp != null) {
125
+ temp.getInstance().prepareShadingState(temp);
126
+ if (temp.getShader() != null) {
127
+ float dist = temp.getRay().getMax();
128
+ float r2 = dist * dist;
129
+ float cosThetaY = -Vector3.dot(w, temp.getNormal());
130
+ if (cosThetaY > 0) {
131
+ float g = (cosTheta * cosThetaY) / r2;
132
+ // was this path accounted for yet?
133
+ if (g > b) {
134
+ irr.madd(scale * (g - b) / g, temp.getShader().getRadiance(temp));
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+ return irr;
141
+ }
142
+
143
+ private static class PointLight {
144
+
145
+ Point3 p;
146
+ Vector3 n;
147
+ Color power;
148
+ }
149
+
150
+ private class PointLightStore implements PhotonStore {
151
+
152
+ ArrayList<PointLight> virtualLights = new ArrayList<>();
153
+
154
+ @Override
155
+ public int numEmit() {
156
+ return numPhotons;
157
+ }
158
+
159
+ @Override
160
+ public void prepare(Options options, BoundingBox sceneBounds) {
161
+ }
162
+
163
+ @Override
164
+ public void store(ShadingState state, Vector3 dir, Color power, Color diffuse) {
165
+ state.faceforward();
166
+ PointLight vpl = new PointLight();
167
+ vpl.p = state.getPoint();
168
+ vpl.n = state.getNormal();
169
+ vpl.power = power;
170
+ synchronized (this) {
171
+ virtualLights.add(vpl);
172
+ }
173
+ }
174
+
175
+ @Override
176
+ public void init() {
177
+ }
178
+
179
+ @Override
180
+ public boolean allowDiffuseBounced() {
181
+ return true;
182
+ }
183
+
184
+ @Override
185
+ public boolean allowReflectionBounced() {
186
+ return true;
187
+ }
188
+
189
+ @Override
190
+ public boolean allowRefractionBounced() {
191
+ return true;
192
+ }
193
+ }
194
+ }
@@ -0,0 +1,268 @@
1
+ package org.sunflow.core.gi;
2
+
3
+ import java.util.concurrent.locks.ReentrantReadWriteLock;
4
+
5
+ import org.sunflow.PluginRegistry;
6
+ import org.sunflow.core.GIEngine;
7
+ import org.sunflow.core.GlobalPhotonMapInterface;
8
+ import org.sunflow.core.Options;
9
+ import org.sunflow.core.Ray;
10
+ import org.sunflow.core.Scene;
11
+ import org.sunflow.core.ShadingState;
12
+ import org.sunflow.image.Color;
13
+ import org.sunflow.math.MathUtils;
14
+ import org.sunflow.math.OrthoNormalBasis;
15
+ import org.sunflow.math.Point3;
16
+ import org.sunflow.math.Vector3;
17
+ import org.sunflow.system.UI;
18
+ import org.sunflow.system.UI.Module;
19
+
20
+ public class IrradianceCacheGIEngine implements GIEngine {
21
+
22
+ private int samples;
23
+ private float tolerance;
24
+ private float invTolerance;
25
+ private float minSpacing;
26
+ private float maxSpacing;
27
+ private Node root;
28
+ private ReentrantReadWriteLock rwl;
29
+ private GlobalPhotonMapInterface globalPhotonMap;
30
+
31
+ @Override
32
+ public boolean init(Options options, Scene scene) {
33
+ // get settings
34
+ samples = options.getInt("gi.irr-cache.samples", 256);
35
+ tolerance = options.getFloat("gi.irr-cache.tolerance", 0.05f);
36
+ invTolerance = 1.0f / tolerance;
37
+ minSpacing = options.getFloat("gi.irr-cache.min_spacing", 0.05f);
38
+ maxSpacing = options.getFloat("gi.irr-cache.max_spacing", 5.00f);
39
+ root = null;
40
+ rwl = new ReentrantReadWriteLock();
41
+ globalPhotonMap = PluginRegistry.GLOBAL_PHOTON_MAP_PLUGINS.createObject(options.getString("gi.irr-cache.gmap", null));
42
+ // check settings
43
+ samples = Math.max(0, samples);
44
+ minSpacing = Math.max(0.001f, minSpacing);
45
+ maxSpacing = Math.max(0.001f, maxSpacing);
46
+ // display settings
47
+ UI.printInfo(Module.LIGHT, "Irradiance cache settings:");
48
+ UI.printInfo(Module.LIGHT, " * Samples: %d", samples);
49
+ if (tolerance <= 0) {
50
+ UI.printInfo(Module.LIGHT, " * Tolerance: off");
51
+ } else {
52
+ UI.printInfo(Module.LIGHT, " * Tolerance: %.3f", tolerance);
53
+ }
54
+ UI.printInfo(Module.LIGHT, " * Spacing: %.3f to %.3f", minSpacing, maxSpacing);
55
+ // prepare root node
56
+ Vector3 ext = scene.getBounds().getExtents();
57
+ root = new Node(scene.getBounds().getCenter(), 1.0001f * MathUtils.max(ext.x, ext.y, ext.z));
58
+ // init global photon map
59
+ return (globalPhotonMap != null) ? scene.calculatePhotons(globalPhotonMap, "global", 0, options) : true;
60
+ }
61
+
62
+ @Override
63
+ public Color getGlobalRadiance(ShadingState state) {
64
+ if (globalPhotonMap == null) {
65
+ if (state.getShader() != null) {
66
+ return state.getShader().getRadiance(state);
67
+ } else {
68
+ return Color.BLACK;
69
+ }
70
+ } else {
71
+ return globalPhotonMap.getRadiance(state.getPoint(), state.getNormal());
72
+ }
73
+ }
74
+
75
+ @Override
76
+ public Color getIrradiance(ShadingState state, Color diffuseReflectance) {
77
+ if (samples <= 0) {
78
+ return Color.BLACK;
79
+ }
80
+ if (state.getDiffuseDepth() > 0) {
81
+ // do simple path tracing for additional bounces (single ray)
82
+ float xi = (float) state.getRandom(0, 0, 1);
83
+ float xj = (float) state.getRandom(0, 1, 1);
84
+ float phi = (float) (xi * 2 * Math.PI);
85
+ float cosPhi = (float) Math.cos(phi);
86
+ float sinPhi = (float) Math.sin(phi);
87
+ float sinTheta = (float) Math.sqrt(xj);
88
+ float cosTheta = (float) Math.sqrt(1.0f - xj);
89
+ Vector3 w = new Vector3();
90
+ w.x = cosPhi * sinTheta;
91
+ w.y = sinPhi * sinTheta;
92
+ w.z = cosTheta;
93
+ OrthoNormalBasis onb = state.getBasis();
94
+ onb.transform(w);
95
+ Ray r = new Ray(state.getPoint(), w);
96
+ ShadingState temp = state.traceFinalGather(r, 0);
97
+ return temp != null ? getGlobalRadiance(temp).copy().mul((float) Math.PI) : Color.BLACK;
98
+ }
99
+ rwl.readLock().lock();
100
+ Color irr;
101
+ try {
102
+ irr = getIrradiance(state.getPoint(), state.getNormal());
103
+ } finally {
104
+ rwl.readLock().unlock();
105
+ }
106
+ if (irr == null) {
107
+ // compute new sample
108
+ irr = Color.black();
109
+ OrthoNormalBasis onb = state.getBasis();
110
+ float invR = 0;
111
+ float minR = Float.POSITIVE_INFINITY;
112
+ Vector3 w = new Vector3();
113
+ for (int i = 0; i < samples; i++) {
114
+ float xi = (float) state.getRandom(i, 0, samples);
115
+ float xj = (float) state.getRandom(i, 1, samples);
116
+ float phi = (float) (xi * 2 * Math.PI);
117
+ float cosPhi = (float) Math.cos(phi);
118
+ float sinPhi = (float) Math.sin(phi);
119
+ float sinTheta = (float) Math.sqrt(xj);
120
+ float cosTheta = (float) Math.sqrt(1.0f - xj);
121
+ w.x = cosPhi * sinTheta;
122
+ w.y = sinPhi * sinTheta;
123
+ w.z = cosTheta;
124
+ onb.transform(w);
125
+ Ray r = new Ray(state.getPoint(), w);
126
+ ShadingState temp = state.traceFinalGather(r, i);
127
+ if (temp != null) {
128
+ minR = Math.min(r.getMax(), minR);
129
+ invR += 1.0f / r.getMax();
130
+ temp.getInstance().prepareShadingState(temp);
131
+ irr.add(getGlobalRadiance(temp));
132
+ }
133
+ }
134
+ irr.mul((float) Math.PI / samples);
135
+ invR = samples / invR;
136
+ rwl.writeLock().lock();
137
+ try {
138
+ insert(state.getPoint(), state.getNormal(), invR, irr);
139
+ } finally {
140
+ rwl.writeLock().unlock();
141
+ }
142
+ }
143
+ return irr;
144
+ }
145
+
146
+ private void insert(Point3 p, Vector3 n, float r0, Color irr) {
147
+ if (tolerance <= 0) {
148
+ return;
149
+ }
150
+ Node node = root;
151
+ r0 = MathUtils.clamp(r0 * tolerance, minSpacing, maxSpacing) * invTolerance;
152
+ if (root.isInside(p)) {
153
+ while (node.sideLength >= (4.0 * r0 * tolerance)) {
154
+ int k = 0;
155
+ k |= (p.x > node.center.x) ? 1 : 0;
156
+ k |= (p.y > node.center.y) ? 2 : 0;
157
+ k |= (p.z > node.center.z) ? 4 : 0;
158
+ if (node.children[k] == null) {
159
+ Point3 c = new Point3(node.center);
160
+ c.x += ((k & 1) == 0) ? -node.quadSideLength : node.quadSideLength;
161
+ c.y += ((k & 2) == 0) ? -node.quadSideLength : node.quadSideLength;
162
+ c.z += ((k & 4) == 0) ? -node.quadSideLength : node.quadSideLength;
163
+ node.children[k] = new Node(c, node.halfSideLength);
164
+ }
165
+ node = node.children[k];
166
+ }
167
+ }
168
+ Sample s = new Sample(p, n, r0, irr);
169
+ s.next = node.first;
170
+ node.first = s;
171
+ }
172
+
173
+ private Color getIrradiance(Point3 p, Vector3 n) {
174
+ if (tolerance <= 0) {
175
+ return null;
176
+ }
177
+ Sample x = new Sample(p, n);
178
+ float w = root.find(x);
179
+ return (x.irr == null) ? null : x.irr.mul(1.0f / w);
180
+ }
181
+
182
+ private final class Node {
183
+
184
+ Node[] children;
185
+ Sample first;
186
+ Point3 center;
187
+ float sideLength;
188
+ float halfSideLength;
189
+ float quadSideLength;
190
+
191
+ Node(Point3 center, float sideLength) {
192
+ children = new Node[8];
193
+ for (int i = 0; i < 8; i++) {
194
+ children[i] = null;
195
+ }
196
+ this.center = new Point3(center);
197
+ this.sideLength = sideLength;
198
+ halfSideLength = 0.5f * sideLength;
199
+ quadSideLength = 0.5f * halfSideLength;
200
+ first = null;
201
+ }
202
+
203
+ final boolean isInside(Point3 p) {
204
+ return (Math.abs(p.x - center.x) < halfSideLength) && (Math.abs(p.y - center.y) < halfSideLength) && (Math.abs(p.z - center.z) < halfSideLength);
205
+ }
206
+
207
+ final float find(Sample x) {
208
+ float weight = 0;
209
+ for (Sample s = first; s != null; s = s.next) {
210
+ float c2 = 1.0f - (x.nix * s.nix + x.niy * s.niy + x.niz * s.niz);
211
+ float d2 = (x.pix - s.pix) * (x.pix - s.pix) + (x.piy - s.piy) * (x.piy - s.piy) + (x.piz - s.piz) * (x.piz - s.piz);
212
+ if (c2 > tolerance * tolerance || d2 > maxSpacing * maxSpacing) {
213
+ continue;
214
+ }
215
+ float invWi = (float) (Math.sqrt(d2) * s.invR0 + Math.sqrt(Math.max(c2, 0)));
216
+ if (invWi < tolerance || d2 < minSpacing * minSpacing) {
217
+ float wi = Math.min(1e10f, 1.0f / invWi);
218
+ if (x.irr != null) {
219
+ x.irr.madd(wi, s.irr);
220
+ } else {
221
+ x.irr = s.irr.copy().mul(wi);
222
+ }
223
+ weight += wi;
224
+ }
225
+ }
226
+ for (int i = 0; i < 8; i++) {
227
+ if ((children[i] != null) && (Math.abs(children[i].center.x - x.pix) <= halfSideLength) && (Math.abs(children[i].center.y - x.piy) <= halfSideLength) && (Math.abs(children[i].center.z - x.piz) <= halfSideLength)) {
228
+ weight += children[i].find(x);
229
+ }
230
+ }
231
+ return weight;
232
+ }
233
+ }
234
+
235
+ private static final class Sample {
236
+
237
+ float pix, piy, piz;
238
+ float nix, niy, niz;
239
+ float invR0;
240
+ Color irr;
241
+ Sample next;
242
+
243
+ Sample(Point3 p, Vector3 n) {
244
+ pix = p.x;
245
+ piy = p.y;
246
+ piz = p.z;
247
+ Vector3 ni = new Vector3(n).normalize();
248
+ nix = ni.x;
249
+ niy = ni.y;
250
+ niz = ni.z;
251
+ irr = null;
252
+ next = null;
253
+ }
254
+
255
+ Sample(Point3 p, Vector3 n, float r0, Color irr) {
256
+ pix = p.x;
257
+ piy = p.y;
258
+ piz = p.z;
259
+ Vector3 ni = new Vector3(n).normalize();
260
+ nix = ni.x;
261
+ niy = ni.y;
262
+ niz = ni.z;
263
+ invR0 = 1.0f / r0;
264
+ this.irr = irr;
265
+ next = null;
266
+ }
267
+ }
268
+ }