diff --git a/Source/Raymarcher/Private/Rendering/OctreeShaders.cpp b/Source/Raymarcher/Private/Rendering/OctreeShaders.cpp deleted file mode 100644 index f50bb1f..0000000 --- a/Source/Raymarcher/Private/Rendering/OctreeShaders.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2021 Tomas Bartipan and Technical University of Munich. -// Licensed under MIT license - See License.txt for details. -// Special credits go to : Temaran (compute shader tutorial), TheHugeManatee (original concept, supervision) and Ryan Brucks -// (original raymarching code). - -#include "Rendering/OctreeShaders.h" - -#include "Engine/TextureRenderTargetVolume.h" -#include "Runtime/RenderCore/Public/RenderUtils.h" -#include "Util/UtilityShaders.h" - -#if !UE_BUILD_SHIPPING -#pragma optimize("", off) -#endif - -#define LOCTEXT_NAMESPACE "RaymarchPlugin" - -IMPLEMENT_GLOBAL_SHADER(FGenerateOctreeShader, "/Raymarcher/Private/GenerateOctreeShader.usf", "MainComputeShader", SF_Compute); - -// For making statistics about GPU use - Generating Octree. -DECLARE_FLOAT_COUNTER_STAT(TEXT("GeneratingOctree"), STAT_GPU_GeneratingOctree, STATGROUP_GPU); -DECLARE_GPU_STAT_NAMED(GPUGeneratingOctree, TEXT("GeneratingOctree_")); - -// #TODO profile with different dimensions. -#define OCTREE_NUM_THREADS_PER_GROUP_DIMENSION 1 // This has to be the same as in the compute shader's spec [X, X, X] -#define LEAF_NODE_SIZE 8 // Provided to the shader as a uniform. - -void GenerateOctreeForVolume_RenderThread(FRHICommandListImmediate& RHICmdList, FBasicRaymarchRenderingResources Resources) -{ - check(IsInRenderingThread()); - constexpr int32 GroupSizePerDimension = OCTREE_NUM_THREADS_PER_GROUP_DIMENSION * LEAF_NODE_SIZE; - - // For GPU profiling. - SCOPED_DRAW_EVENTF(RHICmdList, GenerateOctreeForVolume_RenderThread, TEXT("GeneratingOctree")); - SCOPED_GPU_STAT(RHICmdList, GPUGeneratingOctree); - - TShaderMapRef ComputeShader(GetGlobalShaderMap(ERHIFeatureLevel::SM5)); - FRHIComputeShader* ShaderRHI = ComputeShader.GetComputeShader(); - SetComputePipelineState(RHICmdList, ShaderRHI); - RHICmdList.Transition(FRHITransitionInfo(Resources.OctreeUAVRef, ERHIAccess::UAVGraphics, ERHIAccess::UAVCompute)); - - ComputeShader->SetGeneratingResources(RHICmdList, ShaderRHI, - Resources.DataVolumeTextureRef->GetResource()->TextureRHI->GetTexture3D(), - Resources.OctreeVolumeRenderTarget->MippedTexture3DRTResource, LEAF_NODE_SIZE, - Resources.OctreeVolumeRenderTarget->GetNumMips()); - - const uint32 GroupSizeX = FMath::DivideAndRoundUp(Resources.OctreeVolumeRenderTarget->SizeX, GroupSizePerDimension); - const uint32 GroupSizeY = FMath::DivideAndRoundUp(Resources.OctreeVolumeRenderTarget->SizeY, GroupSizePerDimension); - const uint32 GroupSizeZ = FMath::DivideAndRoundUp(Resources.OctreeVolumeRenderTarget->SizeZ, GroupSizePerDimension); - RHICmdList.DispatchComputeShader(GroupSizeX, GroupSizeY, GroupSizeZ); - - ComputeShader->UnbindResources(RHICmdList, ShaderRHI); - RHICmdList.Transition(FRHITransitionInfo(Resources.OctreeUAVRef, ERHIAccess::UAVCompute, ERHIAccess::UAVGraphics)); -} - -#undef LOCTEXT_NAMESPACE - -#if !UE_BUILD_SHIPPING -#pragma optimize("", on) -#endif diff --git a/Source/Raymarcher/Private/Util/RaymarchUtils.cpp b/Source/Raymarcher/Private/Util/RaymarchUtils.cpp index bb3bb99..49a8aa0 100644 --- a/Source/Raymarcher/Private/Util/RaymarchUtils.cpp +++ b/Source/Raymarcher/Private/Util/RaymarchUtils.cpp @@ -17,7 +17,6 @@ #include "SceneInterface.h" #include "SceneUtils.h" #include "ShaderParameterUtils.h" -#include "Rendering/OctreeShaders.h" #include "VolumeTextureToolkit/Public/TextureUtilities.h" #include @@ -97,7 +96,7 @@ void URaymarchUtils::GenerateOctree(FBasicRaymarchRenderingResources& Resources) ENQUEUE_RENDER_COMMAND(CaptureCommand) ([=](FRHICommandListImmediate& RHICmdList) { - GenerateOctreeForVolume_RenderThread(RHICmdList, Resources); + // GenerateOctreeForVolume_RenderThread(RHICmdList, Resources); }); } diff --git a/Source/Raymarcher/Public/Rendering/OctreeShaders.h b/Source/Raymarcher/Public/Rendering/OctreeShaders.h deleted file mode 100644 index a80fab3..0000000 --- a/Source/Raymarcher/Public/Rendering/OctreeShaders.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2021 Tomas Bartipan and Technical University of Munich. -// Licensed under MIT license - See License.txt for details. -// Special credits go to : Temaran (compute shader tutorial), TheHugeManatee (original concept, supervision) and Ryan Brucks -// (original raymarching code). - -#pragma once - -#include "CoreMinimal.h" -#include "GlobalShader.h" -#include "RHICommandList.h" -#include "Rendering/RaymarchTypes.h" -#include "ShaderParameterUtils.h" -#include "ShaderParameters.h" - -void GenerateOctreeForVolume_RenderThread(FRHICommandListImmediate& RHICmdList, FBasicRaymarchRenderingResources Resources); - -// A shader that generates a TF-independent octree accelerator structure for a volume. -class FGenerateOctreeShader : public FGlobalShader -{ - DECLARE_EXPORTED_SHADER_TYPE(FGenerateOctreeShader, Global, RAYMARCHER_API); - -public: - FGenerateOctreeShader() : FGlobalShader() - { - } - - ~FGenerateOctreeShader(){}; - - FGenerateOctreeShader(const ShaderMetaType::CompiledShaderInitializerType& Initializer) : FGlobalShader(Initializer) - { - Volume.Bind(Initializer.ParameterMap, TEXT("Volume"), SPF_Mandatory); - OctreeVolume0.Bind(Initializer.ParameterMap, TEXT("OctreeVolumeMip0"), SPF_Mandatory); - OctreeVolume1.Bind(Initializer.ParameterMap, TEXT("OctreeVolumeMip1"), SPF_Mandatory); - OctreeVolume2.Bind(Initializer.ParameterMap, TEXT("OctreeVolumeMip2"), SPF_Mandatory); - OctreeVolume3.Bind(Initializer.ParameterMap, TEXT("OctreeVolumeMip3"), SPF_Mandatory); - MinMaxValues.Bind(Initializer.ParameterMap, TEXT("MinMaxValues"), SPF_Mandatory); - LeafNodeSize.Bind(Initializer.ParameterMap, TEXT("LeafNodeSize"), SPF_Mandatory); - NumberOfMips.Bind(Initializer.ParameterMap, TEXT("NumberOfMips"), SPF_Mandatory); - } - - void SetGeneratingResources(FRHICommandListImmediate& RHICmdList, FRHIComputeShader* ShaderRHI, const FTexture3DRHIRef pVolume, - const FTexture3DComputeResource* ComputeResource, int InLeafNodeSize, int InNumberOfMips) - { - SetTextureParameter(RHICmdList, ShaderRHI, Volume, pVolume); - SetUAVParameter(RHICmdList, ShaderRHI, OctreeVolume0, ComputeResource->UnorderedAccessViewRHIs[0]); - SetUAVParameter(RHICmdList, ShaderRHI, OctreeVolume1, ComputeResource->UnorderedAccessViewRHIs[1]); - SetUAVParameter(RHICmdList, ShaderRHI, OctreeVolume2, ComputeResource->UnorderedAccessViewRHIs[2]); - SetUAVParameter(RHICmdList, ShaderRHI, OctreeVolume3, ComputeResource->UnorderedAccessViewRHIs[3]); - SetShaderValue(RHICmdList, ShaderRHI, MinMaxValues, FVector2f(0.0, 1.0)); - SetShaderValue(RHICmdList, ShaderRHI, LeafNodeSize, InLeafNodeSize); - SetShaderValue(RHICmdList, ShaderRHI, NumberOfMips, InNumberOfMips); - } - - void UnbindResources(FRHICommandListImmediate& RHICmdList, FRHIComputeShader* ShaderRHI) - { - SetTextureParameter(RHICmdList, ShaderRHI, Volume, nullptr); - SetUAVParameter(RHICmdList, ShaderRHI, OctreeVolume0, nullptr); - SetUAVParameter(RHICmdList, ShaderRHI, OctreeVolume1, nullptr); - SetUAVParameter(RHICmdList, ShaderRHI, OctreeVolume2, nullptr); - SetUAVParameter(RHICmdList, ShaderRHI, OctreeVolume3, nullptr); - } - -protected: - // Volume texture + transfer function resource parameters - LAYOUT_FIELD(FShaderResourceParameter, Volume); - - // OctreeVolume volume mips to modify. - LAYOUT_FIELD(FShaderResourceParameter, OctreeVolume0); - LAYOUT_FIELD(FShaderResourceParameter, OctreeVolume1); - LAYOUT_FIELD(FShaderResourceParameter, OctreeVolume2); - LAYOUT_FIELD(FShaderResourceParameter, OctreeVolume3); - - // Parameter for the added/removed multiplier. - LAYOUT_FIELD(FShaderParameter, MinMaxValues); - - // Length of the size of the cube that creates a single leaf. (Each leaf node will have LeafNodeSize^3 voxels) - LAYOUT_FIELD(FShaderParameter, LeafNodeSize); - - // Number of mips to generate. - LAYOUT_FIELD(FShaderParameter, NumberOfMips) -}; \ No newline at end of file diff --git a/Source/Raymarcher/Shaders/Private/GenerateOctreeShader.usf b/Source/Raymarcher/Shaders/Private/GenerateOctreeShader.usf deleted file mode 100644 index d9fe379..0000000 --- a/Source/Raymarcher/Shaders/Private/GenerateOctreeShader.usf +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2021 Tomas Bartipan and Technical University of Munich. -// Licensed under MIT license - See License.txt for details. -// Special credits go to : Temaran (compute shader tutorial), TheHugeManatee (original concept, supervision) and Ryan Brucks -// (original raymarching code). - -// -// This shader generates an Octree acceleration structure. -// - -#include "/Engine/Private/Common.ush" -#include "OctreeCommon.usf" - -// The Octree Volume texture we're creating in this shader. -RWTexture3D OctreeVolumeMip0; -RWTexture3D OctreeVolumeMip1; -RWTexture3D OctreeVolumeMip2; -RWTexture3D OctreeVolumeMip3; - -// The minimum and maximum values found in the volume. -float2 MinMaxValues; - -// The Volume we're propagating light through. -Texture3D Volume; - -int LeafNodeSize = 8; -int NumberOfMips = 4; - -[numthreads(1, 1, 1)] -void MainComputeShader(uint3 voxelLoc : SV_DispatchThreadID) -{ - // Position in Leaf space (index of the leaf in the octree that this shader will generate) - int3 Pos = int3(voxelLoc.x, voxelLoc.y, voxelLoc.z); - int3 ThreadOffset = Pos * LeafNodeSize; - - // Copy the data from the input volume to maximal resolution mip first. - for (int x = 0; x < LeafNodeSize; x++) - { - for (int y = 0; y < LeafNodeSize; y++) - { - for (int z = 0; z < LeafNodeSize; z++) - { - int3 LocalPos = int3(x, y, z); - int3 ActualPos = ThreadOffset + LocalPos; - // For now, just copy volume value. - OctreeVolumeMip0[ActualPos] = Volume.Load(int4(ActualPos, 0), 0).r * MinMaxValues.y; - } - } - } - - // Make sure the number of mips defined equals the number of UAVs mips. - const int HardcodedNumberOfMips = 4; - if(HardcodedNumberOfMips != NumberOfMips) - { - return; - } - - // Generate the rest of mip levels (1 to NumberOfMips). - RWTexture3D Mips[HardcodedNumberOfMips] = { OctreeVolumeMip0, OctreeVolumeMip1, OctreeVolumeMip2, OctreeVolumeMip3 }; - for (int Mip = 1; Mip < HardcodedNumberOfMips; Mip++) - { - RWTexture3D MipBuffer = Mips[Mip]; - - int Divisor = 1; - for (int i = 0; i < Mip; i++) - { - Divisor *= 2; - } - - // Offset that declare the starting position of the mip we load data from (Mip - 1). - int3 LowerMipOffset = (2 * ThreadOffset) / Divisor; - for (int x = 0; x < LeafNodeSize / Divisor; x++) - { - for (int y = 0; y < LeafNodeSize / Divisor; y++) - { - for (int z = 0; z < LeafNodeSize / Divisor; z++) - { - int3 LocalPos = int3(x, y, z); - - // Multiply LocalPos by two to get the correct position we can load data from in range <0,1>. - int3 CurrentPositionOffset = LowerMipOffset + LocalPos * 2; - - // For now save only the maximal value from all 8 nodes. - float Max = 0; - for (int a = 0; a < 2; a ++) - { - for (int b = 0; b < 2; b ++) - { - for (int c = 0; c < 2; c ++) - { - // Take current offset and append the final offset value to get the correct data position. - int3 FinalPos = CurrentPositionOffset + int3(a, b, c); - float NodeValue = Mips[Mip-1][FinalPos]; - if(Max < NodeValue) - { - Max = NodeValue; - } - } - } - } - int3 MipPos = ThreadOffset/Divisor + LocalPos; - // Insert the value to the Mip. - MipBuffer[MipPos] = Max; - } - } - } - } -} diff --git a/Source/VolumeTextureToolkit/Private/VolumeAsset/DICOMParser/DICOMAppHelper.cpp b/Source/VolumeTextureToolkit/Private/VolumeAsset/DICOMParser/DICOMAppHelper.cpp index f6955b0..30ae9b2 100644 --- a/Source/VolumeTextureToolkit/Private/VolumeAsset/DICOMParser/DICOMAppHelper.cpp +++ b/Source/VolumeTextureToolkit/Private/VolumeAsset/DICOMParser/DICOMAppHelper.cpp @@ -527,7 +527,7 @@ void DICOMAppHelper::ImagePositionPatientCallback( if (val) { - sscanf_s(reinterpret_cast(val), "%f\\%f\\%f", &ord.ImagePositionPatient[0], &ord.ImagePositionPatient[1], + sscanf(reinterpret_cast(val), "%f\\%f\\%f", &ord.ImagePositionPatient[0], &ord.ImagePositionPatient[1], &ord.ImagePositionPatient[2]); } else @@ -550,7 +550,7 @@ void DICOMAppHelper::ImagePositionPatientCallback( if (val) { // file found, add new values - sscanf_s(reinterpret_cast(val), "%f\\%f\\%f", &(*it).second.ImagePositionPatient[0], + sscanf(reinterpret_cast(val), "%f\\%f\\%f", &(*it).second.ImagePositionPatient[0], &(*it).second.ImagePositionPatient[1], &(*it).second.ImagePositionPatient[2]); } else @@ -578,7 +578,7 @@ void DICOMAppHelper::ImageOrientationPatientCallback( DICOMOrderingElements ord; if (val) { - sscanf_s(reinterpret_cast(val), "%f\\%f\\%f\\%f\\%f\\%f", &ord.ImageOrientationPatient[0], + sscanf(reinterpret_cast(val), "%f\\%f\\%f\\%f\\%f\\%f", &ord.ImageOrientationPatient[0], &ord.ImageOrientationPatient[1], &ord.ImageOrientationPatient[2], &ord.ImageOrientationPatient[3], &ord.ImageOrientationPatient[4], &ord.ImageOrientationPatient[5]); } @@ -605,7 +605,7 @@ void DICOMAppHelper::ImageOrientationPatientCallback( // file found, add new values if (val) { - sscanf_s(reinterpret_cast(val), "%f\\%f\\%f\\%f\\%f\\%f", &(*it).second.ImageOrientationPatient[0], + sscanf(reinterpret_cast(val), "%f\\%f\\%f\\%f\\%f\\%f", &(*it).second.ImageOrientationPatient[0], &(*it).second.ImageOrientationPatient[1], &(*it).second.ImageOrientationPatient[2], &(*it).second.ImageOrientationPatient[3], &(*it).second.ImageOrientationPatient[4], &(*it).second.ImageOrientationPatient[5]); @@ -698,7 +698,7 @@ void DICOMAppHelper::PixelSpacingCallback( { if (group == 0x0028 && element == 0x0030) { - if (!val || sscanf_s(reinterpret_cast(val), "%f\\%f", &this->PixelSpacing[0], &this->PixelSpacing[1]) != 2) + if (!val || sscanf(reinterpret_cast(val), "%f\\%f", &this->PixelSpacing[0], &this->PixelSpacing[1]) != 2) { this->PixelSpacing[0] = this->PixelSpacing[1] = 0.0; } diff --git a/Source/VolumeTextureToolkit/Private/VolumeAsset/DICOMParser/DICOMFile.cpp b/Source/VolumeTextureToolkit/Private/VolumeAsset/DICOMParser/DICOMFile.cpp index 0c44540..2021d15 100644 --- a/Source/VolumeTextureToolkit/Private/VolumeAsset/DICOMParser/DICOMFile.cpp +++ b/Source/VolumeTextureToolkit/Private/VolumeAsset/DICOMParser/DICOMFile.cpp @@ -230,7 +230,7 @@ float DICOMFile::ReadAsciiFloat(int len) data >> ret; delete [] val2; #else - sscanf_s(val, "%e", &ret); + sscanf(val, "%e", &ret); #endif std::cout << "Read ASCII float: " << ret << std::endl; @@ -259,7 +259,7 @@ int DICOMFile::ReadAsciiInt(int len) data >> ret; delete [] val2; #else - sscanf_s(val, "%d", &ret); + sscanf(val, "%d", &ret); #endif std::cout << "Read ASCII int: " << ret << std::endl; diff --git a/Source/VolumeTextureToolkit/Public/VolumeAsset/DICOMParser/DICOMConfig.h b/Source/VolumeTextureToolkit/Public/VolumeAsset/DICOMParser/DICOMConfig.h index 0ea13da..9535fa4 100644 --- a/Source/VolumeTextureToolkit/Public/VolumeAsset/DICOMParser/DICOMConfig.h +++ b/Source/VolumeTextureToolkit/Public/VolumeAsset/DICOMParser/DICOMConfig.h @@ -29,7 +29,7 @@ #include #include -#define DICOM_EXPORT __declspec(dllexport) +#define DICOM_EXPORT #define DICOM_EXPIMP_TEMPLATE #endif // __DICOM_CONFIG_H_