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,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
|
+
}
|