pyfast 4.12.0__cp36-abi3-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fast/README.md +41 -0
- fast/__init__.py +22 -0
- fast/bin/DirectML.dll +0 -0
- fast/bin/FAST.dll +0 -0
- fast/bin/InferenceEngineONNXRuntime.dll +0 -0
- fast/bin/InferenceEngineOpenVINO.dll +0 -0
- fast/bin/InferenceEngineTensorFlow.dll +0 -0
- fast/bin/InferenceEngineTensorRT.dll +0 -0
- fast/bin/JKQTCommonSharedLib_Release.dll +0 -0
- fast/bin/JKQTFastPlotterSharedLib_Release.dll +0 -0
- fast/bin/JKQTMathTextSharedLib_Release.dll +0 -0
- fast/bin/JKQTPlotterSharedLib_Release.dll +0 -0
- fast/bin/OpenCL.dll +0 -0
- fast/bin/OpenIGTLink.dll +0 -0
- fast/bin/Qt5Concurrent.dll +0 -0
- fast/bin/Qt5Core.dll +0 -0
- fast/bin/Qt5DBus.dll +0 -0
- fast/bin/Qt5Gui.dll +0 -0
- fast/bin/Qt5Multimedia.dll +0 -0
- fast/bin/Qt5MultimediaWidgets.dll +0 -0
- fast/bin/Qt5Network.dll +0 -0
- fast/bin/Qt5OpenGL.dll +0 -0
- fast/bin/Qt5PrintSupport.dll +0 -0
- fast/bin/Qt5SerialPort.dll +0 -0
- fast/bin/Qt5Sql.dll +0 -0
- fast/bin/Qt5Svg.dll +0 -0
- fast/bin/Qt5Test.dll +0 -0
- fast/bin/Qt5Widgets.dll +0 -0
- fast/bin/Qt5Xml.dll +0 -0
- fast/bin/UFFviewer.exe +0 -0
- fast/bin/_fast.pyd +0 -0
- fast/bin/brotlicommon.dll +0 -0
- fast/bin/brotlidec.dll +0 -0
- fast/bin/brotlienc.dll +0 -0
- fast/bin/cache.json +114134 -0
- fast/bin/dcmdata.dll +0 -0
- fast/bin/dcmimage.dll +0 -0
- fast/bin/dcmimgle.dll +0 -0
- fast/bin/dcmjpeg.dll +0 -0
- fast/bin/fast_configuration.txt +14 -0
- fast/bin/gna.dll +0 -0
- fast/bin/ijg12.dll +0 -0
- fast/bin/ijg16.dll +0 -0
- fast/bin/ijg8.dll +0 -0
- fast/bin/jxl.dll +0 -0
- fast/bin/jxl_cms.dll +0 -0
- fast/bin/jxl_threads.dll +0 -0
- fast/bin/libcrypto-1_1-x64.dll +0 -0
- fast/bin/libjpeg.dll +0 -0
- fast/bin/libopenslide-1.dll +0 -0
- fast/bin/libssl-1_1-x64.dll +0 -0
- fast/bin/oflog.dll +0 -0
- fast/bin/ofstd.dll +0 -0
- fast/bin/onnxruntime.dll +0 -0
- fast/bin/onnxruntime_providers_shared.dll +0 -0
- fast/bin/openvino.dll +0 -0
- fast/bin/openvino_auto_batch_plugin.dll +0 -0
- fast/bin/openvino_auto_plugin.dll +0 -0
- fast/bin/openvino_c.dll +0 -0
- fast/bin/openvino_gapi_preproc.dll +0 -0
- fast/bin/openvino_hetero_plugin.dll +0 -0
- fast/bin/openvino_intel_cpu_plugin.dll +0 -0
- fast/bin/openvino_intel_gna_plugin.dll +0 -0
- fast/bin/openvino_intel_gpu_plugin.dll +0 -0
- fast/bin/openvino_ir_frontend.dll +0 -0
- fast/bin/openvino_onnx_frontend.dll +0 -0
- fast/bin/openvino_paddle_frontend.dll +0 -0
- fast/bin/plugins.xml +24 -0
- fast/bin/realsense2.dll +0 -0
- fast/bin/runPipeline.exe +0 -0
- fast/bin/systemCheck.exe +0 -0
- fast/bin/tbb.dll +0 -0
- fast/bin/tbb_preview.dll +0 -0
- fast/bin/tbbbind.dll +0 -0
- fast/bin/tbbmalloc.dll +0 -0
- fast/bin/tbbmalloc_proxy.dll +0 -0
- fast/bin/tiff.dll +0 -0
- fast/bin/zlib.dll +0 -0
- fast/doc/bright-plotting-style.ini +66 -0
- fast/doc/dark-plotting-style.ini +66 -0
- fast/doc/fonts/UFL.txt +96 -0
- fast/doc/fonts/Ubuntu-Bold.ttf +0 -0
- fast/doc/fonts/Ubuntu-BoldItalic.ttf +0 -0
- fast/doc/fonts/Ubuntu-Italic.ttf +0 -0
- fast/doc/fonts/Ubuntu-Light.ttf +0 -0
- fast/doc/fonts/Ubuntu-LightItalic.ttf +0 -0
- fast/doc/fonts/Ubuntu-Medium.ttf +0 -0
- fast/doc/fonts/Ubuntu-MediumItalic.ttf +0 -0
- fast/doc/fonts/Ubuntu-Regular.ttf +0 -0
- fast/doc/fonts/UbuntuMono-Bold.ttf +0 -0
- fast/doc/fonts/UbuntuMono-BoldItalic.ttf +0 -0
- fast/doc/fonts/UbuntuMono-Italic.ttf +0 -0
- fast/doc/fonts/UbuntuMono-Regular.ttf +0 -0
- fast/doc/images/FAST_logo_square.png +0 -0
- fast/doc/images/fast_icon.ico +0 -0
- fast/doc/images/fast_icon.png +0 -0
- fast/entry_points.py +14 -0
- fast/fast.py +20057 -0
- fast/kernels/Algorithms/AirwaySegmentation/AirwaySegmentation.cl +85 -0
- fast/kernels/Algorithms/ApplyColormap/ApplyColormap.cl +146 -0
- fast/kernels/Algorithms/BinaryThresholding/BinaryThresholding2D.cl +61 -0
- fast/kernels/Algorithms/BinaryThresholding/BinaryThresholding3D.cl +61 -0
- fast/kernels/Algorithms/BlockMatching/BlockMatching.cl +257 -0
- fast/kernels/Algorithms/CenterlineExtraction/CenterlineExtraction.cl +153 -0
- fast/kernels/Algorithms/CoherentPointDrift/CoherentPointDrift.cl +0 -0
- fast/kernels/Algorithms/Color/ColorToGrayscale.cl +22 -0
- fast/kernels/Algorithms/Color/GrayscaleToColor.cl +19 -0
- fast/kernels/Algorithms/GaussianSmoothing/GaussianSmoothing2D.cl +35 -0
- fast/kernels/Algorithms/GaussianSmoothing/GaussianSmoothing3D.cl +75 -0
- fast/kernels/Algorithms/GradientVectorFlow/EulerGradientVectorFlow.cl +174 -0
- fast/kernels/Algorithms/GradientVectorFlow/MultigridGradientVectorFlow.cl +407 -0
- fast/kernels/Algorithms/HounsefieldConverter/HounsefieldConverter.cl +22 -0
- fast/kernels/Algorithms/ImageAdd/ImageAdd.cl +79 -0
- fast/kernels/Algorithms/ImageCaster/ImageCaster.cl +38 -0
- fast/kernels/Algorithms/ImageChannelConverter/ImageChannelConverter.cl +121 -0
- fast/kernels/Algorithms/ImageFlipper/ImageFlipper2D.cl +23 -0
- fast/kernels/Algorithms/ImageFlipper/ImageFlipper3D.cl +51 -0
- fast/kernels/Algorithms/ImageGradient/ImageGradient.cl +71 -0
- fast/kernels/Algorithms/ImageInverter/ImageInverter.cl +30 -0
- fast/kernels/Algorithms/ImageMultiply/ImageMultiply.cl +79 -0
- fast/kernels/Algorithms/ImagePatch/PatchStitcher2D.cl +22 -0
- fast/kernels/Algorithms/ImagePatch/PatchStitcher3D.cl +95 -0
- fast/kernels/Algorithms/ImageResampler/ImageResampler2D.cl +40 -0
- fast/kernels/Algorithms/ImageResampler/ImageResampler3D.cl +32 -0
- fast/kernels/Algorithms/ImageResizer/ImageResizer.cl +134 -0
- fast/kernels/Algorithms/ImageSharpening/ImageSharpening.cl +47 -0
- fast/kernels/Algorithms/ImageSlicer/ImageSlicer.cl +77 -0
- fast/kernels/Algorithms/ImageTransposer/ImageTransposer2D.cl +16 -0
- fast/kernels/Algorithms/ImageTransposer/ImageTransposer3D.cl +45 -0
- fast/kernels/Algorithms/IntensityClipping/IntensityClipping2D.cl +19 -0
- fast/kernels/Algorithms/IntensityClipping/IntensityClipping3D.cl +20 -0
- fast/kernels/Algorithms/IntensityNormalization/IntensityNormalization.cl +85 -0
- fast/kernels/Algorithms/IntensityNormalization/ZeroMeanUnitVariance.cl +76 -0
- fast/kernels/Algorithms/KalmanFilterModelSegmentation/AppearanceModels/RidgeEdge/RidgeEdgeModel.cl +81 -0
- fast/kernels/Algorithms/LabelModifier/LabelModifier.cl +20 -0
- fast/kernels/Algorithms/LaplacianOfGaussian/LaplacianOfGaussian2D.cl +27 -0
- fast/kernels/Algorithms/LevelSet/LevelSetSegmentation.cl +132 -0
- fast/kernels/Algorithms/LungSegmentation/LungSegmentation.cl +22 -0
- fast/kernels/Algorithms/MeshToSegmentation/MeshToSegmentation.cl +184 -0
- fast/kernels/Algorithms/Morphology/Dilation.cl +56 -0
- fast/kernels/Algorithms/Morphology/Erosion.cl +64 -0
- fast/kernels/Algorithms/NeuralNetwork/NeuralNetwork.cl +122 -0
- fast/kernels/Algorithms/NeuralNetwork/VertexTensorToSegmentation.cl +13 -0
- fast/kernels/Algorithms/NonLocalMeans/NonLocalMeans2D.cl +94 -0
- fast/kernels/Algorithms/SeededRegionGrowing/SeededRegionGrowing2D.cl +57 -0
- fast/kernels/Algorithms/SeededRegionGrowing/SeededRegionGrowing3D.cl +58 -0
- fast/kernels/Algorithms/Skeletonization/Skeletonization2D.cl +77 -0
- fast/kernels/Algorithms/SurfaceExtraction/SurfaceExtraction.cl +519 -0
- fast/kernels/Algorithms/SurfaceExtraction/SurfaceExtraction_no_3d_write.cl +739 -0
- fast/kernels/Algorithms/TemporalSmoothing/ImageMovingAverage.cl +66 -0
- fast/kernels/Algorithms/TemporalSmoothing/ImageWeightedMovingAverage.cl +74 -0
- fast/kernels/Algorithms/TissueSegmentation/TissueSegmentation.cl +18 -0
- fast/kernels/Algorithms/TubeSegmentationAndCenterlineExtraction/InverseGradientSegmentation.cl +203 -0
- fast/kernels/Algorithms/TubeSegmentationAndCenterlineExtraction/TubeSegmentationAndCenterlineExtraction.cl +566 -0
- fast/kernels/Algorithms/Ultrasound/EnvelopeAndLogCompressor.cl +45 -0
- fast/kernels/Algorithms/Ultrasound/ScanConverter.cl +76 -0
- fast/kernels/Algorithms/UltrasoundImageCropper/UltrasoundImageCropper.cl +31 -0
- fast/kernels/Algorithms/UltrasoundImageEnhancement/UltrasoundImageEnhancement.cl +27 -0
- fast/kernels/Algorithms/VectorMedianFilter/VectorMedianFilter.cl +31 -0
- fast/kernels/ImageFill.cl +30 -0
- fast/kernels/ImageMinMax.cl +196 -0
- fast/kernels/ImageSum.cl +170 -0
- fast/kernels/Tests/Algorithms/DoubleFilter.cl +7 -0
- fast/kernels/Visualization/BoundingBoxRenderer/BoundingBoxRenderer.frag +8 -0
- fast/kernels/Visualization/BoundingBoxRenderer/BoundingBoxRenderer.geom +69 -0
- fast/kernels/Visualization/BoundingBoxRenderer/BoundingBoxRenderer.vert +17 -0
- fast/kernels/Visualization/HeatmapRenderer/HeatmapRenderer.cl +51 -0
- fast/kernels/Visualization/ImagePyramidRenderer/ImagePyramidRenderer.frag +11 -0
- fast/kernels/Visualization/ImagePyramidRenderer/ImagePyramidRenderer.vert +15 -0
- fast/kernels/Visualization/ImageRenderer/ImageRenderer.vert +15 -0
- fast/kernels/Visualization/ImageRenderer/ImageRendererFLOAT.frag +18 -0
- fast/kernels/Visualization/ImageRenderer/ImageRendererINT.frag +18 -0
- fast/kernels/Visualization/ImageRenderer/ImageRendererUINT.frag +18 -0
- fast/kernels/Visualization/LineRenderer/LineRenderer.frag +8 -0
- fast/kernels/Visualization/LineRenderer/LineRenderer.geom +35 -0
- fast/kernels/Visualization/LineRenderer/LineRenderer.vert +20 -0
- fast/kernels/Visualization/LineRenderer/LineRenderer3D.frag +8 -0
- fast/kernels/Visualization/LineRenderer/LineRenderer3D.vert +20 -0
- fast/kernels/Visualization/LineRenderer/LineRendererJoints.frag +15 -0
- fast/kernels/Visualization/LineRenderer/LineRendererJoints.vert +24 -0
- fast/kernels/Visualization/SegmentationLabelRenderer/SegmentationLabelRenderer.frag +11 -0
- fast/kernels/Visualization/SegmentationLabelRenderer/SegmentationLabelRenderer.vert +16 -0
- fast/kernels/Visualization/SegmentationRenderer/SegmentationPyramidRenderer.frag +53 -0
- fast/kernels/Visualization/SegmentationRenderer/SegmentationRenderer.frag +52 -0
- fast/kernels/Visualization/SegmentationRenderer/SegmentationRenderer.vert +15 -0
- fast/kernels/Visualization/TextRenderer/TextRenderer.frag +11 -0
- fast/kernels/Visualization/TextRenderer/TextRenderer.vert +20 -0
- fast/kernels/Visualization/TriangleRenderer/TriangleRenderer.frag +49 -0
- fast/kernels/Visualization/TriangleRenderer/TriangleRenderer.vert +35 -0
- fast/kernels/Visualization/VectorFieldRenderer/VectorFieldColorRenderer.cl +30 -0
- fast/kernels/Visualization/VertexRenderer/VertexRenderer.frag +14 -0
- fast/kernels/Visualization/VertexRenderer/VertexRenderer.vert +23 -0
- fast/kernels/Visualization/View.cl +10 -0
- fast/kernels/Visualization/VolumeRenderer/AlphaBlendingVolumeRenderer.cl +211 -0
- fast/kernels/Visualization/VolumeRenderer/MaximumIntensityProjection.cl +139 -0
- fast/kernels/Visualization/VolumeRenderer/ThresholdVolumeRenderer.cl +178 -0
- fast/licenses/LICENSE +203 -0
- fast/licenses/MSVC/MSVC_redis_files_license.txt +96 -0
- fast/licenses/OpenIGTLink/LICENSE.txt +30 -0
- fast/licenses/OpenJPEG/LICENSE +39 -0
- fast/licenses/OpenSlide/COPYING.LESSER +504 -0
- fast/licenses/PCRE2/LICENCE.md +103 -0
- fast/licenses/SQLite/PUBLIC-DOMAIN.txt +9 -0
- fast/licenses/THIRD_PARTY_TF_C_LICENSES +7955 -0
- fast/licenses/cairo/COPYING +33 -0
- fast/licenses/cairo/COPYING-LGPL-2.1 +510 -0
- fast/licenses/cairo/COPYING-MPL-1.1 +470 -0
- fast/licenses/clarius/LICENSE +29 -0
- fast/licenses/dcmtk/COPYRIGHT +1034 -0
- fast/licenses/directml/LICENSE-CODE.txt +21 -0
- fast/licenses/directml/LICENSE.txt +48 -0
- fast/licenses/directml/ThirdPartyNotices.txt +103 -0
- fast/licenses/eigen/COPYING.APACHE +203 -0
- fast/licenses/eigen/COPYING.BSD +26 -0
- fast/licenses/eigen/COPYING.GPL +674 -0
- fast/licenses/eigen/COPYING.LGPL +502 -0
- fast/licenses/eigen/COPYING.MINPACK +51 -0
- fast/licenses/eigen/COPYING.MPL2 +373 -0
- fast/licenses/eigen/COPYING.README +18 -0
- fast/licenses/fast/LICENSE +25 -0
- fast/licenses/gdk-pixbuf/COPYING +502 -0
- fast/licenses/glib/COPYING +175 -0
- fast/licenses/hdf5/COPYING +106 -0
- fast/licenses/jkqtplotter/LICENSE +505 -0
- fast/licenses/jpegxl/LICENSE.brotli +19 -0
- fast/licenses/jpegxl/LICENSE.highway +201 -0
- fast/licenses/jpegxl/LICENSE.jpeg-xl +27 -0
- fast/licenses/jpegxl/LICENSE.skcms +29 -0
- fast/licenses/jpegxl/PATENTS +22 -0
- fast/licenses/libdicom/LICENSE +21 -0
- fast/licenses/libffi/LICENSE +21 -0
- fast/licenses/libjpeg-turbo/LICENSE.md +135 -0
- fast/licenses/libjpeg-turbo/README.ijg +260 -0
- fast/licenses/libpng/LICENSE +134 -0
- fast/licenses/libtiff/LICENSE.md +23 -0
- fast/licenses/libxml2/Copyright +24 -0
- fast/licenses/onnxruntime/LICENSE +21 -0
- fast/licenses/onnxruntime/Privacy.md +21 -0
- fast/licenses/onnxruntime/ThirdPartyNotices.txt +6156 -0
- fast/licenses/opencl/LICENSE +201 -0
- fast/licenses/openssl/LICENSE.txt +125 -0
- fast/licenses/openvino/Apache_license.txt +201 -0
- fast/licenses/openvino/EULA.htm +43 -0
- fast/licenses/openvino/EULA.rtf +61 -0
- fast/licenses/openvino/EULA.txt +163 -0
- fast/licenses/openvino/GNA SOFTWARE LICENSE AGREEMENT.txt +1 -0
- fast/licenses/openvino/Intel_Software_Development_Products.rtf +1217 -0
- fast/licenses/openvino/Intel_Software_Development_Products.txt +707 -0
- fast/licenses/openvino/LICENSE +201 -0
- fast/licenses/openvino/OpenVINOsupport.txt +12 -0
- fast/licenses/openvino/onednn_third-party-programs.txt +557 -0
- fast/licenses/openvino/readme.txt +60 -0
- fast/licenses/openvino/redist.txt +42 -0
- fast/licenses/openvino/runtime-third-party-programs.txt +1400 -0
- fast/licenses/openvino/tbb_third-party-programs.txt +230 -0
- fast/licenses/pixman/COPYING +42 -0
- fast/licenses/proxy-libintl/COPYING +482 -0
- fast/licenses/qt5/LICENSE.FDL +450 -0
- fast/licenses/qt5/LICENSE.GPL3-EXCEPT +704 -0
- fast/licenses/qt5/LICENSE.GPLv2 +292 -0
- fast/licenses/qt5/LICENSE.GPLv3 +686 -0
- fast/licenses/qt5/LICENSE.LGPLv21 +514 -0
- fast/licenses/qt5/LICENSE.LGPLv3 +175 -0
- fast/licenses/qt5/LICENSE.QT-LICENSE-AGREEMENT +1331 -0
- fast/licenses/realsense/LICENSE +202 -0
- fast/licenses/realsense/NOTICE +937 -0
- fast/licenses/semaphore/Semaphore_LICENSE.txt +17 -0
- fast/licenses/tiff/COPYRIGHT +21 -0
- fast/licenses/uthash/LICENSE +21 -0
- fast/licenses/zip/UNLICENSE +26 -0
- fast/licenses/zlib/README +115 -0
- fast/licenses/zlib-ng/LICENSE.md +19 -0
- fast/pipelines/uff_viewer/colormap_and_reject.fpl +26 -0
- fast/pipelines/uff_viewer/default.fpl +9 -0
- fast/pipelines/uff_viewer/non_local_means.fpl +34 -0
- fast/plugins/audio/qtaudio_wasapi.dll +0 -0
- fast/plugins/audio/qtaudio_windows.dll +0 -0
- fast/plugins/bearer/qgenericbearer.dll +0 -0
- fast/plugins/generic/qtuiotouchplugin.dll +0 -0
- fast/plugins/iconengines/qsvgicon.dll +0 -0
- fast/plugins/imageformats/qgif.dll +0 -0
- fast/plugins/imageformats/qicns.dll +0 -0
- fast/plugins/imageformats/qico.dll +0 -0
- fast/plugins/imageformats/qjpeg.dll +0 -0
- fast/plugins/imageformats/qsvg.dll +0 -0
- fast/plugins/imageformats/qtga.dll +0 -0
- fast/plugins/imageformats/qtiff.dll +0 -0
- fast/plugins/imageformats/qwbmp.dll +0 -0
- fast/plugins/imageformats/qwebp.dll +0 -0
- fast/plugins/mediaservice/dsengine.dll +0 -0
- fast/plugins/mediaservice/qtmedia_audioengine.dll +0 -0
- fast/plugins/mediaservice/wmfengine.dll +0 -0
- fast/plugins/platforms/qdirect2d.dll +0 -0
- fast/plugins/platforms/qminimal.dll +0 -0
- fast/plugins/platforms/qoffscreen.dll +0 -0
- fast/plugins/platforms/qwindows.dll +0 -0
- fast/plugins/platformthemes/qxdgdesktopportal.dll +0 -0
- fast/plugins/playlistformats/qtmultimedia_m3u.dll +0 -0
- fast/plugins/printsupport/windowsprintersupport.dll +0 -0
- fast/plugins/sqldrivers/qsqlite.dll +0 -0
- fast/plugins/sqldrivers/qsqlodbc.dll +0 -0
- fast/plugins/styles/qwindowsvistastyle.dll +0 -0
- pyfast-4.12.0.dist-info/METADATA +81 -0
- pyfast-4.12.0.dist-info/RECORD +307 -0
- pyfast-4.12.0.dist-info/WHEEL +5 -0
- pyfast-4.12.0.dist-info/entry_points.txt +5 -0
- pyfast-4.12.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
const sampler_t volumeSampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;
|
|
2
|
+
|
|
3
|
+
// intersect ray with a box
|
|
4
|
+
// http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm
|
|
5
|
+
int intersectBox(float4 r_o, float4 r_d, float4 boxmin, float4 boxmax, float *tnear, float *tfar) {
|
|
6
|
+
// compute intersection of ray with all six bbox planes
|
|
7
|
+
float4 invR = (float4)(1.0f,1.0f,1.0f,1.0f) / r_d;
|
|
8
|
+
float4 tbot = invR * (boxmin - r_o);
|
|
9
|
+
float4 ttop = invR * (boxmax - r_o);
|
|
10
|
+
|
|
11
|
+
// re-order intersections to find smallest and largest on each axis
|
|
12
|
+
float4 tmin = min(ttop, tbot);
|
|
13
|
+
float4 tmax = max(ttop, tbot);
|
|
14
|
+
|
|
15
|
+
// find the largest tmin and the smallest tmax
|
|
16
|
+
float largest_tmin = max(max(tmin.x, tmin.y), max(tmin.x, tmin.z));
|
|
17
|
+
float smallest_tmax = min(min(tmax.x, tmax.y), min(tmax.x, tmax.z));
|
|
18
|
+
|
|
19
|
+
*tnear = largest_tmin;
|
|
20
|
+
*tfar = smallest_tmax;
|
|
21
|
+
|
|
22
|
+
return smallest_tmax > largest_tmin;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
uint rgbaFloatToInt(float4 rgba)
|
|
26
|
+
{
|
|
27
|
+
rgba.x = clamp(rgba.x,0.0f,1.0f);
|
|
28
|
+
rgba.y = clamp(rgba.y,0.0f,1.0f);
|
|
29
|
+
rgba.z = clamp(rgba.z,0.0f,1.0f);
|
|
30
|
+
rgba.w = clamp(rgba.w,0.0f,1.0f);
|
|
31
|
+
return ((uint)(rgba.w*255.0f)<<24) | ((uint)(rgba.z*255.0f)<<16) | ((uint)(rgba.y*255.0f)<<8) | (uint)(rgba.x*255.0f);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
float3 reflect(float3 I, float3 N) {
|
|
35
|
+
return I - 2.0f * dot(N, I) * N;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
float3 transformPosition(__constant float* transform, float3 pos) {
|
|
39
|
+
float4 position = {pos.x, pos.y, pos.z, 1};
|
|
40
|
+
float transformedPosition[4];
|
|
41
|
+
|
|
42
|
+
// Multiply with transform
|
|
43
|
+
// transform is column major
|
|
44
|
+
for(int i = 0; i < 4; i++) {
|
|
45
|
+
float sum = 0;
|
|
46
|
+
sum += transform[0 + i*4]*position.x;
|
|
47
|
+
sum += transform[1 + i*4]*position.y;
|
|
48
|
+
sum += transform[2 + i*4]*position.z;
|
|
49
|
+
sum += transform[3 + i*4]*position.w;
|
|
50
|
+
transformedPosition[i] = sum;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
float3 result = {transformedPosition[0], transformedPosition[1], transformedPosition[2]};
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
float4 vload4_at_pos(int position, __constant float* data) {
|
|
58
|
+
return (float4)(data[position], data[position+1], data[position+2], data[position+3]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
float4 getColorFromTransferFunction(float intensity, __constant float* transferFunction, int steps) {
|
|
62
|
+
float4 first = vload4_at_pos(1, transferFunction);
|
|
63
|
+
float firstIntensity = transferFunction[0];
|
|
64
|
+
|
|
65
|
+
if(intensity <= firstIntensity)
|
|
66
|
+
return first;
|
|
67
|
+
|
|
68
|
+
for(int i = 1; i < steps; ++i) {
|
|
69
|
+
float4 second = vload4_at_pos(i*5 + 1, transferFunction);
|
|
70
|
+
float secondIntensity = transferFunction[i*5];
|
|
71
|
+
if(intensity <= secondIntensity) {
|
|
72
|
+
return mix(first, second, (intensity - firstIntensity)/(secondIntensity - firstIntensity));
|
|
73
|
+
}
|
|
74
|
+
first = second;
|
|
75
|
+
firstIntensity = secondIntensity;
|
|
76
|
+
}
|
|
77
|
+
return first;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Wang Hash based RNG, used to get rid of sampling artifact patterns
|
|
81
|
+
float ParallelRNG(unsigned int x) {
|
|
82
|
+
unsigned int value = x;
|
|
83
|
+
|
|
84
|
+
value = (value ^ 61) ^ (value>>16);
|
|
85
|
+
value *= 9;
|
|
86
|
+
value ^= value << 4;
|
|
87
|
+
value *= 0x27d4eb2d;
|
|
88
|
+
value ^= value >> 15;
|
|
89
|
+
|
|
90
|
+
return (float)(value & 0x0ff) / 255.0f; // Convert to float 0-1
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
__kernel void volumeRender(
|
|
95
|
+
__read_only image3d_t volume,
|
|
96
|
+
__write_only image2d_t framebuffer,
|
|
97
|
+
__constant float* invViewMatrix,
|
|
98
|
+
__constant float* invViewMatrix2,
|
|
99
|
+
__read_only image2d_t inputFramebuffer,
|
|
100
|
+
__read_only image2d_t inputDepthFramebuffer,
|
|
101
|
+
__private float zNear,
|
|
102
|
+
__private float zFar,
|
|
103
|
+
__constant float* transferFunction,
|
|
104
|
+
__private int steps
|
|
105
|
+
) {
|
|
106
|
+
|
|
107
|
+
const int width = get_image_width(framebuffer);
|
|
108
|
+
const int height = get_image_height(framebuffer);
|
|
109
|
+
|
|
110
|
+
// Grid position
|
|
111
|
+
const int x = get_global_id(0);
|
|
112
|
+
const int y = get_global_id(1);
|
|
113
|
+
|
|
114
|
+
// Normalized grid position
|
|
115
|
+
const float u = ((x / (float) width)*2.0f-1.0f)*((float)width/height); // compensate for aspect ratio != 1
|
|
116
|
+
const float v = ((y / (float) height)*2.0f-1.0f);
|
|
117
|
+
|
|
118
|
+
const float4 inputColor = read_imagef(inputFramebuffer, volumeSampler, (int2)(x,y));
|
|
119
|
+
|
|
120
|
+
// Bounding box of volume
|
|
121
|
+
const float4 boxMin = (float4)(0.0f, 0.0f, 0.0f,1.0f);
|
|
122
|
+
const float4 boxMax = (float4)(get_image_width(volume), get_image_height(volume), get_image_depth(volume), 1.0f);
|
|
123
|
+
// Maximum depth to cast ray inside the volume
|
|
124
|
+
|
|
125
|
+
// Calculate ray origin and direction
|
|
126
|
+
float4 rayOrigin;
|
|
127
|
+
float4 rayDirection;
|
|
128
|
+
|
|
129
|
+
// Ray origin is at the camera center
|
|
130
|
+
rayOrigin = (float4)(invViewMatrix[12], invViewMatrix[13], invViewMatrix[14], 1.0f);
|
|
131
|
+
|
|
132
|
+
// Calculate ray direction which is the direction of the vector (u,v,-2) - (0,0,0)
|
|
133
|
+
float4 temp = normalize(((float4)(u, v, -2.0f,0.0f)));
|
|
134
|
+
// Apply camera rotation on the ray direction vector
|
|
135
|
+
rayDirection.x = dot(temp, ((float4)(invViewMatrix[0],invViewMatrix[4],invViewMatrix[8], 0)));
|
|
136
|
+
rayDirection.y = dot(temp, ((float4)(invViewMatrix[1],invViewMatrix[5],invViewMatrix[9], 0)));
|
|
137
|
+
rayDirection.z = dot(temp, ((float4)(invViewMatrix[2],invViewMatrix[6],invViewMatrix[10], 0)));
|
|
138
|
+
rayDirection.w = 1.0f;
|
|
139
|
+
|
|
140
|
+
// Find the distance to where the ray hits the box
|
|
141
|
+
float tnear, tfar;
|
|
142
|
+
int hit = intersectBox(rayOrigin, rayDirection, boxMin, boxMax, &tnear, &tfar);
|
|
143
|
+
if(!hit) {
|
|
144
|
+
// Ray doesn't hit the box at all
|
|
145
|
+
write_imagef(framebuffer, (int2)(x, y), inputColor);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if(tnear < 0.0f)
|
|
150
|
+
tnear = 0.0f; // clamp to near plane
|
|
151
|
+
|
|
152
|
+
// Traverse along ray from back to front, while blending colors
|
|
153
|
+
temp = inputColor;
|
|
154
|
+
// Recover original depth from depth buffer: https://stackoverflow.com/questions/6652253/getting-the-true-z-value-from-the-depth-buffer
|
|
155
|
+
float depth = (read_imagef(inputDepthFramebuffer, volumeSampler, (int2)(x,y)).x*2.0f - 1.0f); // turn depth into normalized coordinate ([-1, 1]
|
|
156
|
+
depth = 2.0f * zNear * zFar / (zFar + zNear - depth * (zFar - zNear));
|
|
157
|
+
float distance = min(tfar, depth) + ParallelRNG(x + y*width);
|
|
158
|
+
while(distance > tnear) { // back to front
|
|
159
|
+
float4 pos = rayOrigin + rayDirection * distance;
|
|
160
|
+
|
|
161
|
+
// read from 3D texture
|
|
162
|
+
float sample = read_imagei(volume, volumeSampler, pos).x;
|
|
163
|
+
|
|
164
|
+
// lookup intensity value in transfer function
|
|
165
|
+
float4 color = getColorFromTransferFunction(sample, transferFunction, steps);
|
|
166
|
+
|
|
167
|
+
// Shading: Calculate volume normal
|
|
168
|
+
float3 normal;
|
|
169
|
+
normal.x = 0.5f * (read_imagei(volume, volumeSampler, pos + (float4)(1, 0, 0, 0)).x -
|
|
170
|
+
read_imagei(volume, volumeSampler, pos - (float4)(1, 0, 0, 0)).x);
|
|
171
|
+
normal.y = 0.5f * (read_imagei(volume, volumeSampler, pos + (float4)(0, 1, 0, 0)).x -
|
|
172
|
+
read_imagei(volume, volumeSampler, pos - (float4)(0, 1, 0, 0)).x);
|
|
173
|
+
normal.z = 0.5f * (read_imagei(volume, volumeSampler, pos + (float4)(0, 0, 1, 0)).x -
|
|
174
|
+
read_imagei(volume, volumeSampler, pos - (float4)(0, 0, 1, 0)).x);
|
|
175
|
+
normal = normalize(normal);
|
|
176
|
+
normal = transformPosition(invViewMatrix2, normal);
|
|
177
|
+
normal = normalize(normal);
|
|
178
|
+
|
|
179
|
+
// Calculate color with light
|
|
180
|
+
float3 objectColor = color.xyz;
|
|
181
|
+
float3 lightColor = {0.7, 0.7, 0.7};
|
|
182
|
+
float3 ambientColor = {0.2, 0.2, 0.2};
|
|
183
|
+
float3 specularColor = {1, 1, 1};
|
|
184
|
+
float3 LightPos = {0, 0, 0};
|
|
185
|
+
float3 ViewPos = {0, 0, 0};
|
|
186
|
+
float shininess = 16.0f;
|
|
187
|
+
|
|
188
|
+
// TODO fix: Light direction is not entirely correct. Look at TriangleRenderer.vert
|
|
189
|
+
LightPos = transformPosition(invViewMatrix2, LightPos);
|
|
190
|
+
ViewPos = transformPosition(invViewMatrix2, ViewPos);
|
|
191
|
+
|
|
192
|
+
float3 lightDir = normalize(LightPos - pos.xyz);
|
|
193
|
+
float diff = max(dot(normal, lightDir), 0.0f);
|
|
194
|
+
float3 diffuse = lightColor * (diff * objectColor);
|
|
195
|
+
float3 viewDir = normalize(ViewPos - pos.xyz);
|
|
196
|
+
float3 reflectDir = reflect(-lightDir, normal);
|
|
197
|
+
float spec = pow(max(dot(viewDir, reflectDir), 0.0f), shininess);
|
|
198
|
+
float3 specular = lightColor * (spec * specularColor);
|
|
199
|
+
float3 ambient = lightColor * ambientColor;
|
|
200
|
+
float3 result = ambient + diffuse + specular;
|
|
201
|
+
color = (float4)(result.x, result.y, result.z, color.w);
|
|
202
|
+
|
|
203
|
+
// accumulate result
|
|
204
|
+
temp = mix(temp, color, color.w);
|
|
205
|
+
|
|
206
|
+
distance -= 0.5f;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// write output color
|
|
210
|
+
write_imagef(framebuffer, (int2)(x, y), temp);
|
|
211
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const sampler_t volumeSampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;
|
|
2
|
+
|
|
3
|
+
float getPixelAsFloat(__read_only image3d_t image, sampler_t sampler, float4 pos) {
|
|
4
|
+
float value;
|
|
5
|
+
int dataType = get_image_channel_data_type(image);
|
|
6
|
+
if(dataType == CLK_FLOAT) {
|
|
7
|
+
value = read_imagef(image, sampler, pos).x;
|
|
8
|
+
} else if(dataType == CLK_UNSIGNED_INT8 || dataType == CLK_UNSIGNED_INT16 || dataType == CLK_UNSIGNED_INT32) {
|
|
9
|
+
value = read_imageui(image, sampler, pos).x;
|
|
10
|
+
} else {
|
|
11
|
+
value = read_imagei(image, sampler, pos).x;
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// intersect ray with a box
|
|
17
|
+
// http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm
|
|
18
|
+
|
|
19
|
+
int intersectBox(float4 r_o, float4 r_d, float4 boxmin, float4 boxmax, float *tnear, float *tfar) {
|
|
20
|
+
// compute intersection of ray with all six bbox planes
|
|
21
|
+
float4 invR = (float4)(1.0f,1.0f,1.0f,1.0f) / r_d;
|
|
22
|
+
float4 tbot = invR * (boxmin - r_o);
|
|
23
|
+
float4 ttop = invR * (boxmax - r_o);
|
|
24
|
+
|
|
25
|
+
// re-order intersections to find smallest and largest on each axis
|
|
26
|
+
float4 tmin = min(ttop, tbot);
|
|
27
|
+
float4 tmax = max(ttop, tbot);
|
|
28
|
+
|
|
29
|
+
// find the largest tmin and the smallest tmax
|
|
30
|
+
float largest_tmin = max(max(tmin.x, tmin.y), max(tmin.x, tmin.z));
|
|
31
|
+
float smallest_tmax = min(min(tmax.x, tmax.y), min(tmax.x, tmax.z));
|
|
32
|
+
|
|
33
|
+
*tnear = largest_tmin;
|
|
34
|
+
*tfar = smallest_tmax;
|
|
35
|
+
|
|
36
|
+
return smallest_tmax > largest_tmin;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
uint rgbaFloatToInt(float4 rgba)
|
|
40
|
+
{
|
|
41
|
+
rgba.x = clamp(rgba.x,0.0f,1.0f);
|
|
42
|
+
rgba.y = clamp(rgba.y,0.0f,1.0f);
|
|
43
|
+
rgba.z = clamp(rgba.z,0.0f,1.0f);
|
|
44
|
+
rgba.w = clamp(rgba.w,0.0f,1.0f);
|
|
45
|
+
return ((uint)(rgba.w*255.0f)<<24) | ((uint)(rgba.z*255.0f)<<16) | ((uint)(rgba.y*255.0f)<<8) | (uint)(rgba.x*255.0f);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
float3 reflect(float3 I, float3 N) {
|
|
49
|
+
return I - 2.0f * dot(N, I) * N;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
__kernel void volumeRender(
|
|
53
|
+
__read_only image3d_t volume,
|
|
54
|
+
__write_only image2d_t framebuffer,
|
|
55
|
+
__constant float* invViewMatrix,
|
|
56
|
+
__constant float* modelMatrix,
|
|
57
|
+
__read_only image2d_t inputFramebuffer,
|
|
58
|
+
__read_only image2d_t inputDepthFramebuffer,
|
|
59
|
+
__private float minimum,
|
|
60
|
+
__private float maximum,
|
|
61
|
+
__private float zNear,
|
|
62
|
+
__private float zFar
|
|
63
|
+
) {
|
|
64
|
+
|
|
65
|
+
const int width = get_image_width(framebuffer);
|
|
66
|
+
const int height = get_image_height(framebuffer);
|
|
67
|
+
|
|
68
|
+
// Grid position
|
|
69
|
+
const int x = get_global_id(0);
|
|
70
|
+
const int y = get_global_id(1);
|
|
71
|
+
|
|
72
|
+
// Normalized grid position
|
|
73
|
+
const float u = ((x / (float) width)*2.0f-1.0f)*((float)width/height); // compensate for aspect ratio != 1
|
|
74
|
+
const float v = ((y / (float) height)*2.0f-1.0f);
|
|
75
|
+
|
|
76
|
+
const float4 inputColor = read_imagef(inputFramebuffer, volumeSampler, (int2)(x,y));
|
|
77
|
+
|
|
78
|
+
// Bounding box of volume
|
|
79
|
+
const float4 boxMin = (float4)(0.0f, 0.0f, 0.0f,1.0f);
|
|
80
|
+
const float4 boxMax = (float4)(get_image_width(volume), get_image_height(volume), get_image_depth(volume), 1.0f);
|
|
81
|
+
// Maximum depth to cast ray inside the volume
|
|
82
|
+
|
|
83
|
+
// Calculate ray origin and direction
|
|
84
|
+
float4 rayOrigin;
|
|
85
|
+
float4 rayDirection;
|
|
86
|
+
|
|
87
|
+
// Ray origin is at the camera center
|
|
88
|
+
rayOrigin = (float4)(invViewMatrix[12], invViewMatrix[13], invViewMatrix[14], 1.0f);
|
|
89
|
+
|
|
90
|
+
// Calculate ray direction which is the direction of the vector (u,v,-2) - (0,0,0)
|
|
91
|
+
float4 temp = normalize(((float4)(u, v, -2.0f,0.0f)));
|
|
92
|
+
// Apply camera rotation on the ray direction vector
|
|
93
|
+
rayDirection.x = dot(temp, ((float4)(invViewMatrix[0],invViewMatrix[4],invViewMatrix[8], 0)));
|
|
94
|
+
rayDirection.y = dot(temp, ((float4)(invViewMatrix[1],invViewMatrix[5],invViewMatrix[9], 0)));
|
|
95
|
+
rayDirection.z = dot(temp, ((float4)(invViewMatrix[2],invViewMatrix[6],invViewMatrix[10], 0)));
|
|
96
|
+
rayDirection.w = 1.0f;
|
|
97
|
+
|
|
98
|
+
// Find the distance to where the ray hits the box
|
|
99
|
+
float tnear, tfar;
|
|
100
|
+
int hit = intersectBox(rayOrigin, rayDirection, boxMin, boxMax, &tnear, &tfar);
|
|
101
|
+
// write output color
|
|
102
|
+
if(!hit) {
|
|
103
|
+
// Ray doesn't hit the box at all
|
|
104
|
+
write_imagef(framebuffer, (int2)(x, y), inputColor);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if(tnear < 0.0f)
|
|
109
|
+
tnear = 0.0f; // clamp to near plane
|
|
110
|
+
|
|
111
|
+
// Traverse along ray from back to front, and keep the maximum intensity
|
|
112
|
+
temp = (float4)(0.0f, 0.0f, 0.0f, 1.0f);
|
|
113
|
+
// Recover original depth from depth buffer: https://stackoverflow.com/questions/6652253/getting-the-true-z-value-from-the-depth-buffer
|
|
114
|
+
float depthBuffer = (read_imagef(inputDepthFramebuffer, volumeSampler, (int2)(x,y)).x*2.0f - 1.0f); // turn depth into normalized coordinate ([-1, 1]
|
|
115
|
+
depthBuffer = 2.0f * zNear * zFar / (zFar + zNear - depthBuffer * (zFar - zNear));
|
|
116
|
+
int distance = min(tfar, depthBuffer); // Start at tfar or the value of the depth buffer, whatever is smallest
|
|
117
|
+
if(distance > tnear) {
|
|
118
|
+
while(distance > tnear) { // stop at tnear
|
|
119
|
+
float4 pos = rayOrigin + rayDirection * distance;
|
|
120
|
+
|
|
121
|
+
// read from 3D texture
|
|
122
|
+
float sample = (getPixelAsFloat(volume, volumeSampler, pos) - minimum) / (maximum - minimum);
|
|
123
|
+
|
|
124
|
+
//sample = 1.0f - sample;
|
|
125
|
+
temp = max(temp, (float4)(sample, sample, sample, 1));
|
|
126
|
+
|
|
127
|
+
distance -= 1;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Threshold, to show background
|
|
131
|
+
//if(temp.x <= 0.1)
|
|
132
|
+
// temp = inputColor;
|
|
133
|
+
} else {
|
|
134
|
+
temp = inputColor;
|
|
135
|
+
}
|
|
136
|
+
// write output color
|
|
137
|
+
write_imagef(framebuffer, (int2)(x, y), temp);
|
|
138
|
+
|
|
139
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
|
|
2
|
+
const sampler_t transferFuncSampler = CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;
|
|
3
|
+
const sampler_t volumeSampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;
|
|
4
|
+
|
|
5
|
+
// intersect ray with a box
|
|
6
|
+
// http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm
|
|
7
|
+
|
|
8
|
+
int intersectBox(float4 r_o, float4 r_d, float4 boxmin, float4 boxmax, float *tnear, float *tfar) {
|
|
9
|
+
// compute intersection of ray with all six bbox planes
|
|
10
|
+
float4 invR = (float4)(1.0f,1.0f,1.0f,1.0f) / r_d;
|
|
11
|
+
float4 tbot = invR * (boxmin - r_o);
|
|
12
|
+
float4 ttop = invR * (boxmax - r_o);
|
|
13
|
+
|
|
14
|
+
// re-order intersections to find smallest and largest on each axis
|
|
15
|
+
float4 tmin = min(ttop, tbot);
|
|
16
|
+
float4 tmax = max(ttop, tbot);
|
|
17
|
+
|
|
18
|
+
// find the largest tmin and the smallest tmax
|
|
19
|
+
float largest_tmin = max(max(tmin.x, tmin.y), max(tmin.x, tmin.z));
|
|
20
|
+
float smallest_tmax = min(min(tmax.x, tmax.y), min(tmax.x, tmax.z));
|
|
21
|
+
|
|
22
|
+
*tnear = largest_tmin;
|
|
23
|
+
*tfar = smallest_tmax;
|
|
24
|
+
|
|
25
|
+
return smallest_tmax > largest_tmin;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
uint rgbaFloatToInt(float4 rgba)
|
|
29
|
+
{
|
|
30
|
+
rgba.x = clamp(rgba.x,0.0f,1.0f);
|
|
31
|
+
rgba.y = clamp(rgba.y,0.0f,1.0f);
|
|
32
|
+
rgba.z = clamp(rgba.z,0.0f,1.0f);
|
|
33
|
+
rgba.w = clamp(rgba.w,0.0f,1.0f);
|
|
34
|
+
return ((uint)(rgba.w*255.0f)<<24) | ((uint)(rgba.z*255.0f)<<16) | ((uint)(rgba.y*255.0f)<<8) | (uint)(rgba.x*255.0f);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
float3 reflect(float3 I, float3 N) {
|
|
38
|
+
return I - 2.0f * dot(N, I) * N;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
float3 transformPosition(__constant float* transform, float3 pos) {
|
|
43
|
+
float4 position = {pos.x, pos.y, pos.z, 1};
|
|
44
|
+
float transformedPosition[4];
|
|
45
|
+
|
|
46
|
+
// Multiply with transform
|
|
47
|
+
// transform is column major
|
|
48
|
+
for(int i = 0; i < 4; i++) {
|
|
49
|
+
float sum = 0;
|
|
50
|
+
sum += transform[0 + i*4]*position.x;
|
|
51
|
+
sum += transform[1 + i*4]*position.y;
|
|
52
|
+
sum += transform[2 + i*4]*position.z;
|
|
53
|
+
sum += transform[3 + i*4]*position.w;
|
|
54
|
+
transformedPosition[i] = sum;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
float3 result = {transformedPosition[0], transformedPosition[1], transformedPosition[2]};
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
__kernel void volumeRender(
|
|
62
|
+
__read_only image3d_t volume,
|
|
63
|
+
__write_only image2d_t framebuffer,
|
|
64
|
+
__constant float* invViewMatrix,
|
|
65
|
+
__constant float* invViewMatrix2,
|
|
66
|
+
__read_only image2d_t inputFramebuffer,
|
|
67
|
+
__read_only image2d_t inputDepthFramebuffer,
|
|
68
|
+
__private float threshold,
|
|
69
|
+
__private float zNear,
|
|
70
|
+
__private float zFar
|
|
71
|
+
) {
|
|
72
|
+
|
|
73
|
+
const int width = get_image_width(framebuffer);
|
|
74
|
+
const int height = get_image_height(framebuffer);
|
|
75
|
+
|
|
76
|
+
// Grid position
|
|
77
|
+
const int x = get_global_id(0);
|
|
78
|
+
const int y = get_global_id(1);
|
|
79
|
+
|
|
80
|
+
// Normalized grid position
|
|
81
|
+
const float u = ((x / (float) width)*2.0f-1.0f)*((float)width/height); // compensate for aspect ratio != 1
|
|
82
|
+
const float v = ((y / (float) height)*2.0f-1.0f);
|
|
83
|
+
|
|
84
|
+
const float4 inputColor = read_imagef(inputFramebuffer, volumeSampler, (int2)(x,y));
|
|
85
|
+
|
|
86
|
+
// Bounding box of volume
|
|
87
|
+
const float4 boxMin = (float4)(0.0f, 0.0f, 0.0f,1.0f);
|
|
88
|
+
const float4 boxMax = (float4)(get_image_width(volume), get_image_height(volume), get_image_depth(volume), 1.0f);
|
|
89
|
+
// Maximum depth to cast ray inside the volume
|
|
90
|
+
|
|
91
|
+
// Calculate ray origin and direction
|
|
92
|
+
float4 rayOrigin;
|
|
93
|
+
float4 rayDirection;
|
|
94
|
+
|
|
95
|
+
// Ray origin is at the camera center
|
|
96
|
+
rayOrigin = (float4)(invViewMatrix[12], invViewMatrix[13], invViewMatrix[14], 1.0f);
|
|
97
|
+
|
|
98
|
+
// Calculate ray direction which is the direction of the vector (u,v,-2) - (0,0,0)
|
|
99
|
+
float4 temp = normalize(((float4)(u, v, -2.0f,0.0f)));
|
|
100
|
+
// Apply camera rotation on the ray direction vector
|
|
101
|
+
rayDirection.x = dot(temp, ((float4)(invViewMatrix[0],invViewMatrix[4],invViewMatrix[8], 0)));
|
|
102
|
+
rayDirection.y = dot(temp, ((float4)(invViewMatrix[1],invViewMatrix[5],invViewMatrix[9], 0)));
|
|
103
|
+
rayDirection.z = dot(temp, ((float4)(invViewMatrix[2],invViewMatrix[6],invViewMatrix[10], 0)));
|
|
104
|
+
rayDirection.w = 1.0f;
|
|
105
|
+
|
|
106
|
+
// Find the distance to where the ray hits the box
|
|
107
|
+
float tnear, tfar;
|
|
108
|
+
int hit = intersectBox(rayOrigin, rayDirection, boxMin, boxMax, &tnear, &tfar);
|
|
109
|
+
// write output color
|
|
110
|
+
if(!hit) {
|
|
111
|
+
// Ray doesn't hit the box at all
|
|
112
|
+
write_imagef(framebuffer, (int2)(x, y), inputColor);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if(tnear < 0.0f)
|
|
117
|
+
tnear = 0.0f; // clamp to near plane
|
|
118
|
+
|
|
119
|
+
// Traverse along ray from back to front, and keep the maximum intensity
|
|
120
|
+
temp = (float4)(0.0f, 0.0f, 0.0f, 1.0f);
|
|
121
|
+
// Recover original depth from depth buffer: https://stackoverflow.com/questions/6652253/getting-the-true-z-value-from-the-depth-buffer
|
|
122
|
+
float depth = (read_imagef(inputDepthFramebuffer, volumeSampler, (int2)(x,y)).x*2.0f - 1.0f); // turn depth into normalized coordinate ([-1, 1]
|
|
123
|
+
depth = 2.0f * zNear * zFar / (zFar + zNear - depth * (zFar - zNear));
|
|
124
|
+
float distance = tnear; // Start at tfar or the value of the depth buffer, whatever is smallest
|
|
125
|
+
while(distance < tfar) { // front to back
|
|
126
|
+
float4 pos = rayOrigin + rayDirection * distance;
|
|
127
|
+
|
|
128
|
+
// read from 3D texture
|
|
129
|
+
float sample = read_imagei(volume, volumeSampler, pos).x;
|
|
130
|
+
if(sample > threshold || distance > depth)
|
|
131
|
+
break;
|
|
132
|
+
|
|
133
|
+
distance += 0.5f;
|
|
134
|
+
}
|
|
135
|
+
if(distance >= tfar || distance > depth) {
|
|
136
|
+
temp = inputColor;
|
|
137
|
+
} else {
|
|
138
|
+
// Calculate normal at distance
|
|
139
|
+
float4 pos = rayOrigin + rayDirection * distance;
|
|
140
|
+
float3 normal;
|
|
141
|
+
normal.x = 0.5f * (read_imagei(volume, volumeSampler, pos + (float4)(1, 0, 0, 0)).x -
|
|
142
|
+
read_imagei(volume, volumeSampler, pos - (float4)(1, 0, 0, 0)).x);
|
|
143
|
+
normal.y = 0.5f * (read_imagei(volume, volumeSampler, pos + (float4)(0, 1, 0, 0)).x -
|
|
144
|
+
read_imagei(volume, volumeSampler, pos - (float4)(0, 1, 0, 0)).x);
|
|
145
|
+
normal.z = 0.5f * (read_imagei(volume, volumeSampler, pos + (float4)(0, 0, 1, 0)).x -
|
|
146
|
+
read_imagei(volume, volumeSampler, pos - (float4)(0, 0, 1, 0)).x);
|
|
147
|
+
normal = normalize(normal);
|
|
148
|
+
normal = transformPosition(invViewMatrix2, normal);
|
|
149
|
+
normal = normalize(normal);
|
|
150
|
+
|
|
151
|
+
// Calculate color with light
|
|
152
|
+
float3 objectColor = {0.0, 1.0, 0.0};
|
|
153
|
+
float3 lightColor = {0.7, 0.7, 0.7};
|
|
154
|
+
float3 ambientColor = {0.2, 0.2, 0.2};
|
|
155
|
+
float3 specularColor = {1, 1, 1};
|
|
156
|
+
float3 LightPos = {0, 0, 0};
|
|
157
|
+
float3 ViewPos = {0, 0, 0};
|
|
158
|
+
float shininess = 16.0f;
|
|
159
|
+
|
|
160
|
+
// TODO fix, look at TriangleRenderer.vert
|
|
161
|
+
LightPos = transformPosition(invViewMatrix2, LightPos);
|
|
162
|
+
ViewPos = transformPosition(invViewMatrix2, ViewPos);
|
|
163
|
+
|
|
164
|
+
float3 lightDir = normalize(LightPos - pos.xyz);
|
|
165
|
+
float diff = max(dot(normal, lightDir), 0.0f);
|
|
166
|
+
float3 diffuse = lightColor * (diff * objectColor);
|
|
167
|
+
float3 viewDir = normalize(ViewPos - pos.xyz);
|
|
168
|
+
float3 reflectDir = reflect(-lightDir, normal);
|
|
169
|
+
float spec = pow(max(dot(viewDir, reflectDir), 0.0f), shininess);
|
|
170
|
+
float3 specular = lightColor * (spec * specularColor);
|
|
171
|
+
float3 ambient = lightColor * ambientColor;
|
|
172
|
+
float3 result = ambient + diffuse + specular;
|
|
173
|
+
temp = (float4)(result.x, result.y, result.z, 1);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// write output color
|
|
177
|
+
write_imagef(framebuffer, (int2)(x, y), temp);
|
|
178
|
+
}
|