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,53 @@
1
+ package org.sunflow.core.shader;
2
+
3
+ import org.sunflow.SunflowAPI;
4
+ import org.sunflow.core.ParameterList;
5
+ import org.sunflow.core.Shader;
6
+ import org.sunflow.core.ShadingState;
7
+ import org.sunflow.image.Color;
8
+
9
+ public class AmbientOcclusionShader implements Shader {
10
+
11
+ private Color bright;
12
+ private Color dark;
13
+ private int samples;
14
+ private float maxDist;
15
+
16
+ public AmbientOcclusionShader() {
17
+ bright = Color.WHITE;
18
+ dark = Color.BLACK;
19
+ samples = 32;
20
+ maxDist = Float.POSITIVE_INFINITY;
21
+ }
22
+
23
+ public AmbientOcclusionShader(Color c, float d) {
24
+ this();
25
+ bright = c;
26
+ maxDist = d;
27
+ }
28
+
29
+ @Override
30
+ public boolean update(ParameterList pl, SunflowAPI api) {
31
+ bright = pl.getColor("bright", bright);
32
+ dark = pl.getColor("dark", dark);
33
+ samples = pl.getInt("samples", samples);
34
+ maxDist = pl.getFloat("maxdist", maxDist);
35
+ if (maxDist <= 0) {
36
+ maxDist = Float.POSITIVE_INFINITY;
37
+ }
38
+ return true;
39
+ }
40
+
41
+ public Color getBrightColor(ShadingState state) {
42
+ return bright;
43
+ }
44
+
45
+ @Override
46
+ public Color getRadiance(ShadingState state) {
47
+ return state.occlusion(samples, maxDist, getBrightColor(state), dark);
48
+ }
49
+
50
+ @Override
51
+ public void scatterPhoton(ShadingState state, Color power) {
52
+ }
53
+ }
@@ -0,0 +1,216 @@
1
+ package org.sunflow.core.shader;
2
+
3
+ import org.sunflow.SunflowAPI;
4
+ import org.sunflow.core.LightSample;
5
+ import org.sunflow.core.ParameterList;
6
+ import org.sunflow.core.Ray;
7
+ import org.sunflow.core.Shader;
8
+ import org.sunflow.core.ShadingState;
9
+ import org.sunflow.image.Color;
10
+ import org.sunflow.math.OrthoNormalBasis;
11
+ import org.sunflow.math.Vector3;
12
+
13
+ public class AnisotropicWardShader implements Shader {
14
+
15
+ private Color rhoD; // diffuse reflectance
16
+ private Color rhoS; // specular reflectance
17
+ private float alphaX;
18
+ private float alphaY;
19
+ private int numRays;
20
+
21
+ public AnisotropicWardShader() {
22
+ rhoD = Color.GRAY;
23
+ rhoS = Color.GRAY;
24
+ alphaX = 1;
25
+ alphaY = 1;
26
+ numRays = 4;
27
+ }
28
+
29
+ @Override
30
+ public boolean update(ParameterList pl, SunflowAPI api) {
31
+ rhoD = pl.getColor("diffuse", rhoD);
32
+ rhoS = pl.getColor("specular", rhoS);
33
+ alphaX = pl.getFloat("roughnessX", alphaX);
34
+ alphaY = pl.getFloat("roughnessY", alphaY);
35
+ numRays = pl.getInt("samples", numRays);
36
+ return true;
37
+ }
38
+
39
+ protected Color getDiffuse(ShadingState state) {
40
+ return rhoD;
41
+ }
42
+
43
+ private float brdf(Vector3 i, Vector3 o, OrthoNormalBasis basis) {
44
+ float fr = 4 * (float) Math.PI * alphaX * alphaY;
45
+ float p = basis.untransformZ(i) * basis.untransformZ(o);
46
+ if (p > 0) {
47
+ fr *= (float) Math.sqrt(p);
48
+ } else {
49
+ fr = 0;
50
+ }
51
+ Vector3 h = Vector3.add(i, o, new Vector3());
52
+ basis.untransform(h);
53
+ float hx = h.x / alphaX;
54
+ hx *= hx;
55
+ float hy = h.y / alphaY;
56
+ hy *= hy;
57
+ float hn = h.z * h.z;
58
+ if (fr > 0) {
59
+ fr = (float) Math.exp(-(hx + hy) / hn) / fr;
60
+ }
61
+ return fr;
62
+ }
63
+
64
+ public Color getRadiance(ShadingState state) {
65
+ // make sure we are on the right side of the material
66
+ state.faceforward();
67
+ OrthoNormalBasis onb = state.getBasis();
68
+ // direct lighting and caustics
69
+ state.initLightSamples();
70
+ state.initCausticSamples();
71
+ Color lr = Color.black();
72
+ // compute specular contribution
73
+ if (state.includeSpecular()) {
74
+ Vector3 in = state.getRay().getDirection().negate(new Vector3());
75
+ for (LightSample sample : state) {
76
+ float cosNL = sample.dot(state.getNormal());
77
+ float fr = brdf(in, sample.getShadowRay().getDirection(), onb);
78
+ lr.madd(cosNL * fr, sample.getSpecularRadiance());
79
+ }
80
+
81
+ // indirect lighting - specular
82
+ if (numRays > 0) {
83
+ int n = state.getDepth() == 0 ? numRays : 1;
84
+ for (int i = 0; i < n; i++) {
85
+ // specular indirect lighting
86
+ double r1 = state.getRandom(i, 0, n);
87
+ double r2 = state.getRandom(i, 1, n);
88
+
89
+ float alphaRatio = alphaY / alphaX;
90
+ float phi = 0;
91
+ if (r1 < 0.25) {
92
+ double val = 4 * r1;
93
+ phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
94
+ } else if (r1 < 0.5) {
95
+ double val = 1 - 4 * (0.5 - r1);
96
+ phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
97
+ phi = (float) Math.PI - phi;
98
+ } else if (r1 < 0.75) {
99
+ double val = 4 * (r1 - 0.5);
100
+ phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
101
+ phi += Math.PI;
102
+ } else {
103
+ double val = 1 - 4 * (1 - r1);
104
+ phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
105
+ phi = 2 * (float) Math.PI - phi;
106
+ }
107
+
108
+ float cosPhi = (float) Math.cos(phi);
109
+ float sinPhi = (float) Math.sin(phi);
110
+
111
+ float denom = (cosPhi * cosPhi) / (alphaX * alphaX) + (sinPhi * sinPhi) / (alphaY * alphaY);
112
+ float theta = (float) Math.atan(Math.sqrt(-Math.log(1 - r2) / denom));
113
+
114
+ float sinTheta = (float) Math.sin(theta);
115
+ float cosTheta = (float) Math.cos(theta);
116
+
117
+ Vector3 h = new Vector3();
118
+ h.x = sinTheta * cosPhi;
119
+ h.y = sinTheta * sinPhi;
120
+ h.z = cosTheta;
121
+ onb.transform(h);
122
+
123
+ Vector3 o = new Vector3();
124
+ float ih = Vector3.dot(h, in);
125
+ o.x = 2 * ih * h.x - in.x;
126
+ o.y = 2 * ih * h.y - in.y;
127
+ o.z = 2 * ih * h.z - in.z;
128
+
129
+ float no = onb.untransformZ(o);
130
+ float ni = onb.untransformZ(in);
131
+ float w = ih * cosTheta * cosTheta * cosTheta * (float) Math.sqrt(Math.abs(no / ni));
132
+
133
+ Ray r = new Ray(state.getPoint(), o);
134
+ lr.madd(w / n, state.traceGlossy(r, i));
135
+ }
136
+ }
137
+ lr.mul(rhoS);
138
+ }
139
+ // add diffuse contribution
140
+ lr.add(state.diffuse(getDiffuse(state)));
141
+ return lr;
142
+ }
143
+
144
+ @Override
145
+ public void scatterPhoton(ShadingState state, Color power) {
146
+ // make sure we are on the right side of the material
147
+ state.faceforward();
148
+ Color d = getDiffuse(state);
149
+ state.storePhoton(state.getRay().getDirection(), power, d);
150
+ float avgD = d.getAverage();
151
+ float avgS = rhoS.getAverage();
152
+ double rnd = state.getRandom(0, 0, 1);
153
+ if (rnd < avgD) {
154
+ // photon is scattered diffusely
155
+ power.mul(d).mul(1.0f / avgD);
156
+ OrthoNormalBasis onb = state.getBasis();
157
+ double u = 2 * Math.PI * rnd / avgD;
158
+ double v = state.getRandom(0, 1, 1);
159
+ float s = (float) Math.sqrt(v);
160
+ float s1 = (float) Math.sqrt(1.0f - v);
161
+ Vector3 w = new Vector3((float) Math.cos(u) * s, (float) Math.sin(u) * s, s1);
162
+ w = onb.transform(w, new Vector3());
163
+ state.traceDiffusePhoton(new Ray(state.getPoint(), w), power);
164
+ } else if (rnd < avgD + avgS) {
165
+ // photon is scattered specularly
166
+ power.mul(rhoS).mul(1 / avgS);
167
+ OrthoNormalBasis basis = state.getBasis();
168
+ Vector3 in = state.getRay().getDirection().negate(new Vector3());
169
+ double r1 = rnd / avgS;
170
+ double r2 = state.getRandom(0, 1, 1);
171
+
172
+ float alphaRatio = alphaY / alphaX;
173
+ float phi = 0;
174
+ if (r1 < 0.25) {
175
+ double val = 4 * r1;
176
+ phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
177
+ } else if (r1 < 0.5) {
178
+ double val = 1 - 4 * (0.5 - r1);
179
+ phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
180
+ phi = (float) Math.PI - phi;
181
+ } else if (r1 < 0.75) {
182
+ double val = 4 * (r1 - 0.5);
183
+ phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
184
+ phi += Math.PI;
185
+ } else {
186
+ double val = 1 - 4 * (1 - r1);
187
+ phi = (float) Math.atan(alphaRatio * Math.tan(Math.PI / 2 * val));
188
+ phi = 2 * (float) Math.PI - phi;
189
+ }
190
+
191
+ float cosPhi = (float) Math.cos(phi);
192
+ float sinPhi = (float) Math.sin(phi);
193
+
194
+ float denom = (cosPhi * cosPhi) / (alphaX * alphaX) + (sinPhi * sinPhi) / (alphaY * alphaY);
195
+ float theta = (float) Math.atan(Math.sqrt(-Math.log(1 - r2) / denom));
196
+
197
+ float sinTheta = (float) Math.sin(theta);
198
+ float cosTheta = (float) Math.cos(theta);
199
+
200
+ Vector3 h = new Vector3();
201
+ h.x = sinTheta * cosPhi;
202
+ h.y = sinTheta * sinPhi;
203
+ h.z = cosTheta;
204
+ basis.transform(h);
205
+
206
+ Vector3 o = new Vector3();
207
+ float ih = Vector3.dot(h, in);
208
+ o.x = 2 * ih * h.x - in.x;
209
+ o.y = 2 * ih * h.y - in.y;
210
+ o.z = 2 * ih * h.z - in.z;
211
+
212
+ Ray r = new Ray(state.getPoint(), o);
213
+ state.traceReflectionPhoton(r, power);
214
+ }
215
+ }
216
+ }
@@ -0,0 +1,31 @@
1
+ package org.sunflow.core.shader;
2
+
3
+ import org.sunflow.SunflowAPI;
4
+ import org.sunflow.core.ParameterList;
5
+ import org.sunflow.core.Shader;
6
+ import org.sunflow.core.ShadingState;
7
+ import org.sunflow.image.Color;
8
+
9
+ public class ConstantShader implements Shader {
10
+
11
+ private Color c;
12
+
13
+ public ConstantShader() {
14
+ c = Color.WHITE;
15
+ }
16
+
17
+ @Override
18
+ public boolean update(ParameterList pl, SunflowAPI api) {
19
+ c = pl.getColor("color", c);
20
+ return true;
21
+ }
22
+
23
+ @Override
24
+ public Color getRadiance(ShadingState state) {
25
+ return c;
26
+ }
27
+
28
+ @Override
29
+ public void scatterPhoton(ShadingState state, Color power) {
30
+ }
31
+ }
@@ -0,0 +1,65 @@
1
+ package org.sunflow.core.shader;
2
+
3
+ import org.sunflow.SunflowAPI;
4
+ import org.sunflow.core.ParameterList;
5
+ import org.sunflow.core.Ray;
6
+ import org.sunflow.core.Shader;
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 DiffuseShader implements Shader {
13
+
14
+ private Color diff;
15
+
16
+ public DiffuseShader() {
17
+ diff = Color.WHITE;
18
+ }
19
+
20
+ @Override
21
+ public boolean update(ParameterList pl, SunflowAPI api) {
22
+ diff = pl.getColor("diffuse", diff);
23
+ return true;
24
+ }
25
+
26
+ public Color getDiffuse(ShadingState state) {
27
+ return diff;
28
+ }
29
+
30
+ @Override
31
+ public Color getRadiance(ShadingState state) {
32
+ // make sure we are on the right side of the material
33
+ state.faceforward();
34
+ // setup lighting
35
+ state.initLightSamples();
36
+ state.initCausticSamples();
37
+ return state.diffuse(getDiffuse(state));
38
+ }
39
+
40
+ @Override
41
+ public void scatterPhoton(ShadingState state, Color power) {
42
+ Color diffuse;
43
+ // make sure we are on the right side of the material
44
+ if (Vector3.dot(state.getNormal(), state.getRay().getDirection()) > 0.0) {
45
+ state.getNormal().negate();
46
+ state.getGeoNormal().negate();
47
+ }
48
+ diffuse = getDiffuse(state);
49
+ state.storePhoton(state.getRay().getDirection(), power, diffuse);
50
+ float avg = diffuse.getAverage();
51
+ double rnd = state.getRandom(0, 0, 1);
52
+ if (rnd < avg) {
53
+ // photon is scattered
54
+ power.mul(diffuse).mul(1.0f / avg);
55
+ OrthoNormalBasis onb = state.getBasis();
56
+ double u = 2 * Math.PI * rnd / avg;
57
+ double v = state.getRandom(0, 1, 1);
58
+ float s = (float) Math.sqrt(v);
59
+ float s1 = (float) Math.sqrt(1.0 - v);
60
+ Vector3 w = new Vector3((float) Math.cos(u) * s, (float) Math.sin(u) * s, s1);
61
+ w = onb.transform(w, new Vector3());
62
+ state.traceDiffusePhoton(new Ray(state.getPoint(), w), power);
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,147 @@
1
+ package org.sunflow.core.shader;
2
+
3
+ import org.sunflow.SunflowAPI;
4
+ import org.sunflow.core.ParameterList;
5
+ import org.sunflow.core.Ray;
6
+ import org.sunflow.core.Shader;
7
+ import org.sunflow.core.ShadingState;
8
+ import org.sunflow.image.Color;
9
+ import org.sunflow.math.Vector3;
10
+
11
+ public class GlassShader implements Shader {
12
+
13
+ private float eta; // refraction index ratio
14
+ private float f0; // fresnel normal incidence
15
+ private Color color;
16
+ private float absorptionDistance;
17
+ private Color absorptionColor;
18
+
19
+ public GlassShader() {
20
+ eta = 1.3f;
21
+ color = Color.WHITE;
22
+ absorptionDistance = 0; // disabled by default
23
+ absorptionColor = Color.GRAY; // 50% absorbtion
24
+ }
25
+
26
+ @Override
27
+ public boolean update(ParameterList pl, SunflowAPI api) {
28
+ color = pl.getColor("color", color);
29
+ eta = pl.getFloat("eta", eta);
30
+ f0 = (1 - eta) / (1 + eta);
31
+ f0 = f0 * f0;
32
+ absorptionDistance = pl.getFloat("absorption.distance", absorptionDistance);
33
+ absorptionColor = pl.getColor("absorption.color", absorptionColor);
34
+ return true;
35
+ }
36
+
37
+ @Override
38
+ public Color getRadiance(ShadingState state) {
39
+ if (!state.includeSpecular()) {
40
+ return Color.BLACK;
41
+ }
42
+ Vector3 reflDir = new Vector3();
43
+ Vector3 refrDir = new Vector3();
44
+ state.faceforward();
45
+ float cos = state.getCosND();
46
+ boolean inside = state.isBehind();
47
+ float neta = inside ? eta : 1.0f / eta;
48
+
49
+ float dn = 2 * cos;
50
+ reflDir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
51
+ reflDir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
52
+ reflDir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
53
+
54
+ // refracted ray
55
+ float arg = 1 - (neta * neta * (1 - (cos * cos)));
56
+ boolean tir = arg < 0;
57
+ if (tir) {
58
+ refrDir.x = refrDir.y = refrDir.z = 0;
59
+ } else {
60
+ float nK = (neta * cos) - (float) Math.sqrt(arg);
61
+ refrDir.x = (neta * state.getRay().dx) + (nK * state.getNormal().x);
62
+ refrDir.y = (neta * state.getRay().dy) + (nK * state.getNormal().y);
63
+ refrDir.z = (neta * state.getRay().dz) + (nK * state.getNormal().z);
64
+ }
65
+
66
+ // compute Fresnel terms
67
+ float cosTheta1 = Vector3.dot(state.getNormal(), reflDir);
68
+ float cosTheta2 = -Vector3.dot(state.getNormal(), refrDir);
69
+
70
+ float pPara = (cosTheta1 - eta * cosTheta2) / (cosTheta1 + eta * cosTheta2);
71
+ float pPerp = (eta * cosTheta1 - cosTheta2) / (eta * cosTheta1 + cosTheta2);
72
+ float kr = 0.5f * (pPara * pPara + pPerp * pPerp);
73
+ float kt = 1 - kr;
74
+
75
+ Color absorbtion = null;
76
+ if (inside && absorptionDistance > 0) {
77
+ // this ray is inside the object and leaving it
78
+ // compute attenuation that occured along the ray
79
+ absorbtion = Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp();
80
+ if (absorbtion.isBlack()) {
81
+ return Color.BLACK; // nothing goes through
82
+ }
83
+ }
84
+ // refracted ray
85
+ Color ret = Color.black();
86
+ if (!tir) {
87
+ ret.madd(kt, state.traceRefraction(new Ray(state.getPoint(), refrDir), 0)).mul(color);
88
+ }
89
+ if (!inside || tir) {
90
+ ret.add(Color.mul(kr, state.traceReflection(new Ray(state.getPoint(), reflDir), 0)).mul(color));
91
+ }
92
+ return absorbtion != null ? ret.mul(absorbtion) : ret;
93
+ }
94
+
95
+ @Override
96
+ public void scatterPhoton(ShadingState state, Color power) {
97
+ Color refr = Color.mul(1 - f0, color);
98
+ Color refl = Color.mul(f0, color);
99
+ float avgR = refl.getAverage();
100
+ float avgT = refr.getAverage();
101
+ double rnd = state.getRandom(0, 0, 1);
102
+ if (rnd < avgR) {
103
+ state.faceforward();
104
+ // don't reflect internally
105
+ if (state.isBehind()) {
106
+ return;
107
+ }
108
+ // photon is reflected
109
+ float cos = state.getCosND();
110
+ power.mul(refl).mul(1.0f / avgR);
111
+ float dn = 2 * cos;
112
+ Vector3 dir = new Vector3();
113
+ dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
114
+ dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
115
+ dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
116
+ state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power);
117
+ } else if (rnd < avgR + avgT) {
118
+ state.faceforward();
119
+ // photon is refracted
120
+ float cos = state.getCosND();
121
+ float neta = state.isBehind() ? eta : 1.0f / eta;
122
+ power.mul(refr).mul(1.0f / avgT);
123
+ float wK = -neta;
124
+ float arg = 1 - (neta * neta * (1 - (cos * cos)));
125
+ Vector3 dir = new Vector3();
126
+ if (state.isBehind() && absorptionDistance > 0) {
127
+ // this ray is inside the object and leaving it
128
+ // compute attenuation that occured along the ray
129
+ power.mul(Color.mul(-state.getRay().getMax() / absorptionDistance, absorptionColor.copy().opposite()).exp());
130
+ }
131
+ if (arg < 0) {
132
+ // TIR
133
+ float dn = 2 * cos;
134
+ dir.x = (dn * state.getNormal().x) + state.getRay().getDirection().x;
135
+ dir.y = (dn * state.getNormal().y) + state.getRay().getDirection().y;
136
+ dir.z = (dn * state.getNormal().z) + state.getRay().getDirection().z;
137
+ state.traceReflectionPhoton(new Ray(state.getPoint(), dir), power);
138
+ } else {
139
+ float nK = (neta * cos) - (float) Math.sqrt(arg);
140
+ dir.x = (-wK * state.getRay().dx) + (nK * state.getNormal().x);
141
+ dir.y = (-wK * state.getRay().dy) + (nK * state.getNormal().y);
142
+ dir.z = (-wK * state.getRay().dz) + (nK * state.getNormal().z);
143
+ state.traceRefractionPhoton(new Ray(state.getPoint(), dir), power);
144
+ }
145
+ }
146
+ }
147
+ }