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.
- checksums.yaml +7 -0
- data/.gitignore +53 -0
- data/.mvn/extensions.xml +8 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +6 -0
- data/LICENSE +674 -0
- data/README.md +2 -0
- data/Rakefile +43 -0
- data/docs/.gitignore +6 -0
- data/docs/_config.yml +20 -0
- data/docs/_includes/footer.html +38 -0
- data/docs/_includes/head.html +15 -0
- data/docs/_includes/header.html +27 -0
- data/docs/_includes/icon-github.html +1 -0
- data/docs/_includes/icon-github.svg +1 -0
- data/docs/_includes/icon-twitter.html +1 -0
- data/docs/_includes/icon-twitter.svg +1 -0
- data/docs/_layouts/default.html +20 -0
- data/docs/_layouts/page.html +14 -0
- data/docs/_layouts/post.html +15 -0
- data/docs/_posts/2017-01-08-animated_ray_tracing.md +72 -0
- data/docs/_posts/2017-01-08-welcome.md +78 -0
- data/docs/_sass/_base.scss +206 -0
- data/docs/_sass/_layout.scss +242 -0
- data/docs/_sass/_syntax-highlighting.scss +71 -0
- data/docs/about.md +12 -0
- data/docs/assets/Animation.ogv +0 -0
- data/docs/assets/Animation.png +0 -0
- data/docs/assets/basic.png +0 -0
- data/docs/assets/basic_traced.png +0 -0
- data/docs/css/main.scss +38 -0
- data/docs/favicon.ico +0 -0
- data/docs/feed.xml +30 -0
- data/docs/index.html +38 -0
- data/joonsrenderer.gemspec +23 -0
- data/lib/joonsrenderer.rb +12 -0
- data/lib/joonsrenderer/version.rb +3 -0
- data/pom.rb +75 -0
- data/pom.xml +163 -0
- data/src/main/java/SunflowGUI.java +1354 -0
- data/src/main/java/joons/JRFiller.java +79 -0
- data/src/main/java/joons/JRImagePanel.java +141 -0
- data/src/main/java/joons/JRRecorder.java +183 -0
- data/src/main/java/joons/JRStatics.java +199 -0
- data/src/main/java/joons/JoonsRenderer.java +837 -0
- data/src/main/java/org/sunflow/AsciiFileSunflowAPI.java +98 -0
- data/src/main/java/org/sunflow/Benchmark.java +313 -0
- data/src/main/java/org/sunflow/BinaryFileSunflowAPI.java +228 -0
- data/src/main/java/org/sunflow/FileSunflowAPI.java +354 -0
- data/src/main/java/org/sunflow/PluginRegistry.java +322 -0
- data/src/main/java/org/sunflow/RealtimeBenchmark.java +125 -0
- data/src/main/java/org/sunflow/RenderObjectMap.java +344 -0
- data/src/main/java/org/sunflow/SunflowAPI.java +762 -0
- data/src/main/java/org/sunflow/SunflowAPIInterface.java +277 -0
- data/src/main/java/org/sunflow/core/AccelerationStructure.java +20 -0
- data/src/main/java/org/sunflow/core/AccelerationStructureFactory.java +36 -0
- data/src/main/java/org/sunflow/core/BucketOrder.java +21 -0
- data/src/main/java/org/sunflow/core/Camera.java +125 -0
- data/src/main/java/org/sunflow/core/CameraLens.java +29 -0
- data/src/main/java/org/sunflow/core/CausticPhotonMapInterface.java +15 -0
- data/src/main/java/org/sunflow/core/Display.java +78 -0
- data/src/main/java/org/sunflow/core/Filter.java +27 -0
- data/src/main/java/org/sunflow/core/GIEngine.java +42 -0
- data/src/main/java/org/sunflow/core/Geometry.java +157 -0
- data/src/main/java/org/sunflow/core/GlobalPhotonMapInterface.java +21 -0
- data/src/main/java/org/sunflow/core/ImageSampler.java +26 -0
- data/src/main/java/org/sunflow/core/Instance.java +224 -0
- data/src/main/java/org/sunflow/core/InstanceList.java +83 -0
- data/src/main/java/org/sunflow/core/IntersectionState.java +120 -0
- data/src/main/java/org/sunflow/core/LightSample.java +104 -0
- data/src/main/java/org/sunflow/core/LightServer.java +382 -0
- data/src/main/java/org/sunflow/core/LightSource.java +67 -0
- data/src/main/java/org/sunflow/core/Modifier.java +16 -0
- data/src/main/java/org/sunflow/core/Options.java +20 -0
- data/src/main/java/org/sunflow/core/ParameterList.java +758 -0
- data/src/main/java/org/sunflow/core/PhotonStore.java +62 -0
- data/src/main/java/org/sunflow/core/PrimitiveList.java +70 -0
- data/src/main/java/org/sunflow/core/Ray.java +219 -0
- data/src/main/java/org/sunflow/core/RenderObject.java +25 -0
- data/src/main/java/org/sunflow/core/Scene.java +377 -0
- data/src/main/java/org/sunflow/core/SceneParser.java +58 -0
- data/src/main/java/org/sunflow/core/Shader.java +30 -0
- data/src/main/java/org/sunflow/core/ShadingCache.java +84 -0
- data/src/main/java/org/sunflow/core/ShadingState.java +939 -0
- data/src/main/java/org/sunflow/core/Statistics.java +85 -0
- data/src/main/java/org/sunflow/core/Tesselatable.java +36 -0
- data/src/main/java/org/sunflow/core/Texture.java +128 -0
- data/src/main/java/org/sunflow/core/TextureCache.java +48 -0
- data/src/main/java/org/sunflow/core/accel/BoundingIntervalHierarchy.java +652 -0
- data/src/main/java/org/sunflow/core/accel/KDTree.java +833 -0
- data/src/main/java/org/sunflow/core/accel/NullAccelerator.java +30 -0
- data/src/main/java/org/sunflow/core/accel/UniformGrid.java +329 -0
- data/src/main/java/org/sunflow/core/bucket/BucketOrderFactory.java +26 -0
- data/src/main/java/org/sunflow/core/bucket/ColumnBucketOrder.java +21 -0
- data/src/main/java/org/sunflow/core/bucket/DiagonalBucketOrder.java +28 -0
- data/src/main/java/org/sunflow/core/bucket/HilbertBucketOrder.java +65 -0
- data/src/main/java/org/sunflow/core/bucket/InvertedBucketOrder.java +28 -0
- data/src/main/java/org/sunflow/core/bucket/RandomBucketOrder.java +49 -0
- data/src/main/java/org/sunflow/core/bucket/RowBucketOrder.java +21 -0
- data/src/main/java/org/sunflow/core/bucket/SpiralBucketOrder.java +43 -0
- data/src/main/java/org/sunflow/core/camera/FisheyeLens.java +25 -0
- data/src/main/java/org/sunflow/core/camera/PinholeLens.java +43 -0
- data/src/main/java/org/sunflow/core/camera/SphericalLens.java +22 -0
- data/src/main/java/org/sunflow/core/camera/ThinLens.java +107 -0
- data/src/main/java/org/sunflow/core/display/FastDisplay.java +119 -0
- data/src/main/java/org/sunflow/core/display/FileDisplay.java +83 -0
- data/src/main/java/org/sunflow/core/display/FrameDisplay.java +97 -0
- data/src/main/java/org/sunflow/core/display/ImgPipeDisplay.java +109 -0
- data/src/main/java/org/sunflow/core/filter/BlackmanHarrisFilter.java +28 -0
- data/src/main/java/org/sunflow/core/filter/BoxFilter.java +16 -0
- data/src/main/java/org/sunflow/core/filter/CatmullRomFilter.java +29 -0
- data/src/main/java/org/sunflow/core/filter/CubicBSpline.java +32 -0
- data/src/main/java/org/sunflow/core/filter/GaussianFilter.java +24 -0
- data/src/main/java/org/sunflow/core/filter/LanczosFilter.java +30 -0
- data/src/main/java/org/sunflow/core/filter/MitchellFilter.java +28 -0
- data/src/main/java/org/sunflow/core/filter/SincFilter.java +25 -0
- data/src/main/java/org/sunflow/core/filter/TriangleFilter.java +16 -0
- data/src/main/java/org/sunflow/core/gi/AmbientOcclusionGIEngine.java +57 -0
- data/src/main/java/org/sunflow/core/gi/FakeGIEngine.java +48 -0
- data/src/main/java/org/sunflow/core/gi/InstantGI.java +194 -0
- data/src/main/java/org/sunflow/core/gi/IrradianceCacheGIEngine.java +268 -0
- data/src/main/java/org/sunflow/core/gi/PathTracingGIEngine.java +65 -0
- data/src/main/java/org/sunflow/core/light/DirectionalSpotlight.java +103 -0
- data/src/main/java/org/sunflow/core/light/ImageBasedLight.java +303 -0
- data/src/main/java/org/sunflow/core/light/PointLight.java +72 -0
- data/src/main/java/org/sunflow/core/light/SphereLight.java +166 -0
- data/src/main/java/org/sunflow/core/light/SunSkyLight.java +362 -0
- data/src/main/java/org/sunflow/core/light/TriangleMeshLight.java +296 -0
- data/src/main/java/org/sunflow/core/modifiers/BumpMappingModifier.java +37 -0
- data/src/main/java/org/sunflow/core/modifiers/NormalMapModifier.java +34 -0
- data/src/main/java/org/sunflow/core/modifiers/PerlinModifier.java +80 -0
- data/src/main/java/org/sunflow/core/parser/Keyword.java +39 -0
- data/src/main/java/org/sunflow/core/parser/RA2Parser.java +107 -0
- data/src/main/java/org/sunflow/core/parser/RA3Parser.java +68 -0
- data/src/main/java/org/sunflow/core/parser/SCAbstractParser.java +299 -0
- data/src/main/java/org/sunflow/core/parser/SCAsciiParser.java +251 -0
- data/src/main/java/org/sunflow/core/parser/SCBinaryParser.java +156 -0
- data/src/main/java/org/sunflow/core/parser/SCParser.java +1403 -0
- data/src/main/java/org/sunflow/core/parser/ShaveRibParser.java +174 -0
- data/src/main/java/org/sunflow/core/parser/TriParser.java +79 -0
- data/src/main/java/org/sunflow/core/photonmap/CausticPhotonMap.java +429 -0
- data/src/main/java/org/sunflow/core/photonmap/GlobalPhotonMap.java +530 -0
- data/src/main/java/org/sunflow/core/photonmap/GridPhotonMap.java +308 -0
- data/src/main/java/org/sunflow/core/primitive/Background.java +55 -0
- data/src/main/java/org/sunflow/core/primitive/BanchoffSurface.java +100 -0
- data/src/main/java/org/sunflow/core/primitive/Box.java +210 -0
- data/src/main/java/org/sunflow/core/primitive/CornellBox.java +476 -0
- data/src/main/java/org/sunflow/core/primitive/CubeGrid.java +318 -0
- data/src/main/java/org/sunflow/core/primitive/Cylinder.java +104 -0
- data/src/main/java/org/sunflow/core/primitive/Hair.java +275 -0
- data/src/main/java/org/sunflow/core/primitive/JuliaFractal.java +266 -0
- data/src/main/java/org/sunflow/core/primitive/ParticleSurface.java +114 -0
- data/src/main/java/org/sunflow/core/primitive/Plane.java +163 -0
- data/src/main/java/org/sunflow/core/primitive/QuadMesh.java +413 -0
- data/src/main/java/org/sunflow/core/primitive/Sphere.java +101 -0
- data/src/main/java/org/sunflow/core/primitive/SphereFlake.java +234 -0
- data/src/main/java/org/sunflow/core/primitive/Torus.java +145 -0
- data/src/main/java/org/sunflow/core/primitive/TriangleMesh.java +849 -0
- data/src/main/java/org/sunflow/core/renderer/BucketRenderer.java +491 -0
- data/src/main/java/org/sunflow/core/renderer/MultipassRenderer.java +237 -0
- data/src/main/java/org/sunflow/core/renderer/ProgressiveRenderer.java +171 -0
- data/src/main/java/org/sunflow/core/renderer/SimpleRenderer.java +106 -0
- data/src/main/java/org/sunflow/core/shader/AmbientOcclusionShader.java +53 -0
- data/src/main/java/org/sunflow/core/shader/AnisotropicWardShader.java +216 -0
- data/src/main/java/org/sunflow/core/shader/ConstantShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/DiffuseShader.java +65 -0
- data/src/main/java/org/sunflow/core/shader/GlassShader.java +147 -0
- data/src/main/java/org/sunflow/core/shader/IDShader.java +27 -0
- data/src/main/java/org/sunflow/core/shader/MirrorShader.java +68 -0
- data/src/main/java/org/sunflow/core/shader/NormalShader.java +32 -0
- data/src/main/java/org/sunflow/core/shader/PhongShader.java +89 -0
- data/src/main/java/org/sunflow/core/shader/PrimIDShader.java +30 -0
- data/src/main/java/org/sunflow/core/shader/QuickGrayShader.java +63 -0
- data/src/main/java/org/sunflow/core/shader/ShinyDiffuseShader.java +98 -0
- data/src/main/java/org/sunflow/core/shader/SimpleShader.java +24 -0
- data/src/main/java/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedDiffuseShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedPhongShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedShinyDiffuseShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedWardShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/UVShader.java +27 -0
- data/src/main/java/org/sunflow/core/shader/UberShader.java +149 -0
- data/src/main/java/org/sunflow/core/shader/ViewCausticsShader.java +33 -0
- data/src/main/java/org/sunflow/core/shader/ViewGlobalPhotonsShader.java +25 -0
- data/src/main/java/org/sunflow/core/shader/ViewIrradianceShader.java +25 -0
- data/src/main/java/org/sunflow/core/shader/WireframeShader.java +83 -0
- data/src/main/java/org/sunflow/core/tesselatable/BezierMesh.java +254 -0
- data/src/main/java/org/sunflow/core/tesselatable/FileMesh.java +251 -0
- data/src/main/java/org/sunflow/core/tesselatable/Gumbo.java +1147 -0
- data/src/main/java/org/sunflow/core/tesselatable/Teapot.java +237 -0
- data/src/main/java/org/sunflow/image/Bitmap.java +15 -0
- data/src/main/java/org/sunflow/image/BitmapReader.java +39 -0
- data/src/main/java/org/sunflow/image/BitmapWriter.java +79 -0
- data/src/main/java/org/sunflow/image/BlackbodySpectrum.java +16 -0
- data/src/main/java/org/sunflow/image/ChromaticitySpectrum.java +55 -0
- data/src/main/java/org/sunflow/image/Color.java +374 -0
- data/src/main/java/org/sunflow/image/ColorEncoder.java +94 -0
- data/src/main/java/org/sunflow/image/ColorFactory.java +122 -0
- data/src/main/java/org/sunflow/image/ConstantSpectralCurve.java +21 -0
- data/src/main/java/org/sunflow/image/IrregularSpectralCurve.java +57 -0
- data/src/main/java/org/sunflow/image/RGBSpace.java +207 -0
- data/src/main/java/org/sunflow/image/RegularSpectralCurve.java +30 -0
- data/src/main/java/org/sunflow/image/SpectralCurve.java +118 -0
- data/src/main/java/org/sunflow/image/XYZColor.java +50 -0
- data/src/main/java/org/sunflow/image/formats/BitmapBlack.java +27 -0
- data/src/main/java/org/sunflow/image/formats/BitmapG8.java +36 -0
- data/src/main/java/org/sunflow/image/formats/BitmapGA8.java +30 -0
- data/src/main/java/org/sunflow/image/formats/BitmapRGB8.java +40 -0
- data/src/main/java/org/sunflow/image/formats/BitmapRGBA8.java +40 -0
- data/src/main/java/org/sunflow/image/formats/BitmapRGBE.java +60 -0
- data/src/main/java/org/sunflow/image/formats/BitmapXYZ.java +38 -0
- data/src/main/java/org/sunflow/image/formats/GenericBitmap.java +73 -0
- data/src/main/java/org/sunflow/image/readers/BMPBitmapReader.java +39 -0
- data/src/main/java/org/sunflow/image/readers/HDRBitmapReader.java +155 -0
- data/src/main/java/org/sunflow/image/readers/IGIBitmapReader.java +104 -0
- data/src/main/java/org/sunflow/image/readers/JPGBitmapReader.java +39 -0
- data/src/main/java/org/sunflow/image/readers/PNGBitmapReader.java +40 -0
- data/src/main/java/org/sunflow/image/readers/TGABitmapReader.java +141 -0
- data/src/main/java/org/sunflow/image/writers/EXRBitmapWriter.java +395 -0
- data/src/main/java/org/sunflow/image/writers/HDRBitmapWriter.java +54 -0
- data/src/main/java/org/sunflow/image/writers/IGIBitmapWriter.java +75 -0
- data/src/main/java/org/sunflow/image/writers/PNGBitmapWriter.java +39 -0
- data/src/main/java/org/sunflow/image/writers/TGABitmapWriter.java +63 -0
- data/src/main/java/org/sunflow/math/BoundingBox.java +340 -0
- data/src/main/java/org/sunflow/math/MathUtils.java +159 -0
- data/src/main/java/org/sunflow/math/Matrix4.java +573 -0
- data/src/main/java/org/sunflow/math/MovingMatrix4.java +119 -0
- data/src/main/java/org/sunflow/math/OrthoNormalBasis.java +110 -0
- data/src/main/java/org/sunflow/math/PerlinScalar.java +331 -0
- data/src/main/java/org/sunflow/math/PerlinVector.java +132 -0
- data/src/main/java/org/sunflow/math/Point2.java +36 -0
- data/src/main/java/org/sunflow/math/Point3.java +133 -0
- data/src/main/java/org/sunflow/math/QMC.java +209 -0
- data/src/main/java/org/sunflow/math/Solvers.java +142 -0
- data/src/main/java/org/sunflow/math/Vector3.java +197 -0
- data/src/main/java/org/sunflow/system/BenchmarkFramework.java +73 -0
- data/src/main/java/org/sunflow/system/BenchmarkTest.java +17 -0
- data/src/main/java/org/sunflow/system/ByteUtil.java +119 -0
- data/src/main/java/org/sunflow/system/FileUtils.java +27 -0
- data/src/main/java/org/sunflow/system/ImagePanel.java +282 -0
- data/src/main/java/org/sunflow/system/Memory.java +18 -0
- data/src/main/java/org/sunflow/system/Parser.java +162 -0
- data/src/main/java/org/sunflow/system/Plugins.java +142 -0
- data/src/main/java/org/sunflow/system/RenderGlobalsPanel.java +209 -0
- data/src/main/java/org/sunflow/system/SearchPath.java +67 -0
- data/src/main/java/org/sunflow/system/Timer.java +53 -0
- data/src/main/java/org/sunflow/system/UI.java +112 -0
- data/src/main/java/org/sunflow/system/UserInterface.java +46 -0
- data/src/main/java/org/sunflow/system/ui/ConsoleInterface.java +48 -0
- data/src/main/java/org/sunflow/system/ui/SilentInterface.java +28 -0
- data/src/main/java/org/sunflow/util/FastHashMap.java +220 -0
- data/src/main/java/org/sunflow/util/FloatArray.java +77 -0
- data/src/main/java/org/sunflow/util/IntArray.java +77 -0
- data/src/test/java/a_maintest.java +129 -0
- metadata +300 -0
|
@@ -0,0 +1,837 @@
|
|
|
1
|
+
package joons;
|
|
2
|
+
|
|
3
|
+
import java.util.List;
|
|
4
|
+
|
|
5
|
+
import org.sunflow.SunflowAPI;
|
|
6
|
+
import org.sunflow.math.Matrix4;
|
|
7
|
+
import org.sunflow.math.Point3;
|
|
8
|
+
import org.sunflow.math.Vector3;
|
|
9
|
+
|
|
10
|
+
import processing.core.*;
|
|
11
|
+
import processing.opengl.PGraphicsOpenGL;
|
|
12
|
+
import static joons.JRStatics.*;
|
|
13
|
+
|
|
14
|
+
public class JoonsRenderer {
|
|
15
|
+
|
|
16
|
+
public JRRecorder recorder;
|
|
17
|
+
private SunflowAPI api;
|
|
18
|
+
private boolean renderIsAGo;
|
|
19
|
+
private boolean rendering = false;
|
|
20
|
+
private boolean rendered = false;
|
|
21
|
+
private final PApplet app;
|
|
22
|
+
|
|
23
|
+
public JoonsRenderer(PApplet parent) {
|
|
24
|
+
PGraphicsOpenGL pg = (PGraphicsOpenGL) parent.g;
|
|
25
|
+
FOV = pg.cameraFOV; //default value from Processing
|
|
26
|
+
ASPECT = pg.cameraAspect; //default value from Processing
|
|
27
|
+
recorder = new JRRecorder(parent);
|
|
28
|
+
this.app = parent;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public boolean isRendering() {
|
|
32
|
+
return rendering;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public boolean isRendered() {
|
|
36
|
+
return rendered;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//rendering command interface
|
|
40
|
+
public void beginRecord() {
|
|
41
|
+
if (rendering) {
|
|
42
|
+
app.beginRecord(recorder);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public void endRecord() {
|
|
47
|
+
if (rendering) {
|
|
48
|
+
app.endRecord();
|
|
49
|
+
rendering = false;
|
|
50
|
+
rendered = renderSunflow();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public void render() {
|
|
55
|
+
rendering = true;
|
|
56
|
+
rendered = false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//image settings interface
|
|
60
|
+
public void setSizeMultiplier(double multiplier) {
|
|
61
|
+
SIZE_MULTIPLIER = multiplier;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public void setSampler(String sampler) {
|
|
65
|
+
SAMPLER = sampler;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public void setAA(int aaMin, int aaMax) {
|
|
69
|
+
AA_MIN = aaMin;
|
|
70
|
+
AA_MAX = aaMax;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public void setAA(int aaMin, int aaMax, int aaSamples) {
|
|
74
|
+
setAA(aaMin, aaMax);
|
|
75
|
+
AA_SAMPLES = aaSamples;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public void setCaustics(int emitInMillions) {
|
|
79
|
+
setCaustics(emitInMillions, 50 + 10 * emitInMillions - 5, 0.5f); //rule of thumb
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public void setCaustics(int emitInMillions, int gather) {
|
|
83
|
+
setCaustics(emitInMillions, gather, 0.5f); //rule of thumb
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public void setCaustics(int emitInMillions, int gather, float radius) {
|
|
87
|
+
CAUSTICS_EMIT = emitInMillions * 1000000; // just to make life easier.
|
|
88
|
+
CAUSTICS_GATHER = gather;
|
|
89
|
+
CAUSTICS_RADIUS = radius;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public void setTraceDepths(int diff, int refl, int refr) {
|
|
93
|
+
TRACE_DEPTH_DIFF = diff;
|
|
94
|
+
TRACE_DEPTH_REFL = refl;
|
|
95
|
+
TRACE_DEPTH_REFR = refr;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public void setDOF(float focalDistance, float lensRadius) {
|
|
99
|
+
FOCAL_DISTANCE = focalDistance;
|
|
100
|
+
LENS_RADIUS = lensRadius; //larger the R, say 5, greater the DOF effect.
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
//background interface
|
|
104
|
+
public void background(float gray) {
|
|
105
|
+
BG_R = gray / 255f;
|
|
106
|
+
BG_G = gray / 255f;
|
|
107
|
+
BG_B = gray / 255f;
|
|
108
|
+
if (!rendering) {
|
|
109
|
+
app.background(gray);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public void background(float r, float g, float b) {
|
|
114
|
+
BG_R = r / 255f;
|
|
115
|
+
BG_G = g / 255f;
|
|
116
|
+
BG_B = b / 255f;
|
|
117
|
+
if (!rendering) {
|
|
118
|
+
app.background(r, g, b);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public void background(String type) {
|
|
123
|
+
background(type, null);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public void background(String type, float... params) {
|
|
127
|
+
|
|
128
|
+
//gi, instant
|
|
129
|
+
if (type == null ? GI_INSTANT == null : type.equals(GI_INSTANT)) {
|
|
130
|
+
if (params == null) {
|
|
131
|
+
GI_IS_CALLED = true;
|
|
132
|
+
} else if (params.length == 4) {
|
|
133
|
+
GI_IS_CALLED = true;
|
|
134
|
+
GI_INSTANT_SAMPLES = (int) params[0];
|
|
135
|
+
GI_INSTANT_SETS = (int) params[1];
|
|
136
|
+
GI_INSTANT_C = params[2];
|
|
137
|
+
GI_INSTANT_BIAS_SAMPLES = (int) params[3];
|
|
138
|
+
} else {
|
|
139
|
+
if (rendering) {
|
|
140
|
+
PApplet.println(GI_INSTANT_ERROR);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
//gi, ambient occlusion
|
|
146
|
+
if (type == null ? GI_AMB_OCC == null : type.equals(GI_AMB_OCC)) {
|
|
147
|
+
if (params == null) {
|
|
148
|
+
GI_AMB_OCC_IS_CALLED = true;
|
|
149
|
+
} else if (params.length == 8) {
|
|
150
|
+
GI_AMB_OCC_BRIGHT_R = params[0] / 255f;
|
|
151
|
+
GI_AMB_OCC_BRIGHT_G = params[1] / 255f;
|
|
152
|
+
GI_AMB_OCC_BRIGHT_B = params[2] / 255f;
|
|
153
|
+
GI_AMB_OCC_DARK_R = params[3] / 255f;
|
|
154
|
+
GI_AMB_OCC_DARK_G = params[4] / 255f;
|
|
155
|
+
GI_AMB_OCC_DARK_B = params[5] / 255f;
|
|
156
|
+
GI_AMB_OCC_MAX_DIST = params[6];
|
|
157
|
+
GI_AMB_OCC_SAMPLES = (int) params[7];
|
|
158
|
+
} else {
|
|
159
|
+
if (rendering) {
|
|
160
|
+
PApplet.println(GI_AMB_OCC_ERROR);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
//cornell box
|
|
166
|
+
if (type == null ? CORNELL_BOX == null : type.equals(CORNELL_BOX)) {
|
|
167
|
+
if (params != null) {
|
|
168
|
+
switch (params.length) {
|
|
169
|
+
case 3:
|
|
170
|
+
cornellBox(params[0], params[1], params[2]);
|
|
171
|
+
break;
|
|
172
|
+
case 7:
|
|
173
|
+
cornellBox(params[0], params[1], params[2], params[3], params[4], params[5], (int) params[6]);
|
|
174
|
+
break;
|
|
175
|
+
case 22:
|
|
176
|
+
cornellBox(params[0], params[1], params[2], params[3], params[4], params[5], (int) params[6],
|
|
177
|
+
params[7], params[8], params[9], params[10], params[11], params[12],
|
|
178
|
+
params[13], params[14], params[15], params[16], params[17], params[18],
|
|
179
|
+
params[19], params[20], params[21]);
|
|
180
|
+
break;
|
|
181
|
+
default:
|
|
182
|
+
if (rendering) {
|
|
183
|
+
PApplet.println(CORNELL_BOX_ERROR);
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
if (rendering) {
|
|
189
|
+
PApplet.println(CORNELL_BOX_ERROR);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
//shade interface
|
|
196
|
+
public void fill(String type) {
|
|
197
|
+
if (type == null ? LIGHT == null : type.equals(LIGHT)) {
|
|
198
|
+
fill(type, DEF_RADIANCE, DEF_RADIANCE, DEF_RADIANCE);
|
|
199
|
+
} else {
|
|
200
|
+
fill(type, DEF_RGB, DEF_RGB, DEF_RGB);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public void fill(String type, float... params) {
|
|
205
|
+
switch(type){
|
|
206
|
+
case(CONSTANT):
|
|
207
|
+
case(DIFFUSE):
|
|
208
|
+
case(SHINY):
|
|
209
|
+
case(PHONG):
|
|
210
|
+
case(AMBIENT_OCCLUSION):
|
|
211
|
+
case(LIGHT):
|
|
212
|
+
case(MIRROR):
|
|
213
|
+
fillers.add(new JRFiller(type, params));
|
|
214
|
+
break;
|
|
215
|
+
default:
|
|
216
|
+
if (rendering) {
|
|
217
|
+
PApplet.println(FILLER_UNKOWN_ERROR);
|
|
218
|
+
}
|
|
219
|
+
FILLERS_ARE_VALID = false;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
//First three parameters are always used as RGB.
|
|
223
|
+
//This can be used to give an idea about what the render may look like before render.
|
|
224
|
+
//When showing light shaded objects in processing,
|
|
225
|
+
//the r, g, b is normalized so that the highest value of them
|
|
226
|
+
//is set to 255, and the rest is normalized in proportion.
|
|
227
|
+
if (params.length >= 3) {
|
|
228
|
+
if (null == type) {
|
|
229
|
+
app.fill(params[0], params[1], params[2]);
|
|
230
|
+
} else {
|
|
231
|
+
switch (type) {
|
|
232
|
+
case LIGHT:
|
|
233
|
+
float r,
|
|
234
|
+
g,
|
|
235
|
+
b,
|
|
236
|
+
max;
|
|
237
|
+
r = params[0];
|
|
238
|
+
g = params[1];
|
|
239
|
+
b = params[2];
|
|
240
|
+
max = PApplet.max(new float[]{r, g, b});
|
|
241
|
+
app.fill(255 * r / max, 255 * g / max, 255 * b / max);
|
|
242
|
+
break;
|
|
243
|
+
case GLASS:
|
|
244
|
+
app.fill(params[0], params[1], params[2], DEF_GLASS_ALPHA);
|
|
245
|
+
break;
|
|
246
|
+
default:
|
|
247
|
+
app.fill(params[0], params[1], params[2]);
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Adds a Sunsky light to the scene with default sun, up, and east
|
|
256
|
+
* directions. The Sunsky light will make no attempt at creating a simulated
|
|
257
|
+
* light in your Processing render.
|
|
258
|
+
*
|
|
259
|
+
* @param extendSkyBeyondHorizon Choose whether to have the sky extend
|
|
260
|
+
* beyond the horizon. If false, a horizon plane will exist at the scene
|
|
261
|
+
* origin.
|
|
262
|
+
*/
|
|
263
|
+
public void sunsky(boolean extendSkyBeyondHorizon) {
|
|
264
|
+
sunsky(
|
|
265
|
+
extendSkyBeyondHorizon,
|
|
266
|
+
DEF_SUNSKY_DIR[0], DEF_SUNSKY_DIR[1], DEF_SUNSKY_DIR[2],
|
|
267
|
+
DEF_SUNSKY_SAMPLES
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Adds a Sunsky light to the scene with default up and east directions. The
|
|
273
|
+
* Sunsky light will make no attempt at creating a simulated light in your
|
|
274
|
+
* Processing render.
|
|
275
|
+
*
|
|
276
|
+
* @param extendSkyBeyondHorizon Choose whether to have the sky extend
|
|
277
|
+
* beyond the horizon. If false, a horizon plane will exist at the scene
|
|
278
|
+
* origin.
|
|
279
|
+
* @param dirX X component of the directional position of the sun in the sky
|
|
280
|
+
* (0.f .. 1.0f)
|
|
281
|
+
* @param dirY X component of the directional position of the sun in the sky
|
|
282
|
+
* (0.f .. 1.0f)
|
|
283
|
+
* @param dirZ X component of the directional position of the sun in the sky
|
|
284
|
+
* (0.f .. 1.0f)
|
|
285
|
+
* @param samples Number of samples to use when rendering the sunsky light
|
|
286
|
+
*/
|
|
287
|
+
public void sunsky(boolean extendSkyBeyondHorizon, float dirX, float dirY, float dirZ, int samples) {
|
|
288
|
+
sunsky(
|
|
289
|
+
extendSkyBeyondHorizon,
|
|
290
|
+
dirX, dirY, dirZ,
|
|
291
|
+
samples,
|
|
292
|
+
DEF_SUNSKY_UP[0], DEF_SUNSKY_UP[1], DEF_SUNSKY_UP[2],
|
|
293
|
+
DEF_SUNSKY_EAST[0], DEF_SUNSKY_EAST[1], DEF_SUNSKY_EAST[2]
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* The Sunsky light will make no attempt at creating a simulated light in
|
|
299
|
+
* your processing render.
|
|
300
|
+
*
|
|
301
|
+
* @param extendSkyBeyondHorizon Choose whether to have the sky extend
|
|
302
|
+
* beyond the horizon. If false, a horizon plane will exist at the scene
|
|
303
|
+
* origin.
|
|
304
|
+
* @param dirX X component of the directional position of the sun in the sky
|
|
305
|
+
* (0.f .. 1.0f)
|
|
306
|
+
* @param dirY X component of the directional position of the sun in the sky
|
|
307
|
+
* (0.f .. 1.0f)
|
|
308
|
+
* @param dirZ X component of the directional position of the sun in the sky
|
|
309
|
+
* (0.f .. 1.0f)
|
|
310
|
+
* @param samples Number of samples to use when rendering the sunsky light
|
|
311
|
+
* @param upX X component of the up direction within the scene (0.f .. 1.0f)
|
|
312
|
+
* @param upY Y component of the up direction within the scene (0.f .. 1.0f)
|
|
313
|
+
* @param upZ Z component of the up direction within the scene (0.f .. 1.0f)
|
|
314
|
+
* @param eastX X component of the east direction within the scene (0.f ..
|
|
315
|
+
* 1.0f)
|
|
316
|
+
* @param eastY Y component of the east direction within the scene (0.f ..
|
|
317
|
+
* 1.0f)
|
|
318
|
+
* @param eastZ Z component of the east direction within the scene (0.f ..
|
|
319
|
+
* 1.0f)
|
|
320
|
+
*/
|
|
321
|
+
public void sunsky(boolean extendSkyBeyondHorizon, float dirX, float dirY, float dirZ, int samples, float upX, float upY, float upZ, float eastX, float eastY, float eastZ) {
|
|
322
|
+
float[] params = new float[]{extendSkyBeyondHorizon ? 1 : 0, dirX, dirY, dirZ, samples, upX, upY, upZ, eastX, eastY, eastZ};
|
|
323
|
+
JRFiller filler = new JRFiller(SUNSKY, params);
|
|
324
|
+
fillers.add(filler);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
//cornell box implementation
|
|
328
|
+
private void cornellBox(float width, float height, float depth) {
|
|
329
|
+
cornellBox(width, height, depth, DEF_CORB_RADIANCE, DEF_CORB_RADIANCE, DEF_CORB_RADIANCE, DEF_SAMPLES);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
private void cornellBox(float width, float height, float depth,
|
|
333
|
+
float radianceR, float radianceG, float radianceB, int samples) {
|
|
334
|
+
cornellBox(width, height, depth,
|
|
335
|
+
radianceR, radianceG, radianceB, samples,
|
|
336
|
+
DEF_CORB_COLOR_1, DEF_CORB_COLOR_2, DEF_CORB_COLOR_2, DEF_CORB_COLOR_2, DEF_CORB_COLOR_2, DEF_CORB_COLOR_1,
|
|
337
|
+
DEF_CORB_COLOR_1, DEF_CORB_COLOR_1, DEF_CORB_COLOR_1, DEF_CORB_COLOR_1, DEF_CORB_COLOR_1, DEF_CORB_COLOR_1,
|
|
338
|
+
DEF_CORB_COLOR_1, DEF_CORB_COLOR_1, DEF_CORB_COLOR_1); //default vaules
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
private void cornellBox(float width, float height, float depth,
|
|
342
|
+
float radianceR, float radianceG, float radianceB, int samples,
|
|
343
|
+
float leftR, float leftG, float leftB, float rightR, float rightG, float rightB,
|
|
344
|
+
float backR, float backG, float backB, float topR, float topG, float topB,
|
|
345
|
+
float bottomR, float bottomG, float bottomB) {
|
|
346
|
+
float w = width / 2;
|
|
347
|
+
float h = height / 2;
|
|
348
|
+
float d = depth / 2;
|
|
349
|
+
|
|
350
|
+
//back up current filler
|
|
351
|
+
String tempFillerType = getCurrentFiller().getType();
|
|
352
|
+
float[] tempParams = getCurrentFiller().p;
|
|
353
|
+
|
|
354
|
+
//-x side
|
|
355
|
+
this.fill("diffuse", leftR, leftG, leftB);
|
|
356
|
+
app.beginShape(PApplet.QUADS);
|
|
357
|
+
app.vertex(-w, h, -d);
|
|
358
|
+
app.vertex(-w, h, d);
|
|
359
|
+
app.vertex(-w, -h, d);
|
|
360
|
+
app.vertex(-w, -h, -d);
|
|
361
|
+
app.endShape();
|
|
362
|
+
|
|
363
|
+
//+x side
|
|
364
|
+
this.fill("diffuse", rightR, rightG, rightB);
|
|
365
|
+
app.beginShape(PApplet.QUADS);
|
|
366
|
+
app.vertex(w, h, -d);
|
|
367
|
+
app.vertex(w, h, d);
|
|
368
|
+
app.vertex(w, -h, d);
|
|
369
|
+
app.vertex(w, -h, -d);
|
|
370
|
+
app.endShape();
|
|
371
|
+
|
|
372
|
+
//back
|
|
373
|
+
this.fill("diffuse", backR, backG, backB);
|
|
374
|
+
app.beginShape(PApplet.QUADS);
|
|
375
|
+
app.vertex(w, h, -d);
|
|
376
|
+
app.vertex(w, -h, -d);
|
|
377
|
+
app.vertex(-w, -h, -d);
|
|
378
|
+
app.vertex(-w, h, -d);
|
|
379
|
+
app.endShape();
|
|
380
|
+
|
|
381
|
+
//bottom
|
|
382
|
+
this.fill("diffuse", bottomR, bottomG, bottomB);
|
|
383
|
+
app.beginShape(PApplet.QUADS);
|
|
384
|
+
app.vertex(w, h, -d);
|
|
385
|
+
app.vertex(w, h, d);
|
|
386
|
+
app.vertex(-w, h, d);
|
|
387
|
+
app.vertex(-w, h, -d);
|
|
388
|
+
app.endShape();
|
|
389
|
+
|
|
390
|
+
//ceiling rim
|
|
391
|
+
this.fill("diffuse", topR, topG, topB);
|
|
392
|
+
app.beginShape(PApplet.QUADS);
|
|
393
|
+
app.vertex(w, -h, d);
|
|
394
|
+
app.vertex(w, -h, -d);
|
|
395
|
+
app.vertex(w / 3f, -h, -d / 3f);
|
|
396
|
+
app.vertex(w / 3f, -h, d / 3f);
|
|
397
|
+
|
|
398
|
+
app.vertex(w, -h, -d);
|
|
399
|
+
app.vertex(-w, -h, -d);
|
|
400
|
+
app.vertex(-w / 3f, -h, -d / 3f);
|
|
401
|
+
app.vertex(w / 3f, -h, -d / 3f);
|
|
402
|
+
|
|
403
|
+
app.vertex(-w, -h, -d);
|
|
404
|
+
app.vertex(-w, -h, d);
|
|
405
|
+
app.vertex(-w / 3f, -h, d / 3f);
|
|
406
|
+
app.vertex(-w / 3f, -h, -d / 3f);
|
|
407
|
+
|
|
408
|
+
app.vertex(-w, -h, d);
|
|
409
|
+
app.vertex(w, -h, d);
|
|
410
|
+
app.vertex(w / 3f, -h, d / 3f);
|
|
411
|
+
app.vertex(-w / 3f, -h, d / 3f);
|
|
412
|
+
app.endShape();
|
|
413
|
+
|
|
414
|
+
//ceiling light
|
|
415
|
+
this.fill("light", radianceR, radianceG, radianceB, samples);
|
|
416
|
+
app.beginShape(PApplet.QUADS);
|
|
417
|
+
app.vertex(w / 3f, -h, d / 3f);
|
|
418
|
+
app.vertex(w / 3f, -h, -d / 3f);
|
|
419
|
+
app.vertex(-w / 3f, -h, -d / 3f);
|
|
420
|
+
app.vertex(-w / 3f, -h, d / 3f);
|
|
421
|
+
app.endShape();
|
|
422
|
+
|
|
423
|
+
//restore previous fill
|
|
424
|
+
this.fill(tempFillerType, tempParams);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
//rendering inteface
|
|
428
|
+
private boolean renderSunflow() {
|
|
429
|
+
PApplet.println(JR_VERSION_PRINT);
|
|
430
|
+
checkSettings();
|
|
431
|
+
if (renderIsAGo) {
|
|
432
|
+
//saves processing image to sketch folder
|
|
433
|
+
app.saveFrame(UNRENDERED_FILE_NAME);
|
|
434
|
+
|
|
435
|
+
//create & build sunflow renderer api
|
|
436
|
+
createSunflowRenderer();
|
|
437
|
+
if (buildSunflowRenderer()) {
|
|
438
|
+
|
|
439
|
+
//render using the created & built api
|
|
440
|
+
JRImagePanel imagePanel = new JRImagePanel();
|
|
441
|
+
api.render(SunflowAPI.DEFAULT_OPTIONS, imagePanel);
|
|
442
|
+
IMG_RENDERED = imagePanel.getInversedImage();
|
|
443
|
+
IMG_RENDERED.save(app.sketchPath(RENDERED_INV_FILE_NAME));
|
|
444
|
+
return true;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
private void checkSettings() {
|
|
451
|
+
renderIsAGo = true;
|
|
452
|
+
|
|
453
|
+
if (!FILLERS_ARE_VALID) {
|
|
454
|
+
renderIsAGo = false;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (!SAMPLER.equals(IPR) && !SAMPLER.equals(BUCKET)) {
|
|
458
|
+
PApplet.println(IMAGE_SAMPLER_ERROR);
|
|
459
|
+
renderIsAGo = false;
|
|
460
|
+
}
|
|
461
|
+
if (AA_MIN > 2 || AA_MIN < -2 || AA_MAX > 2 || AA_MAX < -2 || AA_MIN > AA_MAX) {
|
|
462
|
+
PApplet.println(IMAGE_AA_ERROR);
|
|
463
|
+
renderIsAGo = false;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
private void createSunflowRenderer() {
|
|
468
|
+
//compiling sunflow api
|
|
469
|
+
StringBuilder template = new StringBuilder();
|
|
470
|
+
template.append("import org.sunflow.core.*;\n");
|
|
471
|
+
template.append("import org.sunflow.core.accel.*;\n");
|
|
472
|
+
template.append("import org.sunflow.core.camera.*;\n");
|
|
473
|
+
template.append("import org.sunflow.core.primitive.*;\n");
|
|
474
|
+
template.append("import org.sunflow.core.shader.*;\n");
|
|
475
|
+
template.append("import org.sunflow.image.Color;\n");
|
|
476
|
+
template.append("import org.sunflow.math.*;\n\n");
|
|
477
|
+
template.append("public void build() {\n");
|
|
478
|
+
template.append("}\n");
|
|
479
|
+
String buildTemplate = template.toString();
|
|
480
|
+
api = SunflowAPI.compile(buildTemplate);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
private boolean buildSunflowRenderer() {
|
|
484
|
+
//image settings
|
|
485
|
+
api.parameter("resolutionX", (int) (app.width * SIZE_MULTIPLIER));
|
|
486
|
+
api.parameter("resolutionY", (int) (app.height * SIZE_MULTIPLIER));
|
|
487
|
+
api.parameter("sampler", SAMPLER);
|
|
488
|
+
api.parameter("aa.min", AA_MIN);
|
|
489
|
+
api.parameter("aa.max", AA_MAX);
|
|
490
|
+
api.parameter("aa.samples", AA_SAMPLES);
|
|
491
|
+
api.parameter("filter", "gaussian");
|
|
492
|
+
api.options(SunflowAPI.DEFAULT_OPTIONS);
|
|
493
|
+
|
|
494
|
+
//camera block
|
|
495
|
+
//common settings
|
|
496
|
+
//default setting for camera after viewModel transformation.
|
|
497
|
+
api.parameter("transform", Matrix4.lookAt(new Point3(0, 0, 0),
|
|
498
|
+
new Point3(0, 0, -1),
|
|
499
|
+
new Vector3(0, 1, 0)));
|
|
500
|
+
|
|
501
|
+
//compensating for the different ways Processing and Sunflow implement FOV.
|
|
502
|
+
//Processing has mid-plane vertical FOV, whereas Sunflow has mid-plane horizontal FOV.
|
|
503
|
+
float fovSunflow = 2 * PApplet.atan(PApplet.tan(FOV / 2f) * ASPECT) * 360 / (2 * PApplet.PI);
|
|
504
|
+
api.parameter("fov", fovSunflow);
|
|
505
|
+
api.parameter("aspect", ASPECT);
|
|
506
|
+
|
|
507
|
+
//individual camera block
|
|
508
|
+
if (FOCAL_DISTANCE == -1) {
|
|
509
|
+
//pinhole camera
|
|
510
|
+
api.camera("Camera_0", "pinhole");
|
|
511
|
+
api.parameter("camera", "Camera_0");
|
|
512
|
+
api.options(SunflowAPI.DEFAULT_OPTIONS);
|
|
513
|
+
|
|
514
|
+
} else {
|
|
515
|
+
//thin lens camera
|
|
516
|
+
api.parameter("focus.distance", FOCAL_DISTANCE);
|
|
517
|
+
api.parameter("lens.radius", LENS_RADIUS);
|
|
518
|
+
api.camera("Camera_0", "thinlens");
|
|
519
|
+
api.parameter("camera", "Camera_0");
|
|
520
|
+
api.options(SunflowAPI.DEFAULT_OPTIONS);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
//caustics block
|
|
524
|
+
api.parameter("caustics.emit", CAUSTICS_EMIT);
|
|
525
|
+
api.parameter("caustics", "kd");
|
|
526
|
+
api.parameter("caustics.gather", CAUSTICS_GATHER);
|
|
527
|
+
api.parameter("caustics.radius", CAUSTICS_RADIUS);
|
|
528
|
+
api.options(SunflowAPI.DEFAULT_OPTIONS);
|
|
529
|
+
|
|
530
|
+
//trace depth block
|
|
531
|
+
api.parameter("depths.diffuse", TRACE_DEPTH_DIFF);
|
|
532
|
+
api.parameter("depths.reflection", TRACE_DEPTH_REFL);
|
|
533
|
+
api.parameter("depths.refraction", TRACE_DEPTH_REFR);
|
|
534
|
+
api.options(SunflowAPI.DEFAULT_OPTIONS);
|
|
535
|
+
|
|
536
|
+
//global illumination block
|
|
537
|
+
//gi, ambient occlusion
|
|
538
|
+
if (GI_AMB_OCC_IS_CALLED) {
|
|
539
|
+
api.parameter("gi.engine", "ambocc");
|
|
540
|
+
api.parameter("gi.ambocc.bright", null, new float[]{GI_AMB_OCC_BRIGHT_R, GI_AMB_OCC_BRIGHT_G, GI_AMB_OCC_BRIGHT_B});
|
|
541
|
+
api.parameter("gi.ambocc.dark", null, new float[]{GI_AMB_OCC_DARK_R, GI_AMB_OCC_DARK_G, GI_AMB_OCC_DARK_B});
|
|
542
|
+
api.parameter("gi.ambocc.samples", GI_AMB_OCC_SAMPLES);
|
|
543
|
+
api.parameter("gi.ambocc.maxdist", GI_AMB_OCC_MAX_DIST);
|
|
544
|
+
api.options(SunflowAPI.DEFAULT_OPTIONS);
|
|
545
|
+
|
|
546
|
+
} else if (!GI_AMB_OCC_IS_CALLED && GI_IS_CALLED) { //gi, instant
|
|
547
|
+
api.parameter("gi.engine", "igi");
|
|
548
|
+
api.parameter("gi.igi.samples", GI_INSTANT_SAMPLES);
|
|
549
|
+
api.parameter("gi.igi.sets", GI_INSTANT_SETS);
|
|
550
|
+
api.parameter("gi.igi.c", GI_INSTANT_C);
|
|
551
|
+
api.parameter("gi.igi.bias_samples", GI_INSTANT_BIAS_SAMPLES);
|
|
552
|
+
api.options(SunflowAPI.DEFAULT_OPTIONS);
|
|
553
|
+
|
|
554
|
+
} else { //no gi
|
|
555
|
+
api.parameter("gi.engine", "none");
|
|
556
|
+
api.options(SunflowAPI.DEFAULT_OPTIONS);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
//light block
|
|
560
|
+
int numLightsInScene = 0;
|
|
561
|
+
for (int i = 0; i < fillers.size(); i++) {
|
|
562
|
+
JRFiller temp = fillers.get(i);
|
|
563
|
+
if (temp.getType() == null ? LIGHT == null : temp.getType().equals(LIGHT)) {
|
|
564
|
+
if (!buildLight(temp, i)) {
|
|
565
|
+
return false;
|
|
566
|
+
} else {
|
|
567
|
+
numLightsInScene++;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// Sunsky light block.
|
|
573
|
+
for (int i = 0; i < fillers.size(); i++) {
|
|
574
|
+
JRFiller filler = fillers.get(i);
|
|
575
|
+
if (filler.getType() == null ? SUNSKY == null : filler.getType().equals(SUNSKY)) {
|
|
576
|
+
// Now, we counted the lights in the previous loop becuase
|
|
577
|
+
// the Sunsky light in Sunflow doesn't emit photons and we
|
|
578
|
+
// must have at least ONE photon emitting light in the scene
|
|
579
|
+
// or the scene will crash. We can also only have one Sunsky
|
|
580
|
+
// in our scene, so we'll keep the same light name, which
|
|
581
|
+
// the Sunflow API will just overwrite if there are subsequent
|
|
582
|
+
// calls to creating a Sunsky light.
|
|
583
|
+
if (numLightsInScene == 0) {
|
|
584
|
+
// We need to generate at least one light, so let's just create one
|
|
585
|
+
// that _should_ be harmless in the scene somewhere. We're going to
|
|
586
|
+
// Create a point light somewhere far away.
|
|
587
|
+
/*
|
|
588
|
+
* Parameters:
|
|
589
|
+
* "center": Point
|
|
590
|
+
* "power": Color
|
|
591
|
+
*/
|
|
592
|
+
api.parameter("center", new Point3(-500, 0, -500));
|
|
593
|
+
api.parameter("power", "sRGB linear", 0.01f, 0.01f, 0.01f);
|
|
594
|
+
api.light("defaultPointLight", "point");
|
|
595
|
+
}
|
|
596
|
+
/*
|
|
597
|
+
* Parameter list:
|
|
598
|
+
* [0] extendSkyBeyondHorizong
|
|
599
|
+
* [1] dirX
|
|
600
|
+
* [2] dirY
|
|
601
|
+
* [3] dirZ
|
|
602
|
+
* [4] samples
|
|
603
|
+
* [5] upX
|
|
604
|
+
* [6] upY
|
|
605
|
+
* [7] upZ
|
|
606
|
+
* [8] eastX
|
|
607
|
+
* [9] eastY
|
|
608
|
+
* [10] eastZ
|
|
609
|
+
*/
|
|
610
|
+
api.parameter("ground.extendsky", filler.p[0] == 0);
|
|
611
|
+
api.parameter("up", new Vector3(filler.p[5], filler.p[6], filler.p[7]));
|
|
612
|
+
api.parameter("east", new Vector3(filler.p[8], filler.p[9], filler.p[10]));
|
|
613
|
+
api.parameter("samples", (int) filler.p[4]);
|
|
614
|
+
api.parameter("sundir", new Vector3(filler.p[1], filler.p[2], filler.p[3]));
|
|
615
|
+
api.parameter("turbidity", DEF_SUNSKY_TURBIDITY);
|
|
616
|
+
api.light("sunsky_" + i, SUNSKY);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
//shader block
|
|
621
|
+
for (int i = 0; i < fillers.size(); i++) {
|
|
622
|
+
JRFiller temp = fillers.get(i);
|
|
623
|
+
if (temp.getType() == null ? LIGHT != null : !temp.getType().equals(LIGHT)) {
|
|
624
|
+
if (!buildFiller(temp, i)) {
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
//instance block
|
|
631
|
+
for (int i = 0; i < fillers.size(); i++) {
|
|
632
|
+
JRFiller temp = fillers.get(i);
|
|
633
|
+
if (temp.getType() == null ? LIGHT != null : !temp.getType().equals(LIGHT)) {
|
|
634
|
+
buildInstance(temp, i); //should have the same condition as shader block
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
//background primitive
|
|
639
|
+
api.parameter("color", null, new float[]{BG_R, BG_G, BG_B});
|
|
640
|
+
api.shader("bg.shader", "constant");
|
|
641
|
+
api.geometry("bg", "background");
|
|
642
|
+
api.parameter("shaders", "bg.shader");
|
|
643
|
+
api.instance("bg.instance", "bg");
|
|
644
|
+
|
|
645
|
+
return true;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
private boolean buildLight(JRFiller temp, int i) {
|
|
649
|
+
//light mesh
|
|
650
|
+
if (temp.np == 3 || temp.np == 4) {
|
|
651
|
+
api.parameter("radiance", null, new float[]{temp.p[0], temp.p[1], temp.p[2]});
|
|
652
|
+
if (temp.np == 4) {
|
|
653
|
+
api.parameter("samples", (int) temp.p[3]);
|
|
654
|
+
}
|
|
655
|
+
api.parameter("points", "point", "vertex", temp.verticesToArray());
|
|
656
|
+
api.parameter("triangles", temp.triangleIndicesToArray());
|
|
657
|
+
api.light("Shader_" + i, "triangle_mesh");
|
|
658
|
+
} else {
|
|
659
|
+
PApplet.println(FILLER_LIGHT_ERROR);
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
//light spheres
|
|
664
|
+
List<Float> spheres = temp.getSpheres();
|
|
665
|
+
int noOfSpheres = (int) spheres.size() / 4;
|
|
666
|
+
|
|
667
|
+
for (int j = 0; j < noOfSpheres; j++) {
|
|
668
|
+
float x = spheres.get(j * 4);
|
|
669
|
+
float y = spheres.get(j * 4 + 1);
|
|
670
|
+
float z = spheres.get(j * 4 + 2);
|
|
671
|
+
float r = spheres.get(j * 4 + 3);
|
|
672
|
+
|
|
673
|
+
if (temp.np == 3 || temp.np == 4) {
|
|
674
|
+
api.parameter("radiance", null, new float[]{temp.p[0], temp.p[1], temp.p[2]});
|
|
675
|
+
api.parameter("center", new Point3(x, y, z));
|
|
676
|
+
api.parameter("radius", r);
|
|
677
|
+
if (temp.np == 4) {
|
|
678
|
+
api.parameter("samples", (int) temp.p[3]);
|
|
679
|
+
}
|
|
680
|
+
api.light("SphereLight_" + i + "_" + j, "sphere");
|
|
681
|
+
} else {
|
|
682
|
+
return false;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return true;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
private boolean buildFiller(JRFiller temp, int i) {
|
|
689
|
+
//constant shader
|
|
690
|
+
if (temp.getType() == null ? CONSTANT == null : temp.getType().equals(CONSTANT)) {
|
|
691
|
+
if (temp.np == 3) {
|
|
692
|
+
api.parameter("color", SRGB_NONLINEAR, temp.p[0] / 255f, temp.p[1] / 255f, temp.p[2] / 255f);
|
|
693
|
+
api.shader("Shader_" + i, "constant");
|
|
694
|
+
} else {
|
|
695
|
+
PApplet.println(FILLER_CONSTANT_ERROR);
|
|
696
|
+
return false;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
//diffuse shader
|
|
701
|
+
if (temp.getType() == null ? DIFFUSE == null : temp.getType().equals(DIFFUSE)) {
|
|
702
|
+
if (temp.np == 3) {
|
|
703
|
+
api.parameter("diffuse", SRGB_NONLINEAR, temp.p[0] / 255f, temp.p[1] / 255f, temp.p[2] / 255f);
|
|
704
|
+
api.shader("Shader_" + i, "diffuse");
|
|
705
|
+
} else {
|
|
706
|
+
PApplet.println(FILLER_DIFFUSE_ERROR);
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
//shiny shader
|
|
712
|
+
if (temp.getType() == null ? SHINY == null : temp.getType().equals(SHINY)) {
|
|
713
|
+
if (temp.np == 3 || temp.np == 4) {
|
|
714
|
+
api.parameter("diffuse", SRGB_NONLINEAR, temp.p[0] / 255f, temp.p[1] / 255f, temp.p[2] / 255f);
|
|
715
|
+
if (temp.np == 4) {
|
|
716
|
+
api.parameter("shiny", temp.p[3]);
|
|
717
|
+
}
|
|
718
|
+
api.shader("Shader_" + i, "shiny_diffuse");
|
|
719
|
+
} else {
|
|
720
|
+
PApplet.println(FILLER_SHINY_ERROR);
|
|
721
|
+
return false;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
//mirror shader
|
|
726
|
+
if (temp.getType() == null ? MIRROR == null : temp.getType().equals(MIRROR)) {
|
|
727
|
+
if (temp.np == 3) {
|
|
728
|
+
api.parameter("color", SRGB_NONLINEAR, temp.p[0] / 255f, temp.p[1] / 255f, temp.p[2] / 255f);
|
|
729
|
+
api.shader("Shader_" + i, "mirror");
|
|
730
|
+
} else {
|
|
731
|
+
PApplet.println(FILLER_MIRROR_ERROR);
|
|
732
|
+
return false;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
//glass shader
|
|
737
|
+
if (temp.getType() == null ? GLASS == null : temp.getType().equals(GLASS)) {
|
|
738
|
+
if (temp.np == 3 || temp.np == 4 || temp.np == 8) {
|
|
739
|
+
api.parameter("color", SRGB_NONLINEAR, temp.p[0] / 255f, temp.p[1] / 255f, temp.p[2] / 255f);
|
|
740
|
+
if (temp.np >= 4) {
|
|
741
|
+
api.parameter("eta", temp.p[3]); // index of refraction, IOR, def 1.6f
|
|
742
|
+
}
|
|
743
|
+
if (temp.np == 8) {
|
|
744
|
+
api.parameter("absorption.distance", temp.p[4]); // def 5
|
|
745
|
+
api.parameter("absorption.color", SRGB_NONLINEAR, temp.p[5] / 255f, temp.p[6] / 255f, temp.p[7] / 255f);
|
|
746
|
+
}
|
|
747
|
+
api.shader("Shader_" + i, "glass");
|
|
748
|
+
} else {
|
|
749
|
+
PApplet.println(FILLER_GLASS_ERROR);
|
|
750
|
+
return false;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
//phong shader
|
|
755
|
+
if (temp.getType() == null ? PHONG == null : temp.getType().equals(PHONG)) {
|
|
756
|
+
if (temp.np == 3 || temp.np == 6 || temp.np == 8) {
|
|
757
|
+
api.parameter("diffuse", SRGB_NONLINEAR, new float[]{temp.p[0] / 255f, temp.p[1] / 255f, temp.p[2] / 255f});
|
|
758
|
+
if (temp.np >= 6) {
|
|
759
|
+
api.parameter("specular", SRGB_NONLINEAR, new float[]{temp.p[3] / 255f, temp.p[4] / 255f, temp.p[5] / 255f});
|
|
760
|
+
}
|
|
761
|
+
if (temp.np == 8) {
|
|
762
|
+
api.parameter("power", temp.p[6]);
|
|
763
|
+
api.parameter("samples", (int) temp.p[7]);
|
|
764
|
+
}
|
|
765
|
+
api.shader("Shader_" + i, "phong");
|
|
766
|
+
} else {
|
|
767
|
+
PApplet.println(FILLER_PHONG_ERROR);
|
|
768
|
+
return false;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
//ambient occlusion shader
|
|
773
|
+
if (temp.getType() == null ? AMBIENT_OCCLUSION == null : temp.getType().equals(AMBIENT_OCCLUSION)) {
|
|
774
|
+
if (temp.np == 3 || temp.np == 8) {
|
|
775
|
+
api.parameter("bright", SRGB_NONLINEAR, new float[]{temp.p[0] / 255f, temp.p[1] / 255f, temp.p[2] / 255f});
|
|
776
|
+
if (temp.np != 8) {
|
|
777
|
+
api.parameter("maxdist", DEF_AMB_OCC_MAX_DIST);
|
|
778
|
+
}
|
|
779
|
+
if (temp.np == 8) {
|
|
780
|
+
api.parameter("dark", SRGB_NONLINEAR, new float[]{temp.p[3] / 255f, temp.p[4] / 255f, temp.p[5] / 255f});
|
|
781
|
+
api.parameter("maxdist", temp.p[6]);
|
|
782
|
+
api.parameter("samples", (int) temp.p[7]);
|
|
783
|
+
}
|
|
784
|
+
api.shader("Shader_" + i, "ambient_occlusion");
|
|
785
|
+
} else {
|
|
786
|
+
PApplet.println(FILLER_AMB_OCC_ERROR);
|
|
787
|
+
return false;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return true;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
private void buildInstance(JRFiller temp, int i) {
|
|
794
|
+
//render the respective objects with the above defined shaders
|
|
795
|
+
|
|
796
|
+
//generic mesh method
|
|
797
|
+
api.parameter("points", "point", "vertex", temp.verticesToArray()); //np is the number of points, or vertices
|
|
798
|
+
api.parameter("triangles", temp.triangleIndicesToArray()); //nt is the number of triangle faces.
|
|
799
|
+
api.geometry("Object_" + i, "triangle_mesh");
|
|
800
|
+
api.parameter("shaders", "Shader_" + i);
|
|
801
|
+
api.instance("Object_" + i + ".instance", "Object_" + i);
|
|
802
|
+
|
|
803
|
+
//render the respective spheres
|
|
804
|
+
List<Float> spheres = temp.getSpheres();
|
|
805
|
+
int noOfSpheres = spheres.size() / 4;
|
|
806
|
+
|
|
807
|
+
for (int j = 0; j < noOfSpheres; j++) {
|
|
808
|
+
float x = spheres.get(j * 4);
|
|
809
|
+
float y = spheres.get(j * 4 + 1);
|
|
810
|
+
float z = spheres.get(j * 4 + 2);
|
|
811
|
+
float r = spheres.get(j * 4 + 3);
|
|
812
|
+
|
|
813
|
+
Matrix4 translate = Matrix4.IDENTITY.multiply(Matrix4.translation(x, y, z));
|
|
814
|
+
Matrix4 scale = Matrix4.IDENTITY.multiply(Matrix4.scale(r, r, r));
|
|
815
|
+
|
|
816
|
+
Matrix4 m = Matrix4.IDENTITY;
|
|
817
|
+
m = scale.multiply(m);
|
|
818
|
+
m = translate.multiply(m);
|
|
819
|
+
|
|
820
|
+
api.geometry("Sphere_" + i + "_" + j, "sphere");
|
|
821
|
+
api.parameter("shaders", "Shader_" + i);
|
|
822
|
+
api.parameter("transform", m);
|
|
823
|
+
api.instance("Sphere_" + i + "_" + j + ".instance", "Sphere_" + i + "_" + j);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
public void displayRendered(boolean displaySwitch) {
|
|
828
|
+
//the below are to reset the display before displaying the rendered image
|
|
829
|
+
if (rendered && displaySwitch) {
|
|
830
|
+
app.background(255);
|
|
831
|
+
app.noLights();
|
|
832
|
+
app.camera();
|
|
833
|
+
app.perspective();
|
|
834
|
+
app.image(IMG_RENDERED, 0, 0, app.width, app.height);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|