├── .gitattributes
├── .gitignore
├── README.md
├── Screenshot (25).png
├── build.xml
├── manifest.mf
├── nbproject
├── build-impl.xml
├── configs
│ ├── Run_as_WebStart.properties
│ └── Run_in_Browser.properties
├── genfiles.properties
├── jfx-impl.xml
├── private
│ ├── configs
│ │ ├── Run_as_WebStart.properties
│ │ └── Run_in_Browser.properties
│ ├── private.properties
│ └── private.xml
├── project.properties
└── project.xml
└── src
├── AbsObject.java
├── Camera.java
├── Colour.java
├── Floor.java
├── Intersect.java
├── LightSource.java
├── Material.java
├── Materials.java
├── Ray.java
├── RayTracer.java
├── Render.java
├── Sphere.java
├── Vector.java
├── View.java
└── rayTraceRender.java
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JavaFX-Ray-Tracer
2 | A ray tracer with a JavaFX front end and Java backend.
3 |
4 | Supports:
5 | - Diffusion
6 | - Specularity
7 | - Super, Adaptive, and Stochastic(Monte Carlo) Antialiasing
8 | - Camera manipulation
9 | - Custom materials (no uv mapping)
10 | - Custom point source lighting
11 | - Custom objects (only spheres currently)
12 | - Render previews
13 |
14 | Upcoming:
15 | -Finish refraction
16 | - * ray splitting for reflection, and refraction
17 | - * total internal reflection
18 | - * Fresnel reflectivity
19 | - Add normal mapping
20 | - Add displacement mapping
21 | - Add Fresnel reflectivity
22 | - Add Depth of Field
23 | - Add area light sources
24 | - Add diffuse inter-reflection
25 | - Add surface and object caustics
26 | - Add transparency
27 | - Add soft shadows
28 |
--------------------------------------------------------------------------------
/Screenshot (25).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coelacant1/JavaFX-Ray-Tracer/4c339a22dc9c1b8ab8ecdea612d2b7f2672596c7/Screenshot (25).png
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 | Builds, tests, and runs the project rowland005_renderApp.
3 |
4 |
53 |
54 |
--------------------------------------------------------------------------------
/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | X-COMMENT: Main-Class will be added automatically by build
3 |
4 |
--------------------------------------------------------------------------------
/nbproject/build-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 | Must set src.dir
234 | Must set test.src.dir
235 | Must set build.dir
236 | Must set dist.dir
237 | Must set build.classes.dir
238 | Must set dist.javadoc.dir
239 | Must set build.test.classes.dir
240 | Must set build.test.results.dir
241 | Must set build.classes.excludes
242 | Must set dist.jar
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 | Must set javac.includes
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 | No tests executed.
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 | Must set JVM to use for profiling in profiler.info.jvm
723 | Must set profiler agent JVM arguments in profiler.info.jvmargs.agent
724 |
725 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
944 |
945 |
946 |
947 |
948 |
949 |
950 |
951 | Must select some files in the IDE or set javac.includes
952 |
953 |
954 |
955 |
956 |
957 |
958 |
959 |
960 |
965 |
966 |
967 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
988 |
989 |
990 |
991 |
992 |
993 |
994 |
995 |
996 |
997 |
998 |
999 |
1000 |
1001 | To run this application from the command line without Ant, try:
1002 |
1003 | java -jar "${dist.jar.resolved}"
1004 |
1005 |
1006 |
1007 |
1008 |
1009 |
1010 |
1011 |
1012 |
1013 |
1014 |
1015 |
1016 |
1017 |
1018 |
1019 |
1020 |
1021 |
1022 |
1023 |
1024 |
1025 |
1026 |
1027 |
1028 |
1029 |
1030 |
1031 |
1032 |
1033 |
1034 |
1039 |
1040 |
1041 |
1042 |
1043 |
1044 |
1045 |
1046 |
1047 |
1048 |
1049 |
1050 | Must select one file in the IDE or set run.class
1051 |
1052 |
1053 |
1054 | Must select one file in the IDE or set run.class
1055 |
1056 |
1057 |
1062 |
1063 |
1064 |
1065 |
1066 |
1067 |
1068 |
1069 |
1070 |
1071 |
1072 |
1073 |
1074 |
1075 |
1076 |
1077 |
1078 |
1079 |
1080 |
1081 | Must select one file in the IDE or set debug.class
1082 |
1083 |
1084 |
1085 |
1086 | Must select one file in the IDE or set debug.class
1087 |
1088 |
1089 |
1090 |
1091 | Must set fix.includes
1092 |
1093 |
1094 |
1095 |
1096 |
1097 |
1098 |
1103 |
1106 |
1107 | This target only works when run from inside the NetBeans IDE.
1108 |
1109 |
1110 |
1111 |
1112 |
1113 |
1114 |
1115 |
1116 | Must select one file in the IDE or set profile.class
1117 | This target only works when run from inside the NetBeans IDE.
1118 |
1119 |
1120 |
1121 |
1122 |
1123 |
1124 |
1125 |
1126 | This target only works when run from inside the NetBeans IDE.
1127 |
1128 |
1129 |
1130 |
1131 |
1132 |
1133 |
1134 |
1135 |
1136 |
1137 |
1138 |
1139 | This target only works when run from inside the NetBeans IDE.
1140 |
1141 |
1142 |
1143 |
1144 |
1145 |
1146 |
1147 |
1148 |
1149 |
1150 |
1151 |
1152 |
1153 |
1154 |
1155 |
1156 |
1157 |
1158 |
1159 |
1160 |
1161 |
1164 |
1165 |
1166 |
1167 |
1168 |
1169 |
1170 |
1171 |
1172 |
1173 |
1174 |
1175 |
1176 |
1177 | Must select one file in the IDE or set run.class
1178 |
1179 |
1180 |
1181 |
1182 |
1183 | Must select some files in the IDE or set test.includes
1184 |
1185 |
1186 |
1187 |
1188 | Must select one file in the IDE or set run.class
1189 |
1190 |
1191 |
1192 |
1193 | Must select one file in the IDE or set applet.url
1194 |
1195 |
1196 |
1197 |
1202 |
1203 |
1204 |
1205 |
1206 |
1207 |
1208 |
1209 |
1210 |
1211 |
1212 |
1213 |
1214 |
1215 |
1216 |
1217 |
1218 |
1219 |
1220 |
1221 |
1222 |
1223 |
1224 |
1225 |
1226 |
1227 |
1228 |
1229 |
1230 |
1231 |
1232 |
1233 |
1234 |
1235 |
1236 |
1237 |
1238 |
1239 |
1240 |
1241 |
1246 |
1247 |
1248 |
1249 |
1250 |
1251 |
1252 |
1253 |
1254 |
1255 |
1256 |
1257 |
1258 |
1259 |
1260 |
1261 |
1262 |
1263 |
1264 |
1265 |
1266 |
1267 |
1268 |
1269 |
1270 |
1271 |
1272 | Must select some files in the IDE or set javac.includes
1273 |
1274 |
1275 |
1276 |
1277 |
1278 |
1279 |
1280 |
1281 |
1282 |
1283 |
1284 |
1289 |
1290 |
1291 |
1292 |
1293 |
1294 |
1295 |
1296 | Some tests failed; see details above.
1297 |
1298 |
1299 |
1300 |
1301 |
1302 |
1303 |
1304 |
1305 | Must select some files in the IDE or set test.includes
1306 |
1307 |
1308 |
1309 | Some tests failed; see details above.
1310 |
1311 |
1312 |
1313 | Must select some files in the IDE or set test.class
1314 | Must select some method in the IDE or set test.method
1315 |
1316 |
1317 |
1318 | Some tests failed; see details above.
1319 |
1320 |
1321 |
1326 |
1327 | Must select one file in the IDE or set test.class
1328 |
1329 |
1330 |
1331 | Must select one file in the IDE or set test.class
1332 | Must select some method in the IDE or set test.method
1333 |
1334 |
1335 |
1336 |
1337 |
1338 |
1339 |
1340 |
1341 |
1342 |
1343 |
1344 |
1349 |
1350 | Must select one file in the IDE or set applet.url
1351 |
1352 |
1353 |
1354 |
1355 |
1356 |
1357 |
1362 |
1363 | Must select one file in the IDE or set applet.url
1364 |
1365 |
1366 |
1367 |
1368 |
1369 |
1370 |
1371 |
1376 |
1377 |
1378 |
1379 |
1380 |
1381 |
1382 |
1383 |
1384 |
1385 |
1386 |
1387 |
1388 |
1389 |
1390 |
1391 |
1392 |
1393 |
1394 |
1395 |
1396 |
1397 |
1398 |
1399 |
1400 |
1401 |
1402 |
1403 |
1404 |
1405 |
1406 |
1407 |
1408 |
1409 |
1410 |
1411 |
1412 |
1413 |
1414 |
1415 |
1416 |
1417 |
1418 |
1419 |
1420 |
1421 |
--------------------------------------------------------------------------------
/nbproject/configs/Run_as_WebStart.properties:
--------------------------------------------------------------------------------
1 | # Do not modify this property in this configuration. It can be re-generated.
2 | $label=Run as WebStart
3 |
--------------------------------------------------------------------------------
/nbproject/configs/Run_in_Browser.properties:
--------------------------------------------------------------------------------
1 | # Do not modify this property in this configuration. It can be re-generated.
2 | $label=Run in Browser
3 |
--------------------------------------------------------------------------------
/nbproject/genfiles.properties:
--------------------------------------------------------------------------------
1 | build.xml.data.CRC32=c1691376
2 | build.xml.script.CRC32=2c3e14dc
3 | build.xml.stylesheet.CRC32=8064a381@1.79.1.48
4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
6 | nbproject/build-impl.xml.data.CRC32=58402082
7 | nbproject/build-impl.xml.script.CRC32=ba6c94b9
8 | nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
9 |
--------------------------------------------------------------------------------
/nbproject/private/configs/Run_as_WebStart.properties:
--------------------------------------------------------------------------------
1 | # Do not modify this property in this configuration. It can be re-generated.
2 | javafx.run.as=webstart
3 |
--------------------------------------------------------------------------------
/nbproject/private/configs/Run_in_Browser.properties:
--------------------------------------------------------------------------------
1 | # Do not modify this property in this configuration. It can be re-generated.
2 | javafx.run.as=embedded
3 |
--------------------------------------------------------------------------------
/nbproject/private/private.properties:
--------------------------------------------------------------------------------
1 | auxiliary.org-netbeans-modules-projectapi.issue214819_5f_fx_5f_enabled=true
2 | # No need to modify this property unless customizing JavaFX Ant task infrastructure
3 | endorsed.javafx.ant.classpath=.
4 | javafx.run.inbrowser=
5 | javafx.run.inbrowser.path=C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE
6 | user.properties.file=C:\\Users\\Rollie\\AppData\\Roaming\\NetBeans\\8.1\\build.properties
7 |
--------------------------------------------------------------------------------
/nbproject/private/private.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Material.java
7 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Render.java
8 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/LightSource.java
9 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/rayTraceRender.java
10 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/AbsObject.java
11 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Floor.java
12 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Intersect.java
13 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Materials.java
14 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/View.java
15 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Camera.java
16 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/RayTracer.java
17 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Sphere.java
18 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Ray.java
19 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Colour.java
20 | file:/C:/Users/Rollie/Documents/NetBeansProjects/rowland005_renderApp/src/Vector.java
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/nbproject/project.properties:
--------------------------------------------------------------------------------
1 | annotation.processing.enabled=true
2 | annotation.processing.enabled.in.editor=false
3 | annotation.processing.processor.options=
4 | annotation.processing.processors.list=
5 | annotation.processing.run.all.processors=true
6 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
7 | application.title=rayTracer
8 | application.vendor=Rollie
9 | build.classes.dir=${build.dir}/classes
10 | build.classes.excludes=**/*.java,**/*.form
11 | # This directory is removed when the project is cleaned:
12 | build.dir=build
13 | build.generated.dir=${build.dir}/generated
14 | build.generated.sources.dir=${build.dir}/generated-sources
15 | # Only compile against the classpath explicitly listed here:
16 | build.sysclasspath=ignore
17 | build.test.classes.dir=${build.dir}/test/classes
18 | build.test.results.dir=${build.dir}/test/results
19 | compile.on.save=true
20 | compile.on.save.unsupported.javafx=true
21 | # Uncomment to specify the preferred debugger connection transport:
22 | #debug.transport=dt_socket
23 | debug.classpath=\
24 | ${run.classpath}
25 | debug.test.classpath=\
26 | ${run.test.classpath}
27 | # This directory is removed when the project is cleaned:
28 | dist.dir=dist
29 | dist.jar=${dist.dir}/rayTracer.jar
30 | dist.javadoc.dir=${dist.dir}/javadoc
31 | endorsed.classpath=
32 | excludes=
33 | includes=**
34 | # Non-JavaFX jar file creation is deactivated in JavaFX 2.0+ projects
35 | jar.archive.disabled=true
36 | jar.compress=false
37 | javac.classpath=\
38 | ${javafx.classpath.extension}
39 | # Space-separated list of extra javac options
40 | javac.compilerargs=
41 | javac.deprecation=false
42 | javac.processorpath=\
43 | ${javac.classpath}
44 | javac.source=1.8
45 | javac.target=1.8
46 | javac.test.classpath=\
47 | ${javac.classpath}:\
48 | ${build.classes.dir}
49 | javac.test.processorpath=\
50 | ${javac.test.classpath}
51 | javadoc.additionalparam=
52 | javadoc.author=false
53 | javadoc.encoding=${source.encoding}
54 | javadoc.noindex=false
55 | javadoc.nonavbar=false
56 | javadoc.notree=false
57 | javadoc.private=false
58 | javadoc.splitindex=true
59 | javadoc.use=true
60 | javadoc.version=false
61 | javadoc.windowtitle=
62 | javafx.application.implementation.version=1.0
63 | javafx.binarycss=false
64 | javafx.classpath.extension=\
65 | ${java.home}/lib/javaws.jar:\
66 | ${java.home}/lib/deploy.jar:\
67 | ${java.home}/lib/plugin.jar
68 | javafx.deploy.allowoffline=true
69 | # If true, application update mode is set to 'background', if false, update mode is set to 'eager'
70 | javafx.deploy.backgroundupdate=false
71 | javafx.deploy.embedJNLP=true
72 | javafx.deploy.includeDT=true
73 | # Set true to prevent creation of temporary copy of deployment artifacts before each run (disables concurrent runs)
74 | javafx.disable.concurrent.runs=false
75 | # Set true to enable multiple concurrent runs of the same WebStart or Run-in-Browser project
76 | javafx.enable.concurrent.external.runs=false
77 | # This is a JavaFX project
78 | javafx.enabled=true
79 | javafx.fallback.class=com.javafx.main.NoJavaFXFallback
80 | # Main class for JavaFX
81 | javafx.main.class=rayTraceRender
82 | javafx.preloader.class=
83 | # This project does not use Preloader
84 | javafx.preloader.enabled=false
85 | javafx.preloader.jar.filename=
86 | javafx.preloader.jar.path=
87 | javafx.preloader.project.path=
88 | javafx.preloader.type=none
89 | # Set true for GlassFish only. Rebases manifest classpaths of JARs in lib dir. Not usable with signed JARs.
90 | javafx.rebase.libs=false
91 | javafx.run.height=600
92 | javafx.run.width=800
93 | # Pre-JavaFX 2.0 WebStart is deactivated in JavaFX 2.0+ projects
94 | jnlp.enabled=false
95 | # Main class for Java launcher
96 | main.class=com.javafx.main.Main
97 | # For improved security specify narrower Codebase manifest attribute to prevent RIAs from being repurposed
98 | manifest.custom.codebase=*
99 | # Specify Permissions manifest attribute to override default (choices: sandbox, all-permissions)
100 | manifest.custom.permissions=
101 | manifest.file=manifest.mf
102 | meta.inf.dir=${src.dir}/META-INF
103 | platform.active=default_platform
104 | run.classpath=\
105 | ${dist.jar}:\
106 | ${javac.classpath}:\
107 | ${build.classes.dir}
108 | run.test.classpath=\
109 | ${javac.test.classpath}:\
110 | ${build.test.classes.dir}
111 | source.encoding=UTF-8
112 | src.dir=src
113 | test.src.dir=test
114 |
--------------------------------------------------------------------------------
/nbproject/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.netbeans.modules.java.j2seproject
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | rayTracer
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | antialiasing
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/AbsObject.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public abstract class AbsObject {
13 | public Material material;
14 | public String name;
15 |
16 | public abstract Vector normal(Vector _vector);
17 | public abstract Intersect intersect(Ray ray);
18 | }
--------------------------------------------------------------------------------
/src/Camera.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public class Camera {
13 | public Vector position;
14 | public Vector above;
15 | public Vector front;
16 | public Vector right;
17 |
18 | public static Camera create(Vector target, Vector _position){
19 | Vector tempM, _front, _bottom, tempCFD, tempNormCFD, _right, tempCFR, tempNormCFR, _above;
20 | tempM = Vector.subtract(target, _position);
21 | _front = Vector.normal(tempM);
22 |
23 | _bottom = new Vector(0, -1, 0);
24 |
25 | tempCFD = Vector.crossP(_front, _bottom);
26 | tempNormCFD = Vector.normal(tempCFD);
27 | _right = Vector.multiply(2.0, tempNormCFD);
28 |
29 | tempCFR = Vector.crossP(_front, _right);
30 | tempNormCFR = Vector.normal(tempCFR);
31 | _above = Vector.multiply(2.0, tempNormCFR);
32 |
33 | return new Camera() {{
34 | this.position = _position;
35 | this.front = _front;
36 | this.above = _above;
37 | this.right = _right;
38 | }};
39 | }
40 |
41 | public static Camera create(Vector target, Vector _position, double x, double y){
42 | Vector tempM, _front, _bottom, tempCFD, tempNormCFD, _right, tempCFR, tempNormCFR, _above;
43 | double ratio = y / x;
44 |
45 | tempM = Vector.subtract(target, _position);
46 | _front = Vector.normal(tempM);
47 |
48 | _bottom = new Vector(0, -1, 0);
49 |
50 | tempCFD = Vector.crossP(_front, _bottom);
51 | tempNormCFD = Vector.normal(tempCFD);
52 | _right = Vector.multiply(2.0, tempNormCFD);
53 |
54 | tempCFR = Vector.crossP(_front, _right);
55 | tempNormCFR = Vector.normal(tempCFR);
56 | _above = Vector.multiply(2.0 * ratio, tempNormCFR);
57 |
58 | return new Camera() {{
59 | this.position = _position;
60 | this.front = _front;
61 | this.above = _above;
62 | this.right = _right;
63 | }};
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Colour.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | import java.awt.Color;
8 |
9 | /**
10 | *
11 | * @author Rollie
12 | */
13 |
14 | public class Colour
15 | {
16 | public double R, G, B;
17 |
18 | public Colour(double r, double g, double b)
19 | {
20 | R = r; G = g; B = b;
21 | }
22 |
23 | public static Colour def = create(0, 0, 0);
24 |
25 | public static Colour create(double r, double g, double b)
26 | {
27 | return new Colour(r, g, b);
28 | }
29 |
30 | public static Colour multiply(double k, Colour _colour)
31 | {
32 | return new Colour((k * _colour.R), (k * _colour.G), (k * _colour.B));
33 | }
34 |
35 | public static Colour multiply(Colour _colourO, Colour _colourT)
36 | {
37 | return new Colour((_colourO.R * _colourT.R), (_colourO.G * _colourT.G), (_colourO.B * _colourT.B));
38 | }
39 |
40 | public static Colour add(Colour _colourO, Colour _colourT)
41 | {
42 | return new Colour(_colourO.R + _colourT.R, _colourO.G + _colourT.G, _colourO.B + _colourT.B);
43 | }
44 |
45 | public static Colour average(Colour _colourO, Colour _colourT)
46 | {
47 | return new Colour((_colourO.R + _colourT.R) / 2, (_colourO.G + _colourT.G) / 2, (_colourO.B + _colourT.B) / 2);
48 | }
49 |
50 | public static Colour subtract(Colour _colourO, Colour _colourT)
51 | {
52 | return new Colour(_colourO.R - _colourT.R, _colourO.G - _colourT.G, _colourO.B - _colourT.B);
53 | }
54 |
55 | public double checkColour(double _colour)
56 | {
57 | if (_colour < 0){
58 | _colour = 0;
59 | }
60 | else if (_colour > 1){
61 | _colour = 1;
62 | }
63 |
64 | return _colour;
65 | }
66 |
67 | Color toColour()
68 | {
69 | return (new Color((int)(checkColour(R) * 255), (int)(checkColour(G) * 255), (int)(checkColour(B) * 255)));
70 | }
71 | }
--------------------------------------------------------------------------------
/src/Floor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public class Floor extends AbsObject
13 | {
14 | public double displacement;
15 | public Vector objectPosition;
16 |
17 | @Override
18 | public Vector normal(Vector position)
19 | {
20 | return objectPosition;
21 | }
22 |
23 | @Override
24 | public Intersect intersect(Ray _ray)
25 | {
26 | double _vectorD = Vector.dotProduct(objectPosition, _ray.direction);
27 | double _distance;
28 |
29 | if (_vectorD <= 0)
30 | {
31 | _distance = (displacement + Vector.dotProduct(objectPosition, _ray.begin)) / (-_vectorD);
32 | Floor floor = this;
33 |
34 | return new Intersect(){{
35 | object = floor;
36 | ray = _ray;
37 | distance = _distance;
38 | }};
39 | }
40 | else
41 | {
42 | return null;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Intersect.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public class Intersect {
13 | public AbsObject object;
14 | public double distance;
15 | public Ray ray;
16 | }
17 |
--------------------------------------------------------------------------------
/src/LightSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public class LightSource {
13 | public String name;
14 | public Colour color;
15 | public Vector position;
16 | }
17 |
--------------------------------------------------------------------------------
/src/Material.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public class Material{
13 | public java.util.function.Function specular;
14 | public java.util.function.Function reflect;
15 | public java.util.function.Function diffuse;
16 | public java.util.function.Function refractiveIndex;
17 | public double transparency;
18 | public double specularWidth;
19 | public String name;
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/src/Materials.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public class Materials {
13 | public static Material[] materials;
14 |
15 | public static Material Default =
16 | new Material(){{
17 | name = "Default";
18 | refractiveIndex = (Vector position) -> 0.0;
19 | reflect = (Vector position) -> 0.25;
20 | diffuse = (Vector position) -> Colour.create(0.25, 0.25, 0.25);
21 | specular = (Vector position) -> Colour.create(0.25, 0.25, 0.25);
22 | specularWidth = 0;
23 | transparency = 0.1;
24 | }};
25 |
26 | public static Material Floor =
27 | new Material(){{
28 | name = "Floor";
29 | //reflect = position -> 0.15;
30 | refractiveIndex = (Vector position) -> 0.0;
31 | reflect = (Vector position) -> 0.65;
32 | diffuse = (Vector position) -> Colour.create(0.25, 0.25, 0.25);
33 | specular = (Vector position) -> Colour.create(0.5, 0.5, 0.5);
34 | specularWidth = 15;
35 | transparency = 0.0;
36 | }};
37 |
38 | public static Material Mirror =
39 | new Material(){{
40 | name = "Mirror";
41 | refractiveIndex = (Vector position) -> 0.0;
42 | reflect = (Vector position) -> 1.0;
43 | diffuse = (Vector position) -> Colour.create(1.0, 1.0, 1.0);
44 | specular = (Vector position) -> Colour.create(0.75, 0.75, 0.75);
45 | specularWidth = 25;
46 | transparency = 0.1;
47 | }};
48 |
49 | public static Material Glass =
50 | new Material(){{
51 | name = "Glass";
52 | refractiveIndex = (Vector position) -> 1.0;
53 | reflect = (Vector position) -> 0.0;
54 | diffuse = (Vector position) -> Colour.create(0.0, 0.0, 0.0);
55 | specular = (Vector position) -> Colour.create(0.5, 0.5, 0.5);
56 | specularWidth = 100;
57 | transparency = 0.95;
58 | }};
59 | }
--------------------------------------------------------------------------------
/src/Ray.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public class Ray {
13 | public Vector direction;
14 | public Vector begin;
15 | }
16 |
--------------------------------------------------------------------------------
/src/RayTracer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | import java.util.ArrayList;
8 | import java.util.Arrays;
9 | import java.util.Collections;
10 | import java.awt.image.BufferedImage;
11 |
12 | /**
13 | * /EXTERNAL SOURCES/ located at lines 108 and 110
14 | *
15 | * /TODO/:
16 | * Finish refraction
17 | * ray splitting for reflection, and refraction
18 | * total internal reflection
19 | * Fresnel reflectivity
20 | * Add normal mapping
21 | * Add displacement mapping
22 | * Add Fresnel reflectivity
23 | * -Add super sampling, adaptive sampling, and stochastic sampling modes
24 | * Add Depth of Field
25 | * Add area light sources
26 | * Add diffuse inter-reflection
27 | * Add surface and object caustics
28 | * Add transparency
29 | * Add soft shadows
30 | *
31 | * @author Rollie
32 | */
33 |
34 | public class RayTracer {
35 | private final int bmpWidth;
36 | private final int bmpHeight;
37 | private final int amount = 4;
38 |
39 | public RayTracer(int w, int h){
40 | bmpWidth = w;
41 | bmpHeight = h;
42 | }
43 |
44 | private Iterable intersections(Ray ray, View view)
45 | {
46 | ArrayList rayIntersections = new ArrayList<>();
47 |
48 | for (AbsObject i : view.objects){
49 | Intersect temp = i.intersect(ray);
50 | if (temp != null){
51 | rayIntersections.add(temp);
52 | }
53 | }
54 |
55 | Collections.sort(rayIntersections, (Intersect x, Intersect y) -> Double.valueOf(x.distance).compareTo(y.distance));
56 |
57 | Iterable temp;
58 | Intersect[] tempL = new Intersect[rayIntersections.toArray().length];
59 |
60 | for (int i = 0; i < tempL.length; i++){
61 | tempL[i] = (Intersect)rayIntersections.toArray()[i];
62 | }
63 |
64 | temp = Arrays.asList(tempL);
65 |
66 | return temp;
67 | }
68 |
69 | private double shadowTest(Ray ray, View view)
70 | {
71 | Iterable intersections = intersections(ray, view);
72 | Intersect intersect = null;
73 |
74 | if(intersections.iterator().hasNext()){
75 | intersect = intersections.iterator().next();
76 | }
77 |
78 | if (intersect == null){
79 | return 0;
80 | }
81 | else{
82 | return intersect.distance;
83 | }
84 | }
85 |
86 | private Colour trace(Ray ray, View view, int amount)
87 | {
88 | Iterable intersections = intersections(ray, view);
89 | Intersect intersect = null;
90 |
91 | if(intersections.iterator().hasNext()){
92 | intersect = intersections.iterator().next();
93 | }
94 |
95 | if (intersect == null){
96 | return Colour.def;
97 | }
98 | else{
99 | return getShade(intersect, view, amount);
100 | }
101 | }
102 |
103 | private Colour getShade(Intersect intersect, View view, int _amount)
104 | {
105 | Vector direction = intersect.ray.direction;
106 | Vector position = Vector.add(Vector.multiply(intersect.distance, intersect.ray.direction), intersect.ray.begin);
107 | Vector normal = intersect.object.normal(position);
108 | //http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf - SOURCE for reflectDirection vector + equation
109 | Vector reflectDirection = Vector.subtract(direction, Vector.multiply(2 * Vector.dotProduct(normal, direction), normal));
110 | //http://web.cse.ohio-state.edu/~hwshen/681/Site/Slides_files/reflection_refraction.pdf - SOURCE for refractDirection vector + equation
111 | //nr -> object refractive index
112 | //(nr(Norm . direction) - sqrt(1 - nr^2(1 - (normal . direction)^2)) * Normal) - normal*direction
113 | Vector refractDirection =
114 | Vector.subtract(
115 | //Vector.multiply(intersect.object.material.refractiveIndex.apply(position), Vector.dotProduct(normal, direction)),
116 | Vector.multiply(
117 | (
118 | (intersect.object.material.refractiveIndex.apply(position) * Vector.dotProduct(normal, direction))-
119 | Math.sqrt(1 - Math.pow(intersect.object.material.refractiveIndex.apply(position), 2) * (1 - Math.pow(Vector.dotProduct(normal, direction), 2)))
120 | ),
121 | normal
122 | ),
123 | Vector.multiply(intersect.object.material.refractiveIndex.apply(position), direction)
124 | );
125 |
126 | Colour outColor = Colour.def;
127 |
128 | outColor = Colour.add(outColor, getColour(intersect.object, position, normal, reflectDirection, view));
129 | //outColor = Colour.add(outColor, getColour(intersect.object, position, normal, refractDirection, view));
130 | //outColor = Colour.add(outColor, Colour.average(getColour(intersect.object, position, normal, reflectDirection, view), getColour(intersect.object, position, normal, refractDirection, view)));
131 |
132 | if (_amount < amount){
133 | Colour reflect = outColor;
134 | Colour refract = outColor;
135 | // Vector.add(position, Vector.multiply(0.001, refractDirection)) -> epsilon correction
136 | //return Colour.add(outColor, getReflectColor(intersect.object, Vector.add(position, Vector.multiply(0.001, reflectDirection)), reflectDirection, view, _amount));
137 | //return Colour.add(outColor, getRefractColor(intersect.object, Vector.add(position, Vector.multiply(0.001, refractDirection)), refractDirection, view, _amount));
138 |
139 | if (intersect.object.material.refractiveIndex.apply(normal) < 1){
140 | //Vector refractDir = Vector.normal(refract());
141 | //refract = getRefractColor(intersect.object, Vector.add(normal, Vector.multiply(0.001, refractDirection)), refractDirection, view, _amount);
142 | }
143 |
144 | reflect = getReflectColor(intersect.object, Vector.add(position, Vector.multiply(0.001, reflectDirection)), reflectDirection, view, _amount);
145 | refract = getRefractColor(intersect.object, Vector.add(normal, Vector.multiply(0.001, refractDirection)), refractDirection, view, _amount);
146 |
147 | reflect = Colour.multiply((1 - intersect.object.material.transparency), reflect);
148 | refract = Colour.multiply((intersect.object.material.transparency), refract);
149 |
150 | return Colour.add(outColor, Colour.add(reflect, refract));
151 | }
152 | else
153 | {
154 | return outColor;
155 | }
156 | }
157 |
158 | private Colour getReflectColor(AbsObject object, Vector position, Vector rayDirection, View view, int _amount)
159 | {
160 | return Colour.multiply(object.material.reflect.apply(position), trace(
161 | new Ray() {{
162 | begin = position;
163 | direction = rayDirection;
164 | }},
165 | view,
166 | _amount + 1
167 | ));
168 | }
169 |
170 | //NOT FINISHED
171 | private Colour getRefractColor(AbsObject object, Vector normal, Vector rayDirection, View view, int _amount){
172 | //double tempFresnel = fresnel(rayDirection, normal, object, 1.5);
173 |
174 | return Colour.multiply(object.material.refractiveIndex.apply(normal), trace(
175 | new Ray() {{
176 | begin = normal;
177 | direction = rayDirection;
178 | }},
179 | view,
180 | _amount + 1
181 | ));
182 | }
183 |
184 | private double fresnel(Vector direction, Vector normal, AbsObject object, double indexRefraction){
185 | double cosineDirection = Vector.dotProduct(direction, normal);
186 | double etaDirection = 1;
187 | double etaT = object.material.refractiveIndex.apply(normal);
188 |
189 | if (cosineDirection > 1){
190 | cosineDirection = 1;
191 | }
192 | else if (cosineDirection < -1){
193 | cosineDirection = -1;
194 | }
195 |
196 | if(cosineDirection > 0){
197 | etaDirection = etaT;
198 | etaT = 1;
199 | }
200 |
201 | double sinT = (etaDirection / etaT) * Math.sqrt(Math.max(0.d, 1 - Math.pow(cosineDirection, 2)));
202 |
203 | if (sinT >= 1){
204 | indexRefraction = 1;
205 | }
206 | else{
207 | double cosT = Math.sqrt(Math.max(0.d, 1 - Math.pow(sinT, 2)));
208 | cosineDirection = Math.abs(cosineDirection);
209 |
210 | double rS = ((etaT * cosineDirection) - (etaDirection * cosT)) / ((etaT * cosineDirection) + (etaDirection * cosT));
211 | double rP = ((etaDirection * cosineDirection) - (etaT * cosT)) / ((etaDirection * cosineDirection) + (etaT * cosT));
212 | indexRefraction = (Math.pow(rS, 2) + Math.pow(rP, 2)) / 2;
213 | }
214 |
215 | return indexRefraction;
216 | }
217 |
218 | private Colour getColour(AbsObject object, Vector position, Vector normal, Vector rayDirection, View view)
219 | {
220 | Colour outColor = Colour.create(0, 0, 0);
221 |
222 | for (LightSource light : view.lightSource)
223 | {
224 | Vector lightDistance = Vector.subtract(light.position, position);
225 | Vector normalLD = Vector.normal(lightDistance);
226 |
227 | double cleanIntersection = shadowTest(
228 | new Ray() {{
229 | begin = position;
230 | direction = normalLD;
231 | }}
232 | , view);
233 |
234 | boolean notInShadow = ((cleanIntersection > Vector.magn(lightDistance)) || (cleanIntersection == 0));
235 |
236 | if (notInShadow)
237 | {
238 | double illumination = Vector.dotProduct(normalLD, normal);
239 | Colour lightColor = illumination > 0 ? Colour.multiply(illumination, light.color) : Colour.create(0, 0, 0);
240 | double specular = Vector.dotProduct(normalLD, Vector.normal(rayDirection));
241 | Colour specularColor = specular > 0 ? Colour.multiply(Math.pow(specular, object.material.specularWidth), light.color) : Colour.create(0, 0, 0);
242 | outColor = Colour.add(outColor, Colour.add(Colour.multiply(object.material.diffuse.apply(position), lightColor), Colour.multiply(object.material.specular.apply(position), specularColor)));
243 | }
244 | }
245 |
246 | return outColor;
247 | }
248 |
249 | private Vector getLocation(double x, double y, Camera camera)
250 | {
251 | return Vector.normal(Vector.add(camera.front, Vector.add(Vector.multiply(centerHorizontal(x), camera.right), Vector.multiply(centerVertical(y), camera.above))));
252 | }
253 |
254 | private double centerHorizontal(double horizontal)
255 | {
256 | double temp;
257 |
258 | temp = (horizontal - (bmpWidth / 2.0)) / (2.0 * bmpWidth);
259 |
260 | return temp;
261 | }
262 |
263 | private double centerVertical(double vertical)
264 | {
265 | double temp;
266 |
267 | temp = -(vertical - (bmpHeight / 2.0)) / (2.0 * bmpHeight);
268 |
269 | return temp;
270 | }
271 |
272 | BufferedImage render(View view)
273 | {
274 | final BufferedImage image = new BufferedImage( bmpWidth, bmpHeight, BufferedImage.TYPE_INT_RGB );
275 |
276 | for (int y = 0; y < bmpHeight; y++)
277 | {
278 | for (int x = 0; x < bmpWidth; x++)
279 | {
280 | Vector _direction = getLocation(x, y, view.camera);
281 |
282 | Colour colour = trace(
283 | new Ray() {{
284 | begin = view.camera.position;
285 | direction = _direction;
286 | }},
287 | view,
288 | 0);
289 |
290 | image.setRGB(x, y, colour.toColour().getRGB());
291 | }
292 | }
293 |
294 | return image;
295 | }
296 |
297 | BufferedImage renderPreview(View view, int quality){
298 | final BufferedImage image = new BufferedImage( bmpWidth, bmpHeight, BufferedImage.TYPE_INT_RGB );
299 | int incrementVal = bmpWidth / quality;
300 |
301 | for (int y = 0; y < bmpHeight; y += bmpHeight / incrementVal)
302 | {
303 | for (int x = 0; x < bmpWidth; x += bmpHeight / incrementVal)
304 | {
305 | Vector _direction = getLocation(x, y, view.camera);
306 |
307 | Colour colour = trace(
308 | new Ray() {{
309 | begin = view.camera.position;
310 | direction = _direction;
311 | }},
312 | view,
313 | 0);
314 |
315 | for (int yM = 0; yM < bmpHeight / incrementVal; yM++)
316 | {
317 | for(int xM = 0; xM < bmpWidth / incrementVal; xM++)
318 | {
319 | image.setRGB(xM + x, yM + y, colour.toColour().getRGB());
320 | }
321 | }
322 | }
323 |
324 | rayTraceRender.setImage(image);
325 | }
326 |
327 | return image;
328 | }
329 |
330 | BufferedImage renderSuperSample(View view, int depth, double filterSize)
331 | {
332 | final BufferedImage image = new BufferedImage( bmpWidth, bmpHeight, BufferedImage.TYPE_INT_RGB );
333 | double increment = filterSize / (double)depth;
334 |
335 | for (int y = 0; y < bmpHeight; y++)
336 | {
337 | for (int x = 0; x < bmpWidth; x++)
338 | {
339 | ArrayList tempVectors = new ArrayList<>();
340 | Vector[] vectors = null;
341 |
342 | for (double yV = -(filterSize / 2); yV <= (filterSize / 2); yV += increment){
343 | for (double xV = -(filterSize / 2); xV <= (filterSize / 2); xV += increment){
344 | tempVectors.add(getLocation(x + xV, y + yV, view.camera));
345 | }
346 | }
347 |
348 | vectors = tempVectors.toArray(new Vector[0]);
349 |
350 | Colour colour = null;
351 |
352 | for (int i = 0; i < vectors.length; i++){
353 | Vector tempVector = vectors[i];
354 |
355 | if (i == 0){
356 | colour = trace(
357 | new Ray() {{
358 | begin = view.camera.position;
359 | direction = tempVector;
360 | }},
361 | view,
362 | 0
363 | );
364 | }
365 | else{
366 | colour = Colour.average(colour, trace(
367 | new Ray() {{
368 | begin = view.camera.position;
369 | direction = tempVector;
370 | }},
371 | view, 0
372 | ));
373 | }
374 | }
375 |
376 | image.setRGB(x, y, colour.toColour().getRGB());
377 | }
378 |
379 | rayTraceRender.setImage(image);
380 | }
381 |
382 | return image;
383 | }
384 |
385 | BufferedImage renderAdaptiveSample(View view, int maxDepth, double filterSize)
386 | {
387 | final BufferedImage image = new BufferedImage( bmpWidth, bmpHeight, BufferedImage.TYPE_INT_RGB );
388 |
389 | for (int y = 0; y < bmpHeight; y++)
390 | {
391 | for (int x = 0; x < bmpWidth; x++)
392 | {
393 | int iterator = 1;
394 | double increment = filterSize;
395 | Colour tempAvgColour = null;
396 | Vector[] vectors = null;
397 |
398 | while(iterator <= maxDepth){
399 | ArrayList tempVectors = new ArrayList<>();
400 |
401 | for (double yV = -(filterSize / 2); yV <= (filterSize / 2); yV += increment){
402 | for (double xV = -(filterSize / 2); xV <= (filterSize / 2); xV += increment){
403 | tempVectors.add(getLocation(x + xV, y + yV, view.camera));
404 | }
405 | }
406 |
407 | vectors = tempVectors.toArray(new Vector[0]);
408 |
409 | Colour[] colourArr = new Colour[vectors.length];
410 |
411 | for (int i = 0; i < vectors.length; i++){
412 | Vector tempVector = vectors[i];
413 | colourArr[i] = trace(
414 | new Ray() {{
415 | begin = view.camera.position;
416 | direction = tempVector;
417 | }},
418 | view,
419 | 0
420 | );
421 | }
422 |
423 | double averageChange = 0.0;
424 |
425 | boolean wasSet = false;
426 |
427 | for(int i = 0; i < colourArr.length; i++){
428 | for (int j = 0; i < colourArr.length; i++){
429 | if(!wasSet){
430 | averageChange = (((double)colourArr[i].R + (double)colourArr[i].G + (double)colourArr[i].B) / 3.0) - ((double)colourArr[j].R + (double)colourArr[j].G + (double)colourArr[j].B) / 3.0;
431 | wasSet = true;
432 | }
433 | else if(i != j){
434 | averageChange = (((((double)colourArr[i].R + (double)colourArr[i].G + (double)colourArr[i].B) / 3.0) - ((double)colourArr[j].R + (double)colourArr[j].G + (double)colourArr[j].B) / 3.0) + averageChange) / 2.0;
435 | }
436 | }
437 | }
438 |
439 | if (averageChange < 0.1 && averageChange > -0.1){
440 | break;
441 | }
442 | else{
443 | iterator *= 2;
444 | increment /= iterator;
445 | }
446 | }
447 |
448 | for (int i = 0; i < vectors.length; i++){
449 | Vector tempVector = vectors[i];
450 |
451 | if (i == 0){
452 | tempAvgColour = trace(
453 | new Ray() {{
454 | begin = view.camera.position;
455 | direction = tempVector;
456 | }},
457 | view,
458 | 0
459 | );
460 | }
461 | else{
462 | tempAvgColour = Colour.average(tempAvgColour, trace(
463 | new Ray() {{
464 | begin = view.camera.position;
465 | direction = tempVector;
466 | }},
467 | view, 0
468 | ));
469 | }
470 | }
471 |
472 | image.setRGB(x, y, tempAvgColour.toColour().getRGB());
473 | }
474 |
475 | rayTraceRender.setImage(image);
476 | }
477 |
478 | return image;
479 | }
480 |
481 | BufferedImage renderStochasticSample(View view, int depth, double filterSize)
482 | {
483 | final BufferedImage image = new BufferedImage( bmpWidth, bmpHeight, BufferedImage.TYPE_INT_RGB );
484 |
485 | double increment = filterSize / (double)depth;
486 |
487 | for (int y = 0; y < bmpHeight; y++)
488 | {
489 | for (int x = 0; x < bmpWidth; x++)
490 | {
491 | ArrayList tempVectors = new ArrayList<>();
492 | Vector[] vectors = null;
493 |
494 | for (double yV = -(filterSize / 2); yV <= (filterSize / 2); yV += increment){
495 | for (double xV = -(filterSize / 2); xV <= (filterSize / 2); xV += increment){
496 | double randX = Math.random() * increment * (Math.random() < 0.5 ? -1 : 1) + xV;
497 | double randY = Math.random() * increment * (Math.random() < 0.5 ? -1 : 1) + yV;
498 |
499 | tempVectors.add(getLocation(x + randX, y + randY, view.camera));
500 | }
501 | }
502 |
503 | vectors = tempVectors.toArray(new Vector[0]);
504 |
505 | Colour colour = null;
506 |
507 | for (int i = 0; i < vectors.length; i++){
508 | Vector tempVector = vectors[i];
509 |
510 | if (i == 0){
511 | colour = trace(
512 | new Ray() {{
513 | begin = view.camera.position;
514 | direction = tempVector;
515 | }},
516 | view,
517 | 0
518 | );
519 | }
520 | else{
521 | colour = Colour.average(colour, trace(
522 | new Ray() {{
523 | begin = view.camera.position;
524 | direction = tempVector;
525 | }},
526 | view, 0
527 | ));
528 | }
529 | }
530 |
531 | image.setRGB(x, y, colour.toColour().getRGB());
532 | }
533 |
534 | rayTraceRender.setImage(image);
535 | }
536 |
537 | return image;
538 | }
539 | }
--------------------------------------------------------------------------------
/src/Render.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | import java.awt.image.BufferedImage;
8 | import javafx.embed.swing.SwingFXUtils;
9 | import javafx.scene.image.Image;
10 |
11 | /**
12 | *
13 | * @author Rollie
14 | */
15 |
16 | public class Render {
17 | public static Image render(int x, int y, View view){
18 | RayTracer rayTracer = new RayTracer(x, y);
19 | BufferedImage temp = rayTracer.render(view);
20 | Image image = SwingFXUtils.toFXImage(temp, null);
21 |
22 | //System.out.println("Standard render complete.");
23 |
24 | return image;
25 | }
26 |
27 | public static Image renderPreview(int x, int y, View view, int accuracy){
28 | RayTracer rayTracer = new RayTracer(x, y);
29 | BufferedImage temp = rayTracer.renderPreview(view, accuracy);
30 | Image image = SwingFXUtils.toFXImage(temp, null);
31 |
32 | //System.out.println("Render preview complete.");
33 |
34 | return image;
35 | }
36 |
37 | public static Image renderSuperSample(int x, int y, View view, int depth, double filterSize){
38 | RayTracer rayTracer = new RayTracer(x, y);
39 | BufferedImage temp = rayTracer.renderSuperSample(view, depth, filterSize);
40 | Image image = SwingFXUtils.toFXImage(temp, null);
41 |
42 | //System.out.println("Super sampled render complete.");
43 |
44 | return image;
45 | }
46 |
47 | public static Image renderAdaptiveSample(int x, int y, View view, int depth, double filterSize){
48 | RayTracer rayTracer = new RayTracer(x, y);
49 | BufferedImage temp = rayTracer.renderAdaptiveSample(view, depth, filterSize);
50 | Image image = SwingFXUtils.toFXImage(temp, null);
51 |
52 | //System.out.println("Adaptive sampled render complete.");
53 |
54 | return image;
55 | }
56 |
57 | public static Image renderStochasticSample(int x, int y, View view, int depth, double filterSize){
58 | RayTracer rayTracer = new RayTracer(x, y);
59 | BufferedImage temp = rayTracer.renderStochasticSample(view, depth, filterSize);
60 | Image image = SwingFXUtils.toFXImage(temp, null);
61 |
62 | //System.out.println("Stochastic sampled render complete.");
63 |
64 | return image;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Sphere.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public class Sphere extends AbsObject
13 | {
14 | public double radius;
15 | public Vector objectPosition;
16 |
17 | @Override
18 | public Vector normal(Vector position)
19 | {
20 | return Vector.normal(Vector.subtract(position, objectPosition));
21 | }
22 |
23 | @Override
24 | public Intersect intersect(Ray _ray)
25 | {
26 | Vector centerOrigin = Vector.subtract(objectPosition, _ray.begin);
27 |
28 | double _vectorD = Vector.dotProduct(centerOrigin, _ray.direction);
29 | double _distance;
30 | double tempVal;
31 |
32 | if (_vectorD >= 0){
33 | tempVal = Math.pow(radius, 2) - (Vector.dotProduct(centerOrigin, centerOrigin) - Math.pow(_vectorD, 2));
34 | _distance = tempVal < 0 ? 0 : _vectorD - Math.sqrt(tempVal);
35 |
36 | if (_distance == 0){
37 | return null;
38 | }
39 | else{
40 | Sphere sphere = this;
41 |
42 | return new Intersect(){{
43 | object = sphere;
44 | ray = _ray;
45 | distance = _distance;
46 | }};
47 | }
48 | }
49 | else{
50 | _distance = 0;
51 |
52 | return null;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Vector.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | /**
8 | *
9 | * @author Rollie
10 | */
11 |
12 | public class Vector {
13 | public double X;
14 | public double Y;
15 | public double Z;
16 |
17 | public Vector(double x, double y, double z)
18 | {
19 | X = x; Y = y; Z = z;
20 | }
21 |
22 | public static Vector create(double x, double y, double z)
23 | {
24 | return new Vector(x, y, z);
25 | }
26 |
27 | public static Vector normal(Vector _vector)
28 | {
29 | double magn = magn(_vector);
30 | double mult = magn == 0 ? Double.POSITIVE_INFINITY : 1 / magn;
31 |
32 | return multiply(mult, _vector);
33 | }
34 |
35 | public static boolean isEqual(Vector _vectorO, Vector _vectorT)
36 | {
37 | return (_vectorO.X == _vectorT.X) && (_vectorO.Y == _vectorT.Y) && (_vectorO.Z == _vectorT.Z);
38 | }
39 |
40 | public static Vector multiply(double k, Vector _vector)
41 | {
42 | return new Vector((_vector.X * k), (_vector.Y * k), (_vector.Z * k));
43 | }
44 |
45 | public static Vector multiply(Vector _vectorO, Vector _vectorT)
46 | {
47 | return new Vector((_vectorO.X * _vectorT.Y), (_vectorO.Y * _vectorT.Y), (_vectorO.Z * _vectorT.Z));
48 | }
49 |
50 | public static Vector multiply(double k, double i)
51 | {
52 | return new Vector((k * i), (k * i), (k * i));
53 | }
54 |
55 | public static Vector subtract(Vector _vectorO, Vector _vectorT)
56 | {
57 | return new Vector(_vectorO.X - _vectorT.X, _vectorO.Y - _vectorT.Y, _vectorO.Z - _vectorT.Z);
58 | }
59 |
60 | public static Vector add(Vector _vectorO, Vector _vectorT)
61 | {
62 | return new Vector(_vectorO.X + _vectorT.X, _vectorO.Y + _vectorT.Y, _vectorO.Z + _vectorT.Z);
63 | }
64 |
65 | public static double dotProduct(Vector _vectorO, Vector _vectorT)
66 | {
67 | return (_vectorO.X * _vectorT.X) + (_vectorO.Y * _vectorT.Y) + (_vectorO.Z * _vectorT.Z);
68 | }
69 |
70 | public static Vector crossP(Vector _vectorO, Vector _vectorT)
71 | {
72 | return new Vector(((_vectorO.Y * _vectorT.Z) - (_vectorO.Z * _vectorT.Y)), ((_vectorO.Z * _vectorT.X) - (_vectorO.X * _vectorT.Z)), ((_vectorO.X * _vectorT.Y) - (_vectorO.Y * _vectorT.X)));
73 | }
74 |
75 | public static double magn(Vector _vector)
76 | {
77 | return Math.sqrt(dotProduct(_vector, _vector));
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/View.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | import java.util.Arrays;
8 |
9 | /**
10 | *
11 | * @author Rollie
12 | */
13 |
14 | abstract class View {
15 | public AbsObject[] objects;
16 | public Camera camera;
17 | public LightSource[] lightSource;
18 |
19 | public Iterable intersect(Ray ray){
20 | Iterable temp;
21 | Intersect[] tempL = new Intersect[objects.length];
22 |
23 | for (int i = 0; i < tempL.length; i++){
24 | tempL[i] = objects[i].intersect(ray);
25 | }
26 |
27 | temp = Arrays.asList(tempL);
28 |
29 | return temp;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/rayTraceRender.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 |
7 | import javafx.application.Application;
8 | import javafx.event.ActionEvent;
9 | import javafx.scene.Scene;
10 | import javafx.scene.control.Button;
11 | import javafx.stage.Stage;
12 | import java.awt.image.BufferedImage;
13 | import java.util.ArrayList;
14 | import java.util.Arrays;
15 | import javafx.collections.FXCollections;
16 | import javafx.collections.ObservableList;
17 | import javafx.scene.image.Image;
18 | import javafx.scene.image.ImageView;
19 | import javafx.embed.swing.SwingFXUtils;
20 | import javafx.geometry.Insets;
21 | import javafx.scene.control.Alert;
22 | import javafx.scene.control.CheckBox;
23 | import javafx.scene.control.ComboBox;
24 | import javafx.scene.control.ListView;
25 | import javafx.scene.layout.GridPane;
26 | import javafx.scene.control.Label;
27 | import javafx.scene.control.TextField;
28 | import javafx.scene.layout.HBox;
29 | import javafx.scene.layout.VBox;
30 | import javafx.stage.Modality;
31 |
32 | /**
33 | *
34 | * @author Rollie
35 | */
36 |
37 | public class rayTraceRender extends Application {
38 | static ImageView imageView = new ImageView();
39 | boolean isFloorOn = true;
40 | boolean antialiasing = false;
41 | int antialiasType = 1;//init supersampling
42 | int objectIterator = 0;
43 | int lightIterator = 0;
44 | int materialIterator = 0;
45 | int antialiasingDepth = 2;
46 | int previewAccuracy = 4;
47 | double antialiasFilterWidth = 1.0;
48 | double tX = 0, tY = 1, tZ = 0, pX = 5, pY = 5, pZ = 5;
49 | Alert alert = new Alert(Alert.AlertType.INFORMATION);
50 |
51 | View view;
52 | View materialView;
53 | View lightView;
54 | Floor floor;
55 | Sphere rmFloor;
56 |
57 | ListView objectList = new ListView<>();
58 | ListView lightList = new ListView<>();
59 | ListView materialList = new ListView<>();
60 |
61 | ObservableList objectListItems = FXCollections.observableArrayList();
62 | ObservableList lightListItems = FXCollections.observableArrayList();
63 | ObservableList materialListItems = FXCollections.observableArrayList();
64 |
65 | public rayTraceRender() {
66 | this.floor = new Floor() {{
67 | material = Materials.Floor;
68 | objectPosition = Vector.create(0, 1, 0);
69 | displacement = 0;
70 | name = "Floor";
71 | }};
72 |
73 | this.rmFloor = new Sphere() {{
74 | material = Materials.Floor;
75 | objectPosition = Vector.create(0, -10000, 0);
76 | radius = 0.0000001;
77 | name = "Floor";
78 | }};
79 |
80 | this.view = new View()
81 | {{
82 | objects = new AbsObject[] {
83 | floor,
84 | new Sphere() {{
85 | material = Materials.Glass;
86 | objectPosition = Vector.create(0, 3, 1);
87 | radius = 1.0;
88 | name = "Sphere." + objectIterator;
89 | objectIterator++;
90 | }},
91 | new Sphere() {{
92 | material = Materials.Glass;
93 | objectPosition = Vector.create(4, 3, 1);
94 | radius = 1.5;
95 | name = "Sphere." + objectIterator;
96 | objectIterator++;
97 | }},
98 | new Sphere() {{
99 | material = Materials.Mirror;
100 | objectPosition = Vector.create(0, 1, 0);
101 | radius = 0.5;
102 | name = "Sphere." + objectIterator;
103 | objectIterator++;
104 | }},
105 | new Sphere() {{
106 | material = Materials.Mirror;
107 | objectPosition = Vector.create(-4, 5, 2);
108 | radius = 2.0;
109 | name = "Sphere." + objectIterator;
110 | objectIterator++;
111 | }},
112 | new Sphere() {{
113 | material = Materials.Mirror;
114 | objectPosition = Vector.create(3, 2, 6);
115 | radius = 1.75;
116 | name = "Sphere." + objectIterator;
117 | objectIterator++;
118 | }},
119 | new Sphere() {{
120 | material = Materials.Mirror;
121 | objectPosition = Vector.create(-5, 5, -6);
122 | radius = 4.0;
123 | name = "Sphere." + objectIterator;
124 | objectIterator++;
125 | }}
126 | };
127 | lightSource = new LightSource[] {
128 | new LightSource() {{
129 | color = Colour.create(0.5, 0.3, 0.75);
130 | position = Vector.create(-2, 5, 0);
131 | name = "Light." + lightIterator;
132 | lightIterator++;
133 | }},
134 | new LightSource() {{
135 | color = Colour.create(0.5, 0.5, 0.5);
136 | position = Vector.create(-10, 12, -7.5);
137 | name = "Light." + lightIterator;
138 | lightIterator++;
139 | }},
140 | new LightSource() {{
141 | color = Colour.create(0.5, 0.6, 0.3);
142 | position = Vector.create(-6, 8, 5);
143 | name = "Light." + lightIterator;
144 | lightIterator++;
145 | }},
146 | new LightSource() {{
147 | color = Colour.create(0.5, 0.1, 0.1);
148 | position = Vector.create(4, 2.5, -5);
149 | name = "Light." + lightIterator;
150 | lightIterator++;
151 | }}};
152 | camera = Camera.create(Vector.create(0, 1, 0), Vector.create(5, 5, 5));
153 | }};
154 |
155 | this.materialView = new View(){{
156 | objects = new AbsObject[]{
157 | new Sphere() {{
158 | material = Materials.Mirror;
159 | objectPosition = Vector.create(0, 1, 0);
160 | radius = 1.0;
161 | name = "Sphere";
162 | }},
163 | floor
164 | };
165 | lightSource = new LightSource[] {
166 | new LightSource() {{
167 | color = Colour.create(0.75, 0.75, 0.75);
168 | position = Vector.create(4, 3, 4);
169 | name = "Light";
170 | }},
171 | new LightSource() {{
172 | color = Colour.create(0.75, 0.75, 0.75);
173 | position = Vector.create(4, 3, -4);
174 | name = "Light";
175 | }},
176 | new LightSource() {{
177 | color = Colour.create(0.75, 0.75, 0.75);
178 | position = Vector.create(-4, 3, 4);
179 | name = "Light";
180 | }},
181 | new LightSource() {{
182 | color = Colour.create(0.75, 0.75, 0.75);
183 | position = Vector.create(-4, 3, -4);
184 | name = "Light";
185 | }}
186 | };
187 | camera = Camera.create(Vector.create(0, 1, 0), Vector.create(3, 3, 3), 600, 450);
188 | }};
189 |
190 | this.lightView = new View(){{
191 | objects = new AbsObject[]{
192 | floor
193 | };
194 | lightSource = new LightSource[] {
195 | new LightSource() {{
196 | color = Colour.create(1.0, 1.0, 1.0);
197 | position = Vector.create(0, 1, 0);
198 | name = "Light";
199 | }}
200 | };
201 | camera = Camera.create(Vector.create(0, 1, 0), Vector.create(3, 3, 3), 600, 450);
202 | }};
203 | }
204 |
205 | @Override
206 | public void start(Stage primaryStage) {
207 | alert.setTitle("Rendering previews...");
208 | alert.setHeaderText("Rendering previews for main window, add material window,\nand add light window. Please wait...");
209 | alert.initModality(Modality.NONE);
210 | alert.show();
211 |
212 | Materials.materials = new Material[] {
213 | Materials.Default,
214 | Materials.Floor,
215 | Materials.Mirror,
216 | Materials.Glass
217 | };
218 |
219 | ImageView imageViewLP = new ImageView();
220 | ImageView imageViewMP = new ImageView();
221 |
222 | Label colorLP = new Label("Color");
223 | Label positionLP = new Label("Position");
224 | Label nameLLP = new Label("Name");
225 | Label emptyLP = new Label("");
226 | Label emptyLP2 = new Label("");
227 | Label specularMP = new Label("Specularity");
228 | Label diffusionMP = new Label("Diffusion");
229 | Label reflectionMP = new Label("Reflection");
230 | Label accuracyMP = new Label("Specular Width");
231 | Label nameLMP = new Label("Name");
232 | Label emptyMP = new Label("");
233 | Label emptyMP2 = new Label("");
234 | Label materialOP = new Label("Material");
235 | Label positionOP = new Label("Position");
236 | Label sizeOP = new Label("Size");
237 | Label nameLOP = new Label("Name");
238 | Label objectLOP = new Label("Object");
239 | Label empty = new Label("");
240 | Label targetCP = new Label("Target");
241 | Label positionCP = new Label("Position");
242 | Label rendFlo = new Label("Render Floor");
243 | Label anti = new Label("Antialiasing");
244 | Label previewQ = new Label("Preview Quality");
245 | Label antiType = new Label("Antialiasing Type");
246 | Label antiDepth = new Label("Antialiasing Depth");
247 | Label antiWidth = new Label("Antialiasing Width");
248 | Label emptyLeftL = new Label("");
249 | Label objectLabel = new Label("Objects");
250 | Label lightLabel = new Label("Lights");
251 | Label materialLabel = new Label("Materials");
252 |
253 | Button removeLP = new Button("Delete");
254 | Button saveLP = new Button("Save");
255 | Button renderLP = new Button("Render");
256 | Button removeMP = new Button("Delete");
257 | Button saveMP = new Button("Save");
258 | Button renderMP = new Button("Render");
259 | Button removeOP = new Button("Delete");
260 | Button saveOP = new Button("Save");
261 | Button cancelCP = new Button("Cancel");
262 | Button saveCP = new Button("Save");
263 | Button cancelS = new Button("Cancel");
264 | Button saveS = new Button("Save");
265 | Button render = new Button("Render");
266 | Button preview = new Button("Preview");
267 | Button addMaterial = new Button("Add Material");
268 | Button addObject = new Button("Add Object");
269 | Button addLight = new Button("Add Light");
270 | Button editCamera = new Button("Edit Camera");
271 | Button settings = new Button("Settings");
272 | Button deleteObject = new Button("Delete Object");
273 | Button deleteLight = new Button("Delete Light");
274 | Button deleteMaterial = new Button("Delete Material");
275 |
276 | ComboBox cmbOP = new ComboBox<>();
277 | ComboBox objectsOP = new ComboBox<>();
278 | ComboBox antialiasingType = new ComboBox<>();
279 | ComboBox antialiasingLevel = new ComboBox<>();
280 | ComboBox previewQuality = new ComboBox<>();
281 |
282 | CheckBox renderFloor = new CheckBox();
283 | CheckBox antialias = new CheckBox();
284 |
285 | HBox colorHLP = new HBox(5);
286 | HBox positionHLP = new HBox(5);
287 | HBox butLP = new HBox(5);
288 | HBox specularHMP = new HBox(5);
289 | HBox diffusionHMP = new HBox(5);
290 | HBox butMP = new HBox(5);
291 | HBox posOP = new HBox(5);
292 | HBox butOP = new HBox(5);
293 | HBox tarCP = new HBox(5);
294 | HBox posCP = new HBox(5);
295 | HBox butCP = new HBox(5);
296 | HBox butS = new HBox(5);
297 | HBox hBox = new HBox(5);
298 |
299 | HBox.setMargin(hBox, new Insets(10));
300 |
301 | VBox vBox = new VBox(5);
302 |
303 | TextField nameLP = new TextField();
304 | TextField rLP = new TextField();
305 | TextField gLP = new TextField();
306 | TextField bLP = new TextField();
307 | TextField xLP = new TextField();
308 | TextField yLP = new TextField();
309 | TextField zLP = new TextField();
310 | TextField nameMP = new TextField();
311 | TextField specularRMP = new TextField();
312 | TextField specularGMP = new TextField();
313 | TextField specularBMP = new TextField();
314 | TextField diffusionRMP = new TextField();
315 | TextField diffusionGMP = new TextField();
316 | TextField diffusionBMP = new TextField();
317 | TextField reflectMP = new TextField();
318 | TextField accurMP = new TextField();
319 | TextField nameOP = new TextField();
320 | TextField xOP = new TextField();
321 | TextField yOP = new TextField();
322 | TextField zOP = new TextField();
323 | TextField radiusOP = new TextField();
324 | TextField xCP = new TextField();
325 | TextField yCP = new TextField();
326 | TextField zCP = new TextField();
327 | TextField xCPT = new TextField();
328 | TextField yCPT = new TextField();
329 | TextField zCPT = new TextField();
330 | TextField antialiasWidth = new TextField();
331 |
332 | GridPane addLightGP = new GridPane();
333 | GridPane addMaterialGP = new GridPane();
334 | GridPane addObjectGP = new GridPane();
335 | GridPane editCameraGP = new GridPane();
336 | GridPane settingsGP = new GridPane();
337 | GridPane root = new GridPane();
338 |
339 | GridPane.setConstraints(imageViewLP, 1, 0);
340 | GridPane.setConstraints(emptyLP2, 1, 1);
341 | GridPane.setConstraints(colorLP, 0, 2);
342 | GridPane.setConstraints(positionLP, 0, 3);
343 | GridPane.setConstraints(nameLLP, 0, 4);
344 | GridPane.setConstraints(colorHLP, 1, 2);
345 | GridPane.setConstraints(positionHLP, 1, 3);
346 | GridPane.setConstraints(nameLP, 1, 4);
347 | GridPane.setConstraints(emptyLP, 1, 5);
348 | GridPane.setConstraints(butLP, 1, 6);
349 | GridPane.setConstraints(imageViewMP, 1, 0);
350 | GridPane.setConstraints(emptyMP2, 1, 1);
351 | GridPane.setConstraints(specularMP, 0, 2);
352 | GridPane.setConstraints(diffusionMP, 0, 3);
353 | GridPane.setConstraints(reflectionMP, 0, 4);
354 | GridPane.setConstraints(specularHMP, 1, 2);
355 | GridPane.setConstraints(diffusionHMP, 1, 3);
356 | GridPane.setConstraints(reflectMP, 1, 4);
357 | GridPane.setConstraints(accuracyMP, 0, 5);
358 | GridPane.setConstraints(accurMP, 1, 5);
359 | GridPane.setConstraints(nameLMP, 0, 6);
360 | GridPane.setConstraints(nameMP, 1, 6);
361 | GridPane.setConstraints(emptyMP, 1, 7);
362 | GridPane.setConstraints(butMP, 1, 8);
363 | GridPane.setConstraints(materialOP, 0, 0);
364 | GridPane.setConstraints(cmbOP, 1, 0);
365 | GridPane.setConstraints(objectsOP, 1, 1);
366 | GridPane.setConstraints(objectLOP, 0, 1);
367 | GridPane.setConstraints(positionOP, 0, 2);
368 | GridPane.setConstraints(sizeOP, 0, 3);
369 | GridPane.setConstraints(posOP, 1, 2);
370 | GridPane.setConstraints(radiusOP, 1, 3);
371 | GridPane.setConstraints(nameLOP, 0, 4);
372 | GridPane.setConstraints(nameOP, 1, 4);
373 | GridPane.setConstraints(empty, 1, 5);
374 | GridPane.setConstraints(butOP, 1, 6);
375 | GridPane.setConstraints(targetCP, 0, 0);
376 | GridPane.setConstraints(tarCP, 1, 0);
377 | GridPane.setConstraints(positionCP, 0, 1);
378 | GridPane.setConstraints(posCP, 1, 1);
379 | GridPane.setConstraints(butCP, 1, 2);
380 | GridPane.setConstraints(rendFlo, 0, 0);
381 | GridPane.setConstraints(renderFloor, 1, 0);
382 | GridPane.setConstraints(anti, 0, 1);
383 | GridPane.setConstraints(antialias, 1, 1);
384 | GridPane.setConstraints(previewQ, 0, 2);
385 | GridPane.setConstraints(previewQuality, 1, 2);
386 | GridPane.setConstraints(antiWidth, 0, 3);
387 | GridPane.setConstraints(antialiasWidth, 1, 3);
388 | GridPane.setConstraints(antiType, 0, 4);
389 | GridPane.setConstraints(antialiasingType, 1, 4);
390 | GridPane.setConstraints(antiDepth, 0, 5);
391 | GridPane.setConstraints(antialiasingLevel, 1, 5);
392 | GridPane.setConstraints(butS, 1, 6);
393 | GridPane.setConstraints(imageView, 0, 0);
394 | GridPane.setConstraints(hBox, 0, 1);
395 | GridPane.setConstraints(vBox, 1, 0);
396 |
397 | addLightGP.setPadding(new Insets(10));
398 | colorLP.setPadding(new Insets(10));
399 | positionLP.setPadding(new Insets(10));
400 | nameLLP.setPadding(new Insets(10));
401 | nameLP.setPadding(new Insets(10));
402 | colorHLP.setPadding(new Insets(5, 0, 0, 0));
403 | positionHLP.setPadding(new Insets(5, 0, 0, 0));
404 | removeLP.setPadding(new Insets(10, 82, 10, 82));
405 | saveLP.setPadding(new Insets(10, 82, 10, 82));
406 | renderLP.setPadding(new Insets(10, 82, 10, 82));
407 | addMaterialGP.setPadding(new Insets(10));
408 | specularMP.setPadding(new Insets(10));
409 | diffusionMP.setPadding(new Insets(10));
410 | reflectionMP.setPadding(new Insets(10));
411 | accuracyMP.setPadding(new Insets(10));
412 | nameLMP.setPadding(new Insets(10));
413 | specularHMP.setPadding(new Insets(5, 0, 0, 0));
414 | diffusionHMP.setPadding(new Insets(5, 0, 0, 0));
415 | removeMP.setPadding(new Insets(10, 82, 10, 82));
416 | saveMP.setPadding(new Insets(10, 82, 10, 82));
417 | renderMP.setPadding(new Insets(10, 82, 10, 82));
418 | addObjectGP.setPadding(new Insets(10));
419 | materialOP.setPadding(new Insets(10));
420 | positionOP.setPadding(new Insets(10));
421 | sizeOP.setPadding(new Insets(10));
422 | nameLOP.setPadding(new Insets(10));
423 | objectLOP.setPadding(new Insets(10));
424 | posOP.setPadding(new Insets(5, 0, 0, 0));
425 | removeOP.setPadding(new Insets(10, 98, 10, 98));
426 | saveOP.setPadding(new Insets(10, 98, 10, 98));
427 | editCameraGP.setPadding(new Insets(10));
428 | targetCP.setPadding(new Insets(10));
429 | positionCP.setPadding(new Insets(10));
430 | tarCP.setPadding(new Insets(5, 0, 0, 0));
431 | posCP.setPadding(new Insets(5, 0, 0, 0));
432 | cancelCP.setPadding(new Insets(10, 98, 10, 98));
433 | saveCP.setPadding(new Insets(10, 98, 10, 98));
434 | settingsGP.setPadding(new Insets(10));
435 | rendFlo.setPadding(new Insets(10));
436 | anti.setPadding(new Insets(10));
437 | previewQ.setPadding(new Insets(10));
438 | antiWidth.setPadding(new Insets(10));
439 | antiType.setPadding(new Insets(10));
440 | antiDepth.setPadding(new Insets(10));
441 | cancelS.setPadding(new Insets(10, 30, 10, 30));
442 | saveS.setPadding(new Insets(10, 30, 10, 30));
443 | render.setPadding(new Insets(10, 25, 10, 25));
444 | preview.setPadding(new Insets(10, 25, 10, 25));
445 | addMaterial.setPadding(new Insets(10, 25, 10, 25));
446 | addObject.setPadding(new Insets(10, 25, 10, 25));
447 | addLight.setPadding(new Insets(10, 25, 10, 25));
448 | editCamera.setPadding(new Insets(10, 25, 10, 25));
449 | settings.setPadding(new Insets(10, 25, 10, 25));
450 | hBox.setPadding(new Insets(5));
451 | emptyLeftL.setPadding(new Insets(-10, 0, -10, 0));
452 | objectLabel.setPadding(new Insets(5, 0, 0, 7));
453 | lightLabel.setPadding(new Insets(5, 0, 0, 7));
454 | materialLabel.setPadding(new Insets(5, 0, 0, 7));
455 | deleteObject.setPadding(new Insets(10));
456 | deleteLight.setPadding(new Insets(10));
457 | deleteMaterial.setPadding(new Insets(10));
458 | vBox.setPadding(new Insets(0, 0, 0, 5));
459 |
460 | nameLP.setPromptText("Name");
461 | rLP.setPromptText("R (0 -> 1)");
462 | gLP.setPromptText("G (0 -> 1)");
463 | bLP.setPromptText("B (0 -> 1)");
464 | xLP.setPromptText("X (R)");
465 | yLP.setPromptText("Y (R)");
466 | zLP.setPromptText("Z (R)");
467 | nameMP.setPromptText("Name");
468 | specularRMP.setPromptText("R (0 -> 1)");
469 | specularGMP.setPromptText("G (0 -> 1)");
470 | specularBMP.setPromptText("B (0 -> 1)");
471 | diffusionRMP.setPromptText("R (0 -> 1)");
472 | diffusionGMP.setPromptText("G (0 -> 1)");
473 | diffusionBMP.setPromptText("B (0 -> 1)");
474 | reflectMP.setPromptText("Reflection (0 -> 1)");
475 | accurMP.setPromptText("Accuracy (0 -> N)");
476 | nameOP.setPromptText("Name");
477 | xOP.setPromptText("X");
478 | yOP.setPromptText("Y");
479 | zOP.setPromptText("Z");
480 | radiusOP.setPromptText("Radius (Sphere Only)");
481 | xCP.setPromptText("X");
482 | yCP.setPromptText("Y");
483 | zCP.setPromptText("Z");
484 | xCPT.setPromptText("X");
485 | yCPT.setPromptText("Y");
486 | zCPT.setPromptText("Z");
487 | antialiasWidth.setPromptText("Cubic Filter (0.0 -> R)");
488 |
489 | Scene lightScene = new Scene(addLightGP);
490 | Scene materialScene = new Scene(addMaterialGP);
491 | Scene objectScene = new Scene(addObjectGP);
492 | Scene cameraScene = new Scene(editCameraGP);
493 | Scene settingsScene = new Scene(settingsGP);
494 | Scene scene = new Scene(root, 1010, 850);
495 |
496 | Stage addLightPopup = new Stage();
497 | Stage addMaterialPopup = new Stage();
498 | Stage addObjectPopup = new Stage();
499 | Stage editCameraPopup = new Stage();
500 | Stage settingsPopup = new Stage();
501 |
502 | addLightPopup.setAlwaysOnTop(true);
503 | addMaterialPopup.setAlwaysOnTop(true);
504 | addObjectPopup.setAlwaysOnTop(true);
505 | editCameraPopup.setAlwaysOnTop(true);
506 | settingsPopup.setAlwaysOnTop(true);
507 |
508 | addLightPopup.initModality(Modality.WINDOW_MODAL);
509 | addMaterialPopup.initModality(Modality.WINDOW_MODAL);
510 | addObjectPopup.initModality(Modality.WINDOW_MODAL);
511 | editCameraPopup.initModality(Modality.WINDOW_MODAL);
512 | settingsPopup.initModality(Modality.WINDOW_MODAL);
513 |
514 | colorHLP.getChildren().addAll(rLP, gLP, bLP);
515 | positionHLP.getChildren().addAll(xLP, yLP, zLP);
516 | butLP.getChildren().addAll(removeLP, saveLP, renderLP);
517 | addLightGP.getChildren().addAll(imageViewLP, emptyLP2, colorLP, positionLP, nameLLP, colorHLP, positionHLP, nameLP, emptyLP, butLP);
518 | specularHMP.getChildren().addAll(specularRMP, specularGMP, specularBMP);
519 | diffusionHMP.getChildren().addAll(diffusionRMP, diffusionGMP, diffusionBMP);
520 | butMP.getChildren().addAll(removeMP, saveMP, renderMP);
521 | addMaterialGP.getChildren().addAll(imageViewMP, specularMP, diffusionMP, specularHMP, diffusionHMP, reflectionMP, butMP, emptyMP, reflectMP, nameLMP, nameMP, accuracyMP, accurMP);
522 | posOP.getChildren().addAll(xOP, yOP, zOP);
523 | butOP.getChildren().addAll(removeOP, saveOP);
524 | addObjectGP.getChildren().addAll(materialOP, objectsOP, objectLOP, positionOP, sizeOP, butOP, empty, cmbOP, posOP, radiusOP, nameLOP, nameOP);
525 | tarCP.getChildren().addAll(xCPT, yCPT, zCPT);
526 | posCP.getChildren().addAll(xCP, yCP, zCP);
527 | butCP.getChildren().addAll(cancelCP, saveCP);
528 | editCameraGP.getChildren().addAll(targetCP, tarCP, positionCP, posCP, butCP);
529 | butS.getChildren().addAll(cancelS, saveS);
530 | settingsGP.getChildren().addAll(rendFlo, anti, previewQ, previewQuality, renderFloor, antialias, antiType, antialiasingType, antiDepth, antialiasingLevel, butS, antiWidth, antialiasWidth);
531 | hBox.getChildren().addAll(render, preview, addMaterial, addObject, addLight, editCamera, settings);
532 | vBox.getChildren().addAll(emptyLeftL, objectLabel, deleteObject, objectList, lightLabel, deleteLight, lightList, materialLabel, deleteMaterial, materialList);
533 | root.getChildren().addAll(imageView, hBox, vBox);
534 |
535 | addLightPopup.setTitle("Add Light");
536 | addMaterialPopup.setTitle("Add Material");
537 | addObjectPopup.setTitle("Add Object");
538 | editCameraPopup.setTitle("Edit Camera");
539 | settingsPopup.setTitle("Settings");
540 | primaryStage.setTitle("Steven Rowland(rowland005) Ray Tracer");
541 |
542 | addLightPopup.setScene(lightScene);
543 | addMaterialPopup.setScene(materialScene);
544 | addObjectPopup.setScene(objectScene);
545 | editCameraPopup.setScene(cameraScene);
546 | settingsPopup.setScene(settingsScene);
547 | primaryStage.setScene(scene);
548 |
549 | xCP.setText(String.valueOf(pX));
550 | yCP.setText(String.valueOf(pY));
551 | zCP.setText(String.valueOf(pZ));
552 |
553 | xCPT.setText(String.valueOf(tX));
554 | yCPT.setText(String.valueOf(tY));
555 | zCPT.setText(String.valueOf(tZ));
556 |
557 |
558 | renderFloor.setSelected(true);
559 | antialias.setSelected(false);
560 |
561 | antialiasingType.getItems().add("Super Sampling");
562 | antialiasingType.getItems().add("Adaptive Sampling");
563 | antialiasingType.getItems().add("Stochastic Sampling");
564 | antialiasingType.setValue("Super Sampling");
565 |
566 | antialiasingLevel.getItems().add("2");
567 | antialiasingLevel.getItems().add("4");
568 | antialiasingLevel.getItems().add("8");
569 | antialiasingLevel.getItems().add("16");
570 | antialiasingLevel.getItems().add("32");
571 | antialiasingLevel.setValue("2");
572 |
573 | previewQuality.getItems().add("50%");
574 | previewQuality.getItems().add("25%");
575 | previewQuality.getItems().add("12.5%");
576 | previewQuality.getItems().add("6.25%");
577 | previewQuality.getItems().add("3.125%");
578 | previewQuality.setValue("25%");
579 |
580 | objectsOP.getItems().add("Sphere");
581 | objectsOP.setValue("Sphere");
582 |
583 | for (AbsObject i : view.objects){
584 | if(!"Floor".equals(i.name)){
585 | objectListItems.add(i.name);
586 | }
587 | }
588 |
589 | for (LightSource i : view.lightSource){
590 | lightListItems.add(i.name);
591 | }
592 |
593 | for (Material i : Materials.materials){
594 | materialListItems.add(i.name);
595 | }
596 |
597 | for(Material i : Materials.materials){
598 | cmbOP.getItems().add(i.name);
599 | }
600 |
601 | antialiasingType.setPrefWidth(185);
602 | antialiasingLevel.setPrefWidth(185);
603 | previewQuality.setPrefWidth(185);
604 | objectList.setItems(objectListItems);
605 | objectList.setPrefWidth(200);
606 | objectList.setPrefHeight(250);
607 | lightList.setItems(lightListItems);
608 | lightList.setPrefWidth(200);
609 | lightList.setPrefHeight(250);
610 | materialList.setItems(materialListItems);
611 | materialList.setPrefWidth(200);
612 | materialList.setPrefHeight(250);
613 | objectsOP.setPrefWidth(457);
614 | cmbOP.setPrefWidth(457);
615 |
616 | imageView.setImage(Render.renderPreview(800, 800, view, previewAccuracy));
617 | imageViewMP.setImage(Render.render(600, 450, materialView));
618 | imageViewLP.setImage(Render.render(600, 450, lightView));
619 |
620 |
621 | renderLP.setOnAction((ActionEvent event) -> {
622 | double r, g, b;
623 |
624 | try{
625 | r = Double.parseDouble(rLP.getText());
626 | g = Double.parseDouble(gLP.getText());
627 | b = Double.parseDouble(bLP.getText());
628 |
629 | LightSource lightTemp = new LightSource(){{
630 | name = "Temp";
631 | color = Colour.create(r, g, b);
632 | position = Vector.create(0, 1, 0);
633 | }};
634 |
635 | lightView.lightSource[0] = lightTemp;
636 | }
637 | catch (Exception ex){
638 |
639 | }
640 |
641 | imageViewLP.setImage(Render.render(600, 450, lightView));
642 | });
643 |
644 | removeLP.setOnAction((ActionEvent event) -> {
645 | addLightPopup.hide();
646 | rLP.setText("");
647 | gLP.setText("");
648 | bLP.setText("");
649 |
650 | xLP.setText("");
651 | yLP.setText("");
652 | zLP.setText("");
653 |
654 | nameLP.setText("");
655 | });
656 |
657 | saveLP.setOnAction((ActionEvent event) -> {
658 | String tempName;
659 | double r, g, b, x, y, z;
660 |
661 | try{
662 | if ("".equals(nameLP.getText())){
663 | tempName = "Light." + lightIterator;
664 | lightIterator++;
665 | }
666 | else{
667 | tempName = nameLP.getText() + "." + lightIterator;
668 | lightIterator++;
669 | }
670 |
671 | r = Double.parseDouble(rLP.getText());
672 | g = Double.parseDouble(gLP.getText());
673 | b = Double.parseDouble(bLP.getText());
674 |
675 | x = Double.parseDouble(xLP.getText());
676 | y = Double.parseDouble(yLP.getText());
677 | z = Double.parseDouble(zLP.getText());
678 |
679 | LightSource lightTemp = new LightSource(){{
680 | name = "Temp";
681 | color = Colour.create(r, g, b);
682 | position = Vector.create(x, y, z);
683 | }};
684 |
685 | addLight(lightTemp, tempName);
686 |
687 | rLP.setText("");
688 | gLP.setText("");
689 | bLP.setText("");
690 |
691 | xLP.setText("");
692 | yLP.setText("");
693 | zLP.setText("");
694 |
695 | nameLP.setText("");
696 | }
697 | catch (Exception ex){
698 |
699 | }
700 |
701 | addLightPopup.hide();
702 | });
703 |
704 | renderMP.setOnAction((ActionEvent event) -> {
705 | double spr, spg, spb, dir, dig, dib, ref;
706 | int acc;
707 |
708 | try{
709 | spr = Double.parseDouble(specularRMP.getText());
710 | spg = Double.parseDouble(specularGMP.getText());
711 | spb = Double.parseDouble(specularBMP.getText());
712 |
713 | dir = Double.parseDouble(diffusionRMP.getText());
714 | dig = Double.parseDouble(diffusionGMP.getText());
715 | dib = Double.parseDouble(diffusionBMP.getText());
716 |
717 | ref = Double.parseDouble(reflectMP.getText());
718 | acc = Integer.parseInt(accurMP.getText());
719 |
720 | Material materialTemp = new Material(){{
721 | name = "Temp";
722 | reflect = (Vector position) -> ref;
723 | diffuse = (Vector position) -> Colour.create(dir, dig, dib);
724 | specular = (Vector position) -> Colour.create(spr, spg, spb);
725 | specular = (Vector position) -> Colour.create(0.5, 0.5, 0.5);
726 | specularWidth = 15;
727 | specularWidth = acc;
728 | }};
729 |
730 | materialView.objects[0].material = materialTemp;
731 | }
732 | catch (Exception ex){
733 |
734 | }
735 |
736 | imageViewMP.setImage(Render.render(600, 450, materialView));
737 | });
738 |
739 | removeMP.setOnAction((ActionEvent event) -> {
740 | addMaterialPopup.hide();
741 | specularRMP.setText("");
742 | specularGMP.setText("");
743 | specularBMP.setText("");
744 |
745 | diffusionRMP.setText("");
746 | diffusionGMP.setText("");
747 | diffusionBMP.setText("");
748 |
749 | reflectMP.setText("");
750 | accurMP.setText("");
751 | });
752 |
753 | saveMP.setOnAction((ActionEvent event) -> {
754 | String tempName;
755 | double spr, spg, spb, dir, dig, dib, ref;
756 | int acc;
757 |
758 | try{
759 | if ("".equals(nameMP.getText())){
760 | tempName = "Material." + materialIterator;
761 | materialIterator++;
762 | }
763 | else{
764 | tempName = nameMP.getText() + "." + materialIterator;
765 | materialIterator++;
766 | }
767 |
768 | spr = Double.parseDouble(specularRMP.getText());
769 | spg = Double.parseDouble(specularGMP.getText());
770 | spb = Double.parseDouble(specularBMP.getText());
771 |
772 | dir = Double.parseDouble(diffusionRMP.getText());
773 | dig = Double.parseDouble(diffusionGMP.getText());
774 | dib = Double.parseDouble(diffusionBMP.getText());
775 |
776 | ref = Double.parseDouble(reflectMP.getText());
777 | acc = Integer.parseInt(accurMP.getText());
778 |
779 | Material materialTemp = new Material(){{
780 | name = tempName;
781 | reflect = (Vector position) -> ref;
782 | diffuse = (Vector position) -> Colour.create(dir, dig, dib);
783 | specular = (Vector position) -> Colour.create(spr, spg, spb);
784 | specularWidth = acc;
785 | }};
786 |
787 | materialView.objects[0].material = materialTemp;
788 |
789 | addMaterial(materialTemp, tempName);
790 |
791 | specularRMP.setText("");
792 | specularGMP.setText("");
793 | specularBMP.setText("");
794 |
795 | diffusionRMP.setText("");
796 | diffusionGMP.setText("");
797 | diffusionBMP.setText("");
798 |
799 | reflectMP.setText("");
800 | accurMP.setText("");
801 | }
802 | catch (Exception ex){
803 |
804 | }
805 |
806 | addMaterialPopup.hide();
807 | });
808 |
809 | removeOP.setOnAction((ActionEvent event) -> {
810 | addObjectPopup.hide();
811 | xOP.setText("");
812 | yOP.setText("");
813 | zOP.setText("");
814 | radiusOP.setText("");
815 | });
816 |
817 | saveOP.setOnAction((ActionEvent event) -> {
818 | Material material = new Material();
819 | String name;
820 |
821 | String object = objectsOP.getValue();
822 |
823 | try{
824 | if(null != object)switch (object) {
825 | case "Sphere":
826 | //do nothing yet
827 | break;
828 | default:
829 | //set sphere
830 | break;
831 | }
832 |
833 | if ("".equals(cmbOP.getValue())){
834 | material = Materials.Default;
835 | }
836 | else{
837 | for(Material i : Materials.materials){
838 | if (i.name.equals(cmbOP.getValue())){
839 | material = i;
840 | }
841 | }
842 | }
843 |
844 | if ("".equals(nameOP.getText())){
845 | name = "Object." + objectIterator;
846 | objectIterator++;
847 | }
848 | else{
849 | name = nameOP.getText() + "." + objectIterator;
850 | objectIterator++;
851 | }
852 |
853 | name = name + "." + objectIterator;
854 | objectIterator++;
855 |
856 | addSphere(
857 | name,
858 | Double.parseDouble(xOP.getText()),
859 | Double.parseDouble(yOP.getText()),
860 | Double.parseDouble(zOP.getText()),
861 | Double.parseDouble(radiusOP.getText()),
862 | material
863 | );
864 | }
865 | catch(Exception ex){
866 |
867 | }
868 |
869 | addObjectPopup.hide();
870 | xOP.setText("");
871 | yOP.setText("");
872 | zOP.setText("");
873 | radiusOP.setText("");
874 | });
875 |
876 | cancelCP.setOnAction((ActionEvent event) -> {
877 | editCameraPopup.hide();
878 | });
879 |
880 | saveCP.setOnAction((ActionEvent event) -> {
881 | try{
882 |
883 | tX = Double.parseDouble(xCPT.getText());
884 | tY = Double.parseDouble(yCPT.getText());
885 | tZ = Double.parseDouble(zCPT.getText());
886 |
887 | pX = Double.parseDouble(xCP.getText());
888 | pY = Double.parseDouble(yCP.getText());
889 | pZ = Double.parseDouble(zCP.getText());
890 |
891 | view.camera = Camera.create(Vector.create(tX, tY, tZ), Vector.create(pX, pY, pZ));
892 | }
893 | catch(Exception ex){}
894 |
895 | editCameraPopup.hide();
896 | });
897 |
898 | cancelS.setOnAction((ActionEvent event) -> {
899 | settingsPopup.hide();
900 | });
901 |
902 | saveS.setOnAction((ActionEvent event) -> {
903 | try{
904 | isFloorOn = renderFloor.isSelected();
905 |
906 | if (!isFloorOn){
907 | view.objects[0] = rmFloor;
908 | }
909 | else{
910 | view.objects[0] = floor;
911 | }
912 |
913 | antialiasing = antialias.isSelected();
914 |
915 | if (!"".equals(antialiasingLevel.getValue())){
916 | antialiasingDepth = Integer.parseInt(antialiasingLevel.getValue());
917 | }
918 |
919 | String previewQual = previewQuality.getValue();
920 |
921 | if(null != previewQual)switch (previewQual) {
922 | case "50%":
923 | previewAccuracy = 2;
924 | break;
925 | case "25%":
926 | previewAccuracy = 4;
927 | break;
928 | case "12.5%":
929 | previewAccuracy = 8;
930 | break;
931 | case "6.25%":
932 | previewAccuracy = 16;
933 | break;
934 | case "3.125%":
935 | previewAccuracy = 32;
936 | break;
937 | default:
938 | previewAccuracy = 4;
939 | break;
940 | }
941 |
942 | String antiSwitchType = antialiasingType.getValue();
943 |
944 | if(null != antiSwitchType)switch (antiSwitchType) {
945 | case "Super Sampling":
946 | antialiasType = 1;
947 | break;
948 | case "Adaptive Sampling":
949 | antialiasType = 2;
950 | break;
951 | case "Stochastic Sampling":
952 | antialiasType = 3;
953 | break;
954 | default:
955 | previewAccuracy = 1;
956 | break;
957 | }
958 |
959 | if ("".equals(antialiasWidth.getText())){
960 | antialiasFilterWidth = 1.0;
961 | }
962 | else{
963 | antialiasFilterWidth = Double.parseDouble(antialiasWidth.getText());
964 |
965 | antialiasFilterWidth = Math.abs(antialiasFilterWidth);
966 | }
967 | }
968 | catch(Exception ex){}
969 |
970 | settingsPopup.hide();
971 | });
972 |
973 | render.setOnAction((ActionEvent) -> {
974 | alert.setTitle("Rendering...");
975 |
976 | if (antialiasing){
977 | //imageView.setImage(renderPreview(800, 800, view, previewAccuracy));
978 |
979 | switch(antialiasType){
980 | case 1:
981 | alert.setHeaderText("Rendering camera view with Super Sampling. Please wait...");
982 | alert.show();
983 |
984 | imageView.setImage(Render.renderSuperSample(800, 800, view, antialiasingDepth, antialiasFilterWidth));
985 | break;
986 | case 2:
987 | alert.setHeaderText("Rendering camera view with Adaptive Sampling. Please wait...");
988 | alert.show();
989 |
990 | imageView.setImage(Render.renderAdaptiveSample(800, 800, view, antialiasingDepth, antialiasFilterWidth));
991 | break;
992 | case 3:
993 | alert.setHeaderText("Rendering camera view with Stochastic(Monte Carlo) Sampling. Please wait...");
994 | alert.show();
995 |
996 | imageView.setImage(Render.renderStochasticSample(800, 800, view, antialiasingDepth, antialiasFilterWidth));
997 | break;
998 | }
999 | }
1000 | else{
1001 | //imageView.setImage(renderPreview(800, 800, view, previewAccuracy));
1002 |
1003 | alert.setHeaderText("Rendering camera view. Please wait...");
1004 | alert.show();
1005 |
1006 | imageView.setImage(Render.render(800, 800, view));
1007 | }
1008 |
1009 | alert.hide();
1010 | });
1011 |
1012 | preview.setOnAction((ActionEvent) -> {
1013 | alert.setTitle("Rendering...");
1014 | alert.setHeaderText("Rendering preview. Please wait...");
1015 | alert.show();
1016 |
1017 | imageView.setImage(Render.renderPreview(800, 800, view, previewAccuracy));
1018 |
1019 | alert.hide();
1020 | });
1021 |
1022 | addMaterial.setOnAction((ActionEvent event) -> {
1023 | materialView.objects[0].material = new Material(){{
1024 | name = "Mirror";
1025 | reflect = (Vector position) -> 1.0;
1026 | diffuse = (Vector position) -> Colour.create(1.0, 1.0, 1.0);
1027 | specular = (Vector position) -> Colour.create(0.5, 0.5, 0.5);
1028 | specularWidth = 100;
1029 | }};
1030 |
1031 | addMaterialPopup.show();
1032 | });
1033 |
1034 | addObject.setOnAction((ActionEvent event) -> {
1035 | cmbOP.getItems().clear();
1036 |
1037 | for(Material i : Materials.materials){
1038 | cmbOP.getItems().add(i.name);
1039 | }
1040 |
1041 | addObjectPopup.show();
1042 | });
1043 |
1044 | addLight.setOnAction((ActionEvent) -> {
1045 | addLightPopup.show();
1046 | });
1047 |
1048 | editCamera.setOnAction((ActionEvent) -> {
1049 | editCameraPopup.show();
1050 | });
1051 |
1052 | settings.setOnAction((ActionEvent) -> {
1053 | settingsPopup.show();
1054 | });
1055 |
1056 | deleteObject.setOnAction((ActionEvent) -> {
1057 | String temp = objectList.getSelectionModel().getSelectedItem();
1058 |
1059 | if(temp != null){
1060 | for (AbsObject object : view.objects) {
1061 | if (temp.equals(object.name)) {
1062 | ArrayList tempList = new ArrayList<>(Arrays.asList(view.objects));
1063 | tempList.remove(object);
1064 | view.objects = tempList.toArray(new AbsObject[0]);
1065 | break;
1066 | }
1067 | }
1068 |
1069 | objectListItems.clear();
1070 |
1071 | for (AbsObject i : view.objects){
1072 | if(!"Floor".equals(i.name)){
1073 | objectListItems.add(i.name);
1074 | }
1075 | }
1076 |
1077 | objectList.setItems(objectListItems);
1078 | }
1079 | });
1080 |
1081 | deleteLight.setOnAction((ActionEvent) -> {
1082 | String temp = lightList.getSelectionModel().getSelectedItem();
1083 |
1084 | if(temp != null){
1085 | for (LightSource lightSource : view.lightSource) {
1086 | if (temp.equals(lightSource.name)) {
1087 | ArrayList tempList = new ArrayList<>(Arrays.asList(view.lightSource));
1088 | tempList.remove(lightSource);
1089 | view.lightSource = tempList.toArray(new LightSource[0]);
1090 | break;
1091 | }
1092 | }
1093 |
1094 | lightListItems.clear();
1095 |
1096 | for (LightSource i : view.lightSource){
1097 | lightListItems.add(i.name);
1098 | }
1099 |
1100 | lightList.setItems(lightListItems);
1101 | }
1102 | });
1103 |
1104 | deleteMaterial.setOnAction((ActionEvent) -> {
1105 | String temp = materialList.getSelectionModel().getSelectedItem();
1106 |
1107 | if(temp != null){
1108 | for (Material material : Materials.materials) {
1109 | if (temp.equals(material.name)) {
1110 | ArrayList tempList = new ArrayList<>(Arrays.asList(Materials.materials));
1111 | tempList.remove(material);
1112 | Materials.materials = tempList.toArray(new Material[0]);
1113 | break;
1114 | }
1115 | }
1116 |
1117 | materialListItems.clear();
1118 |
1119 | for (Material i : Materials.materials){
1120 | materialListItems.add(i.name);
1121 | }
1122 |
1123 | materialList.setItems(materialListItems);
1124 | }
1125 | });
1126 |
1127 | alert.hide();
1128 |
1129 | primaryStage.setMaxHeight(885);//.setResizable(false);
1130 | primaryStage.setMaxWidth(1025);
1131 |
1132 | primaryStage.setMinHeight(885);//.setResizable(false);
1133 | primaryStage.setMinWidth(1025);
1134 |
1135 | primaryStage.show();
1136 |
1137 | Alert message = new Alert(Alert.AlertType.INFORMATION);
1138 | message.setTitle("Welcome");
1139 | message.setHeaderText(
1140 | "This ray tracer supports:\n"
1141 | + " -Diffusion\n"
1142 | + " -Specularity\n"
1143 | + " -Reflection\n"
1144 | + " -Super, Adaptive, and Stochastic(Monte Carlo) Antialiasing\n"
1145 | + " -Camera manipulation(target and position)\n"
1146 | + " -Custom materials\n"
1147 | + " -Custom point source lighting\n"
1148 | + " -Custom objects(currently only a sphere)\n"
1149 | + " -Render previews\n"
1150 | + " -Inward only refraction(no transparency)\n\n"
1151 | + "Press OK to begin."
1152 | );
1153 | message.setGraphic(null);
1154 | message.initModality(Modality.NONE);
1155 | message.show();
1156 | }
1157 |
1158 | /**
1159 | * @param args the command line arguments
1160 | */
1161 | public static void main(String[] args) {
1162 | launch(args);
1163 | }
1164 |
1165 | private void addLight(LightSource tempLight, String _name){
1166 | int tempLength = view.lightSource.length + 1;
1167 |
1168 | LightSource[] tempLightSources = new LightSource[tempLength];
1169 |
1170 | System.arraycopy(view.lightSource, 0, tempLightSources, 0, tempLength - 1);
1171 |
1172 | tempLightSources[tempLength - 1] = tempLight;
1173 |
1174 | view.lightSource = tempLightSources;
1175 |
1176 | lightListItems.add(_name);
1177 | }
1178 |
1179 | private void addSphere(String _name, double x, double y, double z, double _radius, Material _material){
1180 | int tempLength = view.objects.length + 1;
1181 |
1182 | AbsObject[] tempObjects = new AbsObject[tempLength];
1183 |
1184 | System.arraycopy(view.objects, 0, tempObjects, 0, tempLength - 1);
1185 |
1186 | Sphere tempSphere = new Sphere() {{
1187 | material = _material;
1188 | objectPosition = Vector.create(x, y, z);
1189 | radius = _radius;
1190 | name = _name;
1191 | }};
1192 |
1193 | tempObjects[tempLength - 1] = tempSphere;
1194 |
1195 | view.objects = tempObjects;
1196 |
1197 | objectListItems.add(_name);
1198 | }
1199 |
1200 | private void addMaterial(Material material, String _name){
1201 | int tempLength = Materials.materials.length + 1;
1202 |
1203 | Material[] tempMat = new Material[tempLength];
1204 |
1205 | System.arraycopy(Materials.materials, 0, tempMat, 0, tempLength - 1);
1206 |
1207 | tempMat[tempLength - 1] = material;
1208 |
1209 | Materials.materials = tempMat;
1210 |
1211 | materialListItems.add(_name);
1212 | }
1213 |
1214 | public static void setImage(BufferedImage bImage){
1215 | Image image = SwingFXUtils.toFXImage(bImage, null);
1216 |
1217 | imageView.setImage(image);
1218 | }
1219 | }
--------------------------------------------------------------------------------