diff --git a/Assets/Editor/VolumeRenderedObjectCustomInspector.cs b/Assets/Editor/VolumeRenderedObjectCustomInspector.cs index 300bebc7..be437972 100644 --- a/Assets/Editor/VolumeRenderedObjectCustomInspector.cs +++ b/Assets/Editor/VolumeRenderedObjectCustomInspector.cs @@ -6,6 +6,7 @@ namespace UnityVolumeRendering [CustomEditor(typeof(VolumeRenderedObject))] public class VolumeRenderedObjectCustomInspector : Editor { + private bool clipSettings = false; private bool tfSettings = true; private bool lightSettings = true; private bool otherSettings = true; @@ -20,6 +21,30 @@ public override void OnInspectorGUI() if (newRenderMode != oldRenderMode) volrendObj.SetRenderMode(newRenderMode); + #region ClippingData + EditorGUILayout.Space(); + clipSettings = EditorGUILayout.Foldout(clipSettings, "Clipping Settings"); + + if (clipSettings) + { + // Clip dim 1 + Vector2 ClipDim1 = volrendObj.GetClipDim1(); + EditorGUILayout.MinMaxSlider("Clipping Dimension x", ref ClipDim1.x, ref ClipDim1.y, 0.0f, 1.0f); + + // Clip dim 2 + Vector2 ClipDim2 = volrendObj.GetClipDim2(); + EditorGUILayout.MinMaxSlider("Clipping Dimension y", ref ClipDim2.x, ref ClipDim2.y, 0.0f, 1.0f); + + // Clip dim 3 + Vector2 ClipDim3 = volrendObj.GetClipDim3(); + EditorGUILayout.MinMaxSlider("Clipping Dimension y", ref ClipDim3.x, ref ClipDim3.y, 0.0f, 1.0f); + + // setting clip dims + volrendObj.SetClipDims(ClipDim1, ClipDim2, ClipDim3); + } + #endregion EndClippingData + + // Visibility window Vector2 visibilityWindow = volrendObj.GetVisibilityWindow(); EditorGUILayout.MinMaxSlider("Visible value range", ref visibilityWindow.x, ref visibilityWindow.y, 0.0f, 1.0f); diff --git a/Assets/Materials/DirectVolumeRenderingMaterial.mat b/Assets/Materials/DirectVolumeRenderingMaterial.mat index 0686b26e..85cc7773 100644 --- a/Assets/Materials/DirectVolumeRenderingMaterial.mat +++ b/Assets/Materials/DirectVolumeRenderingMaterial.mat @@ -92,5 +92,7 @@ Material: - _UVSec: 0 - _ZWrite: 1 m_Colors: + - _ClipDimMax: {r: 1, g: 1, b: 1, a: 1} + - _ClipDimMin: {r: 0, g: 0, b: 0, a: 1} - _Color: {r: 1, g: 1, b: 1, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/Scripts/Importing/ImageFileImporter/Interface/SimpleITK.meta b/Assets/Scripts/SampleScene.meta similarity index 77% rename from Assets/Scripts/Importing/ImageFileImporter/Interface/SimpleITK.meta rename to Assets/Scripts/SampleScene.meta index 78570c8c..85906d9c 100644 --- a/Assets/Scripts/Importing/ImageFileImporter/Interface/SimpleITK.meta +++ b/Assets/Scripts/SampleScene.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2a823b11bfaf79741bf3312984c336fe +guid: b29785c43f69803468642c527b79dc58 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Scripts/VolumeObject/VolumeRenderedObject.cs b/Assets/Scripts/VolumeObject/VolumeRenderedObject.cs index c4232a04..5e3ea664 100644 --- a/Assets/Scripts/VolumeObject/VolumeRenderedObject.cs +++ b/Assets/Scripts/VolumeObject/VolumeRenderedObject.cs @@ -36,6 +36,13 @@ public class VolumeRenderedObject : MonoBehaviour private bool cubicInterpolationEnabled = false; private CrossSectionManager crossSectionManager; + + [SerializeField, HideInInspector] + private Vector2 ClipDim1 = new Vector2(0.0f, 1.0f); + [SerializeField, HideInInspector] + private Vector2 ClipDim2 = new Vector2(0.0f, 1.0f); + [SerializeField, HideInInspector] + private Vector2 ClipDim3 = new Vector2(0.0f, 1.0f); public SlicingPlane CreateSlicingPlane() { @@ -138,6 +145,47 @@ public Vector2 GetVisibilityWindow() return visibilityWindow; } + public void SetClipDims(Vector2 dim1, Vector2 dim2, Vector2 dim3) + { + bool different = false; + + if (dim1 != ClipDim1) + { + ClipDim1 = dim1; + different = true; + } + if (dim2 != ClipDim2) + { + ClipDim2 = dim2; + different = true; + } + if (dim3 != ClipDim3) + { + ClipDim3 = dim3; + different = true; + } + if (different) + { + UpdateMaterialProperties(); + } + } + + public Vector2 GetClipDim1() + { + return ClipDim1; + } + + public Vector2 GetClipDim2() + { + return ClipDim2; + } + + public Vector2 GetClipDim3() + { + return ClipDim3; + } + + public bool GetRayTerminationEnabled() { return rayTerminationEnabled; @@ -241,6 +289,9 @@ private void UpdateMaterialProperties() meshRenderer.sharedMaterial.SetFloat("_MaxVal", visibilityWindow.y); meshRenderer.sharedMaterial.SetVector("_TextureSize", new Vector3(dataset.dimX, dataset.dimY, dataset.dimZ)); + meshRenderer.sharedMaterial.SetVector("_ClipDimMin", new Vector4(ClipDim1.x, ClipDim2.x, ClipDim3.x, 1f)); + meshRenderer.sharedMaterial.SetVector("_ClipDimMax", new Vector4(ClipDim1.y, ClipDim2.y, ClipDim3.y, 1f)); + if (rayTerminationEnabled) meshRenderer.sharedMaterial.EnableKeyword("RAY_TERMINATE_ON"); else diff --git a/Assets/Shaders/DirectVolumeRenderingShader.shader b/Assets/Shaders/DirectVolumeRenderingShader.shader index 2d4e2727..1e4a32f7 100644 --- a/Assets/Shaders/DirectVolumeRenderingShader.shader +++ b/Assets/Shaders/DirectVolumeRenderingShader.shader @@ -1,476 +1,486 @@ Shader "VolumeRendering/DirectVolumeRenderingShader" { - Properties - { - _DataTex ("Data Texture (Generated)", 3D) = "" {} - _GradientTex("Gradient Texture (Generated)", 3D) = "" {} - _NoiseTex("Noise Texture (Generated)", 2D) = "white" {} - _TFTex("Transfer Function Texture (Generated)", 2D) = "" {} - _MinVal("Min val", Range(0.0, 1.0)) = 0.0 - _MaxVal("Max val", Range(0.0, 1.0)) = 1.0 - } - SubShader - { - Tags { "Queue" = "Transparent" "RenderType" = "Transparent" } - LOD 100 - Cull Front - ZTest LEqual - ZWrite On - Blend SrcAlpha OneMinusSrcAlpha - - Pass - { - CGPROGRAM - #pragma multi_compile MODE_DVR MODE_MIP MODE_SURF - #pragma multi_compile __ TF2D_ON - #pragma multi_compile __ CROSS_SECTION_ON - #pragma multi_compile __ LIGHTING_ON - #pragma multi_compile DEPTHWRITE_ON DEPTHWRITE_OFF - #pragma multi_compile __ DVR_BACKWARD_ON - #pragma multi_compile __ RAY_TERMINATE_ON - #pragma multi_compile __ USE_MAIN_LIGHT - #pragma multi_compile __ CUBIC_INTERPOLATION_ON - #pragma vertex vert - #pragma fragment frag - - #include "UnityCG.cginc" - #include "TricubicSampling.cginc" - - #define AMBIENT_LIGHTING_FACTOR 0.5 - #define JITTER_FACTOR 5.0 - - struct vert_in - { - float4 vertex : POSITION; - float4 normal : NORMAL; - float2 uv : TEXCOORD0; - }; - - struct frag_in - { - float4 vertex : SV_POSITION; - float2 uv : TEXCOORD0; - float3 vertexLocal : TEXCOORD1; - float3 normal : NORMAL; - }; - - struct frag_out - { - float4 colour : SV_TARGET; -#if DEPTHWRITE_ON - float depth : SV_DEPTH; -#endif - }; - - sampler3D _DataTex; - sampler3D _GradientTex; - sampler2D _NoiseTex; - sampler2D _TFTex; - - float _MinVal; - float _MaxVal; - float3 _TextureSize; - -#if CROSS_SECTION_ON -#define CROSS_SECTION_TYPE_PLANE 1 -#define CROSS_SECTION_TYPE_BOX_INCL 2 -#define CROSS_SECTION_TYPE_BOX_EXCL 3 - float4x4 _CrossSectionMatrices[8]; - float _CrossSectionTypes[8]; - int _NumCrossSections; -#endif - - struct RayInfo - { - float3 startPos; - float3 endPos; - float3 direction; - float2 aabbInters; - }; - - struct RaymarchInfo - { - RayInfo ray; - int numSteps; - float numStepsRecip; - float stepSize; - }; - - float3 getViewRayDir(float3 vertexLocal) - { - if(unity_OrthoParams.w == 0) - { - // Perspective - return normalize(ObjSpaceViewDir(float4(vertexLocal, 0.0f))); - } - else - { - // Orthographic - float3 camfwd = mul((float3x3)unity_CameraToWorld, float3(0,0,-1)); - float4 camfwdobjspace = mul(unity_WorldToObject, camfwd); - return normalize(camfwdobjspace); - } - } - - // Find ray intersection points with axis aligned bounding box - float2 intersectAABB(float3 rayOrigin, float3 rayDir, float3 boxMin, float3 boxMax) - { - float3 tMin = (boxMin - rayOrigin) / rayDir; - float3 tMax = (boxMax - rayOrigin) / rayDir; - float3 t1 = min(tMin, tMax); - float3 t2 = max(tMin, tMax); - float tNear = max(max(t1.x, t1.y), t1.z); - float tFar = min(min(t2.x, t2.y), t2.z); - return float2(tNear, tFar); - }; - - // Get a ray for the specified fragment (back-to-front) - RayInfo getRayBack2Front(float3 vertexLocal) - { - RayInfo ray; - ray.direction = getViewRayDir(vertexLocal); - ray.startPos = vertexLocal + float3(0.5f, 0.5f, 0.5f); - // Find intersections with axis aligned boundinng box (the volume) - ray.aabbInters = intersectAABB(ray.startPos, ray.direction, float3(0.0, 0.0, 0.0), float3(1.0f, 1.0f, 1.0)); - - // Check if camera is inside AABB - const float3 farPos = ray.startPos + ray.direction * ray.aabbInters.y - float3(0.5f, 0.5f, 0.5f); - float4 clipPos = UnityObjectToClipPos(float4(farPos, 1.0f)); - ray.aabbInters += min(clipPos.w, 0.0); - - ray.endPos = ray.startPos + ray.direction * ray.aabbInters.y; - return ray; - } - - // Get a ray for the specified fragment (front-to-back) - RayInfo getRayFront2Back(float3 vertexLocal) - { - RayInfo ray = getRayBack2Front(vertexLocal); - ray.direction = -ray.direction; - float3 tmp = ray.startPos; - ray.startPos = ray.endPos; - ray.endPos = tmp; - return ray; - } - - RaymarchInfo initRaymarch(RayInfo ray, int maxNumSteps) - { - RaymarchInfo raymarchInfo; - raymarchInfo.stepSize = 1.732f/*greatest distance in box*/ / maxNumSteps; - raymarchInfo.numSteps = (int)clamp(abs(ray.aabbInters.x - ray.aabbInters.y) / raymarchInfo.stepSize, 1, maxNumSteps); - raymarchInfo.numStepsRecip = 1.0 / raymarchInfo.numSteps; - return raymarchInfo; - } - - // Gets the colour from a 1D Transfer Function (x = density) - float4 getTF1DColour(float density) - { - return tex2Dlod(_TFTex, float4(density, 0.0f, 0.0f, 0.0f)); - } - - // Gets the colour from a 2D Transfer Function (x = density, y = gradient magnitude) - float4 getTF2DColour(float density, float gradientMagnitude) - { - return tex2Dlod(_TFTex, float4(density, gradientMagnitude, 0.0f, 0.0f)); - } - - // Gets the density at the specified position - float getDensity(float3 pos) - { -#if CUBIC_INTERPOLATION_ON - return interpolateTricubicFast(_DataTex, float3(pos.x, pos.y, pos.z), _TextureSize); -#else - return tex3Dlod(_DataTex, float4(pos.x, pos.y, pos.z, 0.0f)); -#endif - } - - // Gets the gradient at the specified position - float3 getGradient(float3 pos) - { -#if CUBIC_INTERPOLATION_ON - return interpolateTricubicFast(_GradientTex, float3(pos.x, pos.y, pos.z), _TextureSize).rgb; -#else - return tex3Dlod(_GradientTex, float4(pos.x, pos.y, pos.z, 0.0f)).rgb; -#endif - } - - // Get the light direction (using main light or view direction, based on setting) - float3 getLightDirection(float3 viewDir) - { -#if defined(USE_MAIN_LIGHT) - return normalize(mul(unity_WorldToObject, _WorldSpaceLightPos0.xyz)); -#else - return viewDir; -#endif - } - - // Performs lighting calculations, and returns a modified colour. - float3 calculateLighting(float3 col, float3 normal, float3 lightDir, float3 eyeDir, float specularIntensity) - { - // Invert normal if facing opposite direction of view direction. - // Optimised version of: if(dot(normal, eyeDir) < 0.0) normal *= -1.0 - normal *= (step(0.0, dot(normal, eyeDir)) * 2.0 - 1.0); - - float ndotl = max(lerp(0.0f, 1.5f, dot(normal, lightDir)), AMBIENT_LIGHTING_FACTOR); - float3 diffuse = ndotl * col; - float3 v = eyeDir; - float3 r = normalize(reflect(-lightDir, normal)); - float rdotv = max( dot( r, v ), 0.0 ); - float3 specular = pow(rdotv, 32.0f) * float3(1.0f, 1.0f, 1.0f) * specularIntensity; - return diffuse + specular; - } - - // Converts local position to depth value - float localToDepth(float3 localPos) - { - float4 clipPos = UnityObjectToClipPos(float4(localPos, 1.0f)); - -#if defined(SHADER_API_GLCORE) || defined(SHADER_API_OPENGL) || defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) - return (clipPos.z / clipPos.w) * 0.5 + 0.5; -#else - return clipPos.z / clipPos.w; -#endif - } - - bool IsCutout(float3 currPos) - { -#if CROSS_SECTION_ON - // Move the reference in the middle of the mesh, like the pivot - float4 pos = float4(currPos - float3(0.5f, 0.5f, 0.5f), 1.0f); - - bool clipped = false; - for (int i = 0; i < _NumCrossSections && !clipped; ++i) - { - const int type = (int)_CrossSectionTypes[i]; - const float4x4 mat = _CrossSectionMatrices[i]; - - // Convert from model space to plane's vector space - float3 planeSpacePos = mul(mat, pos); - if (type == CROSS_SECTION_TYPE_PLANE) - clipped = planeSpacePos.z > 0.0f; - else if(type == CROSS_SECTION_TYPE_BOX_INCL) - clipped = !(planeSpacePos.x >= -0.5f && planeSpacePos.x <= 0.5f && planeSpacePos.y >= -0.5f && planeSpacePos.y <= 0.5f && planeSpacePos.z >= -0.5f && planeSpacePos.z <= 0.5f); - else if(type == CROSS_SECTION_TYPE_BOX_EXCL) - clipped = planeSpacePos.x >= -0.5f && planeSpacePos.x <= 0.5f && planeSpacePos.y >= -0.5f && planeSpacePos.y <= 0.5f && planeSpacePos.z >= -0.5f && planeSpacePos.z <= 0.5f; - } - return clipped; - /* - #if CUTOUT_PLANE - return planeSpacePos.z > 0.0f; - #elif CUTOUT_BOX_INCL - return !(planeSpacePos.x >= -0.5f && planeSpacePos.x <= 0.5f && planeSpacePos.y >= -0.5f && planeSpacePos.y <= 0.5f && planeSpacePos.z >= -0.5f && planeSpacePos.z <= 0.5f); - #elif CUTOUT_BOX_EXCL - return planeSpacePos.x >= -0.5f && planeSpacePos.x <= 0.5f && planeSpacePos.y >= -0.5f && planeSpacePos.y <= 0.5f && planeSpacePos.z >= -0.5f && planeSpacePos.z <= 0.5f; - #endif*/ -#else - return false; -#endif - } - - frag_in vert_main (vert_in v) - { - frag_in o; - o.vertex = UnityObjectToClipPos(v.vertex); - o.uv = v.uv; - o.vertexLocal = v.vertex; - o.normal = UnityObjectToWorldNormal(v.normal); - return o; - } - - // Direct Volume Rendering - frag_out frag_dvr(frag_in i) - { - #define MAX_NUM_STEPS 512 - #define OPACITY_THRESHOLD (1.0 - 1.0 / 255.0) - -#ifdef DVR_BACKWARD_ON - RayInfo ray = getRayBack2Front(i.vertexLocal); -#else - RayInfo ray = getRayFront2Back(i.vertexLocal); -#endif - RaymarchInfo raymarchInfo = initRaymarch(ray, MAX_NUM_STEPS); - - float3 lightDir = normalize(ObjSpaceViewDir(float4(float3(0.0f, 0.0f, 0.0f), 0.0f))); - - // Create a small random offset in order to remove artifacts - ray.startPos += (JITTER_FACTOR * ray.direction * raymarchInfo.stepSize) * tex2D(_NoiseTex, float2(i.uv.x, i.uv.y)).r; - - float4 col = float4(0.0f, 0.0f, 0.0f, 0.0f); -#ifdef DVR_BACKWARD_ON - float tDepth = 0.0f; -#else - float tDepth = raymarchInfo.numStepsRecip * (raymarchInfo.numSteps - 1); -#endif - for (int iStep = 0; iStep < raymarchInfo.numSteps; iStep++) - { - const float t = iStep * raymarchInfo.numStepsRecip; - const float3 currPos = lerp(ray.startPos, ray.endPos, t); - - // Perform slice culling (cross section plane) -#ifdef CROSS_SECTION_ON - if(IsCutout(currPos)) - continue; -#endif - - // Get the dansity/sample value of the current position - const float density = getDensity(currPos); - - // Apply visibility window - if (density < _MinVal || density > _MaxVal) continue; - - // Calculate gradient (needed for lighting and 2D transfer functions) -#if defined(TF2D_ON) || defined(LIGHTING_ON) - float3 gradient = getGradient(currPos); -#endif - - // Apply transfer function -#if TF2D_ON - float mag = length(gradient) / 1.75f; - float4 src = getTF2DColour(density, mag); -#else - float4 src = getTF1DColour(density); -#endif - - // Apply lighting -#if defined(LIGHTING_ON) && defined(DVR_BACKWARD_ON) - src.rgb = calculateLighting(src.rgb, normalize(gradient), getLightDirection(ray.direction), ray.direction, 0.3f); -#elif defined(LIGHTING_ON) - src.rgb = calculateLighting(src.rgb, normalize(gradient), getLightDirection(-ray.direction), -ray.direction, 0.3f); -#endif - -#ifdef DVR_BACKWARD_ON - col.rgb = src.a * src.rgb + (1.0f - src.a) * col.rgb; - col.a = src.a + (1.0f - src.a) * col.a; - - // Optimisation: A branchless version of: if (src.a > 0.15f) tDepth = t; - tDepth = max(tDepth, t * step(0.15, src.a)); -#else - src.rgb *= src.a; - col = (1.0f - col.a) * src + col; - - if (col.a > 0.15 && t < tDepth) { - tDepth = t; - } -#endif - - // Early ray termination -#if !defined(DVR_BACKWARD_ON) && defined(RAY_TERMINATE_ON) - if (col.a > OPACITY_THRESHOLD) { - break; - } -#endif - } - - // Write fragment output - frag_out output; - output.colour = col; -#if DEPTHWRITE_ON - tDepth += (step(col.a, 0.0) * 1000.0); // Write large depth if no hit - const float3 depthPos = lerp(ray.startPos, ray.endPos, tDepth) - float3(0.5f, 0.5f, 0.5f); - output.depth = localToDepth(depthPos); -#endif - return output; - } - - // Maximum Intensity Projection mode - frag_out frag_mip(frag_in i) - { - #define MAX_NUM_STEPS 512 - - RayInfo ray = getRayBack2Front(i.vertexLocal); - RaymarchInfo raymarchInfo = initRaymarch(ray, MAX_NUM_STEPS); - - float maxDensity = 0.0f; - float3 maxDensityPos = ray.startPos; - for (int iStep = 0; iStep < raymarchInfo.numSteps; iStep++) - { - const float t = iStep * raymarchInfo.numStepsRecip; - const float3 currPos = lerp(ray.startPos, ray.endPos, t); - -#ifdef CROSS_SECTION_ON - if (IsCutout(currPos)) - continue; -#endif - - const float density = getDensity(currPos); - if (density > maxDensity && density > _MinVal && density < _MaxVal) - { - maxDensity = density; - maxDensityPos = currPos; - } - } - - // Write fragment output - frag_out output; - output.colour = float4(1.0f, 1.0f, 1.0f, maxDensity); // maximum intensity -#if DEPTHWRITE_ON - output.depth = localToDepth(maxDensityPos - float3(0.5f, 0.5f, 0.5f)); -#endif - return output; - } - - // Surface rendering mode - // Draws the first point (closest to camera) with a density within the user-defined thresholds. - frag_out frag_surf(frag_in i) - { - #define MAX_NUM_STEPS 1024 - - RayInfo ray = getRayFront2Back(i.vertexLocal); - RaymarchInfo raymarchInfo = initRaymarch(ray, MAX_NUM_STEPS); - - // Create a small random offset in order to remove artifacts - ray.startPos = ray.startPos + (JITTER_FACTOR * ray.direction * raymarchInfo.stepSize) * tex2D(_NoiseTex, float2(i.uv.x, i.uv.y)).r; - - float4 col = float4(0,0,0,0); - for (int iStep = 0; iStep < raymarchInfo.numSteps; iStep++) - { - const float t = iStep * raymarchInfo.numStepsRecip; - const float3 currPos = lerp(ray.startPos, ray.endPos, t); - -#ifdef CROSS_SECTION_ON - if (IsCutout(currPos)) - continue; -#endif - - const float density = getDensity(currPos); - if (density > _MinVal && density < _MaxVal) - { - float3 normal = normalize(getGradient(currPos)); - col = getTF1DColour(density); - col.rgb = calculateLighting(col.rgb, normal, getLightDirection(-ray.direction), -ray.direction, 0.15); - col.a = 1.0f; - break; - } - } - - // Write fragment output - frag_out output; - output.colour = col; -#if DEPTHWRITE_ON - - const float tDepth = iStep * raymarchInfo.numStepsRecip + (step(col.a, 0.0) * 1000.0); // Write large depth if no hit - output.depth = localToDepth(lerp(ray.startPos, ray.endPos, tDepth) - float3(0.5f, 0.5f, 0.5f)); -#endif - return output; - } - - frag_in vert(vert_in v) - { - return vert_main(v); - } - - frag_out frag(frag_in i) - { -#if MODE_DVR - return frag_dvr(i); -#elif MODE_MIP - return frag_mip(i); -#elif MODE_SURF - return frag_surf(i); -#endif - } - - ENDCG - } - } + Properties + { + _DataTex("Data Texture (Generated)", 3D) = "" {} + _GradientTex("Gradient Texture (Generated)", 3D) = "" {} + _NoiseTex("Noise Texture (Generated)", 2D) = "white" {} + _TFTex("Transfer Function Texture (Generated)", 2D) = "" {} + _MinVal("Min val", Range(0.0, 1.0)) = 0.0 + _MaxVal("Max val", Range(0.0, 1.0)) = 1.0 + _ClipDimMin("Clip Dim Min", Vector) = (0.0, 0.0, 0.0, 1.0) + _ClipDimMax("Clip Dim Max", Vector) = (1.0, 1.0, 1.0, 1.0) + } + SubShader + { + Tags { "Queue" = "Transparent" "RenderType" = "Transparent" } + LOD 100 + Cull Front + ZTest LEqual + ZWrite On + Blend SrcAlpha OneMinusSrcAlpha + + Pass + { + CGPROGRAM + #pragma multi_compile MODE_DVR MODE_MIP MODE_SURF + #pragma multi_compile __ TF2D_ON + #pragma multi_compile __ CROSS_SECTION_ON + #pragma multi_compile __ LIGHTING_ON + #pragma multi_compile DEPTHWRITE_ON DEPTHWRITE_OFF + #pragma multi_compile __ DVR_BACKWARD_ON + #pragma multi_compile __ RAY_TERMINATE_ON + #pragma multi_compile __ USE_MAIN_LIGHT + #pragma multi_compile __ CUBIC_INTERPOLATION_ON + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + #include "TricubicSampling.cginc" + + #define AMBIENT_LIGHTING_FACTOR 0.5 + #define JITTER_FACTOR 5.0 + + struct vert_in + { + float4 vertex : POSITION; + float4 normal : NORMAL; + float2 uv : TEXCOORD0; + }; + + struct frag_in + { + float4 vertex : SV_POSITION; + float2 uv : TEXCOORD0; + float3 vertexLocal : TEXCOORD1; + float3 normal : NORMAL; + }; + + struct frag_out + { + float4 colour : SV_TARGET; + #if DEPTHWRITE_ON + float depth : SV_DEPTH; + #endif + }; + + sampler3D _DataTex; + sampler3D _GradientTex; + sampler2D _NoiseTex; + sampler2D _TFTex; + + float _MinVal; + float _MaxVal; + float3 _TextureSize; + + // For clipping in any direction + float4 _ClipDimMin, _ClipDimMax; + + #if CROSS_SECTION_ON + #define CROSS_SECTION_TYPE_PLANE 1 + #define CROSS_SECTION_TYPE_BOX_INCL 2 + #define CROSS_SECTION_TYPE_BOX_EXCL 3 + float4x4 _CrossSectionMatrices[8]; + float _CrossSectionTypes[8]; + int _NumCrossSections; + #endif + + struct RayInfo + { + float3 startPos; + float3 endPos; + float3 direction; + float2 aabbInters; + }; + + struct RaymarchInfo + { + RayInfo ray; + int numSteps; + float numStepsRecip; + float stepSize; + }; + + float3 getViewRayDir(float3 vertexLocal) + { + if (unity_OrthoParams.w == 0) + { + // Perspective + return normalize(ObjSpaceViewDir(float4(vertexLocal, 0.0f))); + } + else + { + // Orthographic + float3 camfwd = mul((float3x3)unity_CameraToWorld, float3(0,0,-1)); + float4 camfwdobjspace = mul(unity_WorldToObject, camfwd); + return normalize(camfwdobjspace); + } + } + + // Find ray intersection points with axis aligned bounding box + float2 intersectAABB(float3 rayOrigin, float3 rayDir, float3 boxMin, float3 boxMax) + { + float3 tMin = (boxMin - rayOrigin) / rayDir; + float3 tMax = (boxMax - rayOrigin) / rayDir; + float3 t1 = min(tMin, tMax); + float3 t2 = max(tMin, tMax); + float tNear = max(max(t1.x, t1.y), t1.z); + float tFar = min(min(t2.x, t2.y), t2.z); + return float2(tNear, tFar); + }; + + // Get a ray for the specified fragment (back-to-front) + RayInfo getRayBack2Front(float3 vertexLocal) + { + RayInfo ray; + ray.direction = getViewRayDir(vertexLocal); + ray.startPos = vertexLocal + float3(0.5f, 0.5f, 0.5f); + // Find intersections with axis aligned boundinng box (the volume) + ray.aabbInters = intersectAABB(ray.startPos, ray.direction, float3(0.0, 0.0, 0.0), float3(1.0f, 1.0f, 1.0)); + + // Check if camera is inside AABB + const float3 farPos = ray.startPos + ray.direction * ray.aabbInters.y - float3(0.5f, 0.5f, 0.5f); + float4 clipPos = UnityObjectToClipPos(float4(farPos, 1.0f)); + ray.aabbInters += min(clipPos.w, 0.0); + + ray.endPos = ray.startPos + ray.direction * ray.aabbInters.y; + return ray; + } + + // Get a ray for the specified fragment (front-to-back) + RayInfo getRayFront2Back(float3 vertexLocal) + { + RayInfo ray = getRayBack2Front(vertexLocal); + ray.direction = -ray.direction; + float3 tmp = ray.startPos; + ray.startPos = ray.endPos; + ray.endPos = tmp; + return ray; + } + + RaymarchInfo initRaymarch(RayInfo ray, int maxNumSteps) + { + RaymarchInfo raymarchInfo; + raymarchInfo.stepSize = 1.732f/*greatest distance in box*/ / maxNumSteps; + raymarchInfo.numSteps = (int)clamp(abs(ray.aabbInters.x - ray.aabbInters.y) / raymarchInfo.stepSize, 1, maxNumSteps); + raymarchInfo.numStepsRecip = 1.0 / raymarchInfo.numSteps; + return raymarchInfo; + } + + // Gets the colour from a 1D Transfer Function (x = density) + float4 getTF1DColour(float density) + { + return tex2Dlod(_TFTex, float4(density, 0.0f, 0.0f, 0.0f)); + } + + // Gets the colour from a 2D Transfer Function (x = density, y = gradient magnitude) + float4 getTF2DColour(float density, float gradientMagnitude) + { + return tex2Dlod(_TFTex, float4(density, gradientMagnitude, 0.0f, 0.0f)); + } + + // Gets the density at the specified position + float getDensity(float3 pos) + { + #if CUBIC_INTERPOLATION_ON + return interpolateTricubicFast(_DataTex, float3(pos.x, pos.y, pos.z), _TextureSize); + #else + return tex3Dlod(_DataTex, float4(pos.x, pos.y, pos.z, 0.0f)); + #endif + } + + // Gets the gradient at the specified position + float3 getGradient(float3 pos) + { + #if CUBIC_INTERPOLATION_ON + return interpolateTricubicFast(_GradientTex, float3(pos.x, pos.y, pos.z), _TextureSize).rgb; + #else + return tex3Dlod(_GradientTex, float4(pos.x, pos.y, pos.z, 0.0f)).rgb; + #endif + } + + // Get the light direction (using main light or view direction, based on setting) + float3 getLightDirection(float3 viewDir) + { + #if defined(USE_MAIN_LIGHT) + return normalize(mul(unity_WorldToObject, _WorldSpaceLightPos0.xyz)); + #else + return viewDir; + #endif + } + + // Performs lighting calculations, and returns a modified colour. + float3 calculateLighting(float3 col, float3 normal, float3 lightDir, float3 eyeDir, float specularIntensity) + { + // Invert normal if facing opposite direction of view direction. + // Optimised version of: if(dot(normal, eyeDir) < 0.0) normal *= -1.0 + normal *= (step(0.0, dot(normal, eyeDir)) * 2.0 - 1.0); + + float ndotl = max(lerp(0.0f, 1.5f, dot(normal, lightDir)), AMBIENT_LIGHTING_FACTOR); + float3 diffuse = ndotl * col; + float3 v = eyeDir; + float3 r = normalize(reflect(-lightDir, normal)); + float rdotv = max(dot(r, v), 0.0); + float3 specular = pow(rdotv, 32.0f) * float3(1.0f, 1.0f, 1.0f) * specularIntensity; + return diffuse + specular; + } + + // Converts local position to depth value + float localToDepth(float3 localPos) + { + float4 clipPos = UnityObjectToClipPos(float4(localPos, 1.0f)); + + #if defined(SHADER_API_GLCORE) || defined(SHADER_API_OPENGL) || defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) + return (clipPos.z / clipPos.w) * 0.5 + 0.5; + #else + return clipPos.z / clipPos.w; + #endif + } + + bool IsCutout(float3 currPos) + { + #if CROSS_SECTION_ON + // Move the reference in the middle of the mesh, like the pivot + float4 pos = float4(currPos - float3(0.5f, 0.5f, 0.5f), 1.0f); + + bool clipped = false; + for (int i = 0; i < _NumCrossSections && !clipped; ++i) + { + const int type = (int)_CrossSectionTypes[i]; + const float4x4 mat = _CrossSectionMatrices[i]; + + // Convert from model space to plane's vector space + float3 planeSpacePos = mul(mat, pos); + if (type == CROSS_SECTION_TYPE_PLANE) + clipped = planeSpacePos.z > 0.0f; + else if (type == CROSS_SECTION_TYPE_BOX_INCL) + clipped = !(planeSpacePos.x >= -0.5f && planeSpacePos.x <= 0.5f && planeSpacePos.y >= -0.5f && planeSpacePos.y <= 0.5f && planeSpacePos.z >= -0.5f && planeSpacePos.z <= 0.5f); + else if (type == CROSS_SECTION_TYPE_BOX_EXCL) + clipped = planeSpacePos.x >= -0.5f && planeSpacePos.x <= 0.5f && planeSpacePos.y >= -0.5f && planeSpacePos.y <= 0.5f && planeSpacePos.z >= -0.5f && planeSpacePos.z <= 0.5f; + } + return clipped; + /* + #if CUTOUT_PLANE + return planeSpacePos.z > 0.0f; + #elif CUTOUT_BOX_INCL + return !(planeSpacePos.x >= -0.5f && planeSpacePos.x <= 0.5f && planeSpacePos.y >= -0.5f && planeSpacePos.y <= 0.5f && planeSpacePos.z >= -0.5f && planeSpacePos.z <= 0.5f); + #elif CUTOUT_BOX_EXCL + return planeSpacePos.x >= -0.5f && planeSpacePos.x <= 0.5f && planeSpacePos.y >= -0.5f && planeSpacePos.y <= 0.5f && planeSpacePos.z >= -0.5f && planeSpacePos.z <= 0.5f; + #endif*/ + #else + return false; + #endif + } + + frag_in vert_main(vert_in v) + { + frag_in o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + o.vertexLocal = v.vertex; + o.normal = UnityObjectToWorldNormal(v.normal); + return o; + } + + // Direct Volume Rendering + frag_out frag_dvr(frag_in i) + { + #define MAX_NUM_STEPS 512 + #define OPACITY_THRESHOLD (1.0 - 1.0 / 255.0) + + #ifdef DVR_BACKWARD_ON + RayInfo ray = getRayBack2Front(i.vertexLocal); + #else + RayInfo ray = getRayFront2Back(i.vertexLocal); + #endif + RaymarchInfo raymarchInfo = initRaymarch(ray, MAX_NUM_STEPS); + + float3 lightDir = normalize(ObjSpaceViewDir(float4(float3(0.0f, 0.0f, 0.0f), 0.0f))); + + // Create a small random offset in order to remove artifacts + ray.startPos += (JITTER_FACTOR * ray.direction * raymarchInfo.stepSize) * tex2D(_NoiseTex, float2(i.uv.x, i.uv.y)).r; + + float4 col = float4(0.0f, 0.0f, 0.0f, 0.0f); + #ifdef DVR_BACKWARD_ON + float tDepth = 0.0f; + #else + float tDepth = raymarchInfo.numStepsRecip * (raymarchInfo.numSteps - 1); + #endif + for (int iStep = 0; iStep < raymarchInfo.numSteps; iStep++) + { + const float t = iStep * raymarchInfo.numStepsRecip; + const float3 currPos = lerp(ray.startPos, ray.endPos, t); + + // Perform slice culling (cross section plane) + #ifdef CROSS_SECTION_ON + if (IsCutout(currPos)) + continue; + #endif + + // Get the dansity/sample value of the current position + const float density = getDensity(currPos); + + // Apply visibility window + if (density < _MinVal || density > _MaxVal) continue; + + // cut with clip dims + if (currPos.x < _ClipDimMin.x || currPos.x > _ClipDimMax.x) continue; + if (currPos.y < _ClipDimMin.y || currPos.y > _ClipDimMax.y) continue; + if (currPos.z < _ClipDimMin.z || currPos.z > _ClipDimMax.z) continue; + + // Calculate gradient (needed for lighting and 2D transfer functions) + #if defined(TF2D_ON) || defined(LIGHTING_ON) + float3 gradient = getGradient(currPos); + #endif + + // Apply transfer function + #if TF2D_ON + float mag = length(gradient) / 1.75f; + float4 src = getTF2DColour(density, mag); + #else + float4 src = getTF1DColour(density); + #endif + + // Apply lighting + #if defined(LIGHTING_ON) && defined(DVR_BACKWARD_ON) + src.rgb = calculateLighting(src.rgb, normalize(gradient), getLightDirection(ray.direction), ray.direction, 0.3f); + #elif defined(LIGHTING_ON) + src.rgb = calculateLighting(src.rgb, normalize(gradient), getLightDirection(-ray.direction), -ray.direction, 0.3f); + #endif + + #ifdef DVR_BACKWARD_ON + col.rgb = src.a * src.rgb + (1.0f - src.a) * col.rgb; + col.a = src.a + (1.0f - src.a) * col.a; + + // Optimisation: A branchless version of: if (src.a > 0.15f) tDepth = t; + tDepth = max(tDepth, t * step(0.15, src.a)); + #else + src.rgb *= src.a; + col = (1.0f - col.a) * src + col; + + if (col.a > 0.15 && t < tDepth) { + tDepth = t; + } + #endif + + // Early ray termination + #if !defined(DVR_BACKWARD_ON) && defined(RAY_TERMINATE_ON) + if (col.a > OPACITY_THRESHOLD) { + break; + } + #endif + } + + // Write fragment output + frag_out output; + output.colour = col; + #if DEPTHWRITE_ON + tDepth += (step(col.a, 0.0) * 1000.0); // Write large depth if no hit + const float3 depthPos = lerp(ray.startPos, ray.endPos, tDepth) - float3(0.5f, 0.5f, 0.5f); + output.depth = localToDepth(depthPos); + #endif + return output; + } + + // Maximum Intensity Projection mode + frag_out frag_mip(frag_in i) + { + #define MAX_NUM_STEPS 512 + + RayInfo ray = getRayBack2Front(i.vertexLocal); + RaymarchInfo raymarchInfo = initRaymarch(ray, MAX_NUM_STEPS); + + float maxDensity = 0.0f; + float3 maxDensityPos = ray.startPos; + for (int iStep = 0; iStep < raymarchInfo.numSteps; iStep++) + { + const float t = iStep * raymarchInfo.numStepsRecip; + const float3 currPos = lerp(ray.startPos, ray.endPos, t); + + #ifdef CROSS_SECTION_ON + if (IsCutout(currPos)) + continue; + #endif + + const float density = getDensity(currPos); + if (density > maxDensity && density > _MinVal && density < _MaxVal) + { + maxDensity = density; + maxDensityPos = currPos; + } + } + + // Write fragment output + frag_out output; + output.colour = float4(1.0f, 1.0f, 1.0f, maxDensity); // maximum intensity + #if DEPTHWRITE_ON + output.depth = localToDepth(maxDensityPos - float3(0.5f, 0.5f, 0.5f)); + #endif + return output; + } + + // Surface rendering mode + // Draws the first point (closest to camera) with a density within the user-defined thresholds. + frag_out frag_surf(frag_in i) + { + #define MAX_NUM_STEPS 1024 + + RayInfo ray = getRayFront2Back(i.vertexLocal); + RaymarchInfo raymarchInfo = initRaymarch(ray, MAX_NUM_STEPS); + + // Create a small random offset in order to remove artifacts + ray.startPos = ray.startPos + (JITTER_FACTOR * ray.direction * raymarchInfo.stepSize) * tex2D(_NoiseTex, float2(i.uv.x, i.uv.y)).r; + + float4 col = float4(0,0,0,0); + for (int iStep = 0; iStep < raymarchInfo.numSteps; iStep++) + { + const float t = iStep * raymarchInfo.numStepsRecip; + const float3 currPos = lerp(ray.startPos, ray.endPos, t); + + #ifdef CROSS_SECTION_ON + if (IsCutout(currPos)) + continue; + #endif + + const float density = getDensity(currPos); + if (density > _MinVal && density < _MaxVal) + { + float3 normal = normalize(getGradient(currPos)); + col = getTF1DColour(density); + col.rgb = calculateLighting(col.rgb, normal, getLightDirection(-ray.direction), -ray.direction, 0.15); + col.a = 1.0f; + break; + } + } + + // Write fragment output + frag_out output; + output.colour = col; + #if DEPTHWRITE_ON + + const float tDepth = iStep * raymarchInfo.numStepsRecip + (step(col.a, 0.0) * 1000.0); // Write large depth if no hit + output.depth = localToDepth(lerp(ray.startPos, ray.endPos, tDepth) - float3(0.5f, 0.5f, 0.5f)); + #endif + return output; + } + + frag_in vert(vert_in v) + { + return vert_main(v); + } + + frag_out frag(frag_in i) + { + #if MODE_DVR + return frag_dvr(i); + #elif MODE_MIP + return frag_mip(i); + #elif MODE_SURF + return frag_surf(i); + #endif + } + + ENDCG + } + } } diff --git a/Assets/csc.rsp b/Assets/csc.rsp new file mode 100644 index 00000000..fb1d8d08 --- /dev/null +++ b/Assets/csc.rsp @@ -0,0 +1,2 @@ +-r:System.Drawing.dll +-r:System.IO.Compression.dll \ No newline at end of file diff --git a/Assets/csc.rsp.meta b/Assets/csc.rsp.meta new file mode 100644 index 00000000..ad3806dd --- /dev/null +++ b/Assets/csc.rsp.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cafdcbc396b144a48b7aa0b338842a11 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/CREDITS.md b/CREDITS.md index 1a7c3fb1..55ab5d7e 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -14,5 +14,7 @@ GUI for modifying slicing plane positiomn/orientation. Memory leak fix - [Vahid](https://github.com/vahpy) Texture downscaling, optimisation. +- [Walter](https://github.com/smallvalthoss) +Adding xyz Dimensional Clipping to DirectVolumeRendering. Feel free to add yourself to this list when contributing to this project. diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset index 78c18acc..5162e19f 100644 --- a/ProjectSettings/EditorSettings.asset +++ b/ProjectSettings/EditorSettings.asset @@ -1,21 +1,35 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!159 &1 -EditorSettings: - m_ObjectHideFlags: 0 - serializedVersion: 7 - m_ExternalVersionControlSupport: Visible Meta Files - m_SerializationMode: 2 - m_LineEndingsForNewScripts: 2 - m_DefaultBehaviorMode: 0 - m_SpritePackerMode: 0 - m_SpritePackerPaddingPower: 1 - m_EtcTextureCompressorBehavior: 1 - m_EtcTextureFastCompressor: 1 - m_EtcTextureNormalCompressor: 2 - m_EtcTextureBestCompressor: 4 - m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd - m_ProjectGenerationRootNamespace: - m_UserGeneratedProjectSuffix: - m_CollabEditorSettings: - inProgressEnabled: 1 +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_ExternalVersionControlSupport: Visible Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 2 + m_DefaultBehaviorMode: 0 + m_PrefabRegularEnvironment: {fileID: 0} + m_PrefabUIEnvironment: {fileID: 0} + m_SpritePackerMode: 0 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmref + m_ProjectGenerationRootNamespace: + m_CollabEditorSettings: + inProgressEnabled: 1 + m_EnableTextureStreamingInEditMode: 1 + m_EnableTextureStreamingInPlayMode: 1 + m_AsyncShaderCompilation: 1 + m_EnterPlayModeOptionsEnabled: 0 + m_EnterPlayModeOptions: 3 + m_ShowLightmapResolutionOverlay: 1 + m_UseLegacyProbeSampleCount: 1 + m_AssetPipelineMode: 1 + m_CacheServerMode: 0 + m_CacheServerEndpoint: + m_CacheServerNamespacePrefix: default + m_CacheServerEnableDownload: 1 + m_CacheServerEnableUpload: 1 diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 691412eb..7cfebd19 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -3,7 +3,7 @@ --- !u!129 &1 PlayerSettings: m_ObjectHideFlags: 0 - serializedVersion: 18 + serializedVersion: 20 productGUID: 7e7b03b4f05be5643a2618a6bd9b64d9 AndroidProfiler: 0 AndroidFilterTouchesWhenObscured: 0 @@ -52,7 +52,6 @@ PlayerSettings: m_StackTraceTypes: 010000000100000001000000010000000100000001000000 iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 - displayResolutionDialog: 1 iosUseCustomAppBackgroundBehavior: 0 iosAllowHTTPDownload: 1 allowedAutorotateToPortrait: 1 @@ -85,7 +84,6 @@ PlayerSettings: useMacAppStoreValidation: 0 macAppStoreCategory: public.app-category.games gpuSkinning: 1 - graphicsJobs: 0 xboxPIXTextureCapture: 0 xboxEnableAvatar: 0 xboxEnableKinect: 0 @@ -93,7 +91,6 @@ PlayerSettings: xboxEnableFitness: 0 visibleInBackground: 1 allowFullscreenSwitch: 1 - graphicsJobMode: 0 fullscreenMode: 1 xboxSpeechDB: 0 xboxEnableHeadOrientation: 0 @@ -106,6 +103,7 @@ PlayerSettings: xboxOneMonoLoggingLevel: 0 xboxOneLoggingLevel: 1 xboxOneDisableEsram: 0 + xboxOneEnableTypeOptimization: 0 xboxOnePresentImmediateThreshold: 0 switchQueueCommandMemory: 0 switchQueueControlMemory: 16384 @@ -113,7 +111,13 @@ PlayerSettings: switchNVNShaderPoolsGranularity: 33554432 switchNVNDefaultPoolsGranularity: 16777216 switchNVNOtherPoolsGranularity: 16777216 + switchNVNMaxPublicTextureIDCount: 0 + switchNVNMaxPublicSamplerIDCount: 0 + stadiaPresentMode: 0 + stadiaTargetFramerate: 0 + vulkanNumSwapchainBuffers: 3 vulkanEnableSetSRGBWrite: 0 + vulkanEnableLateAcquireNextImage: 0 m_SupportedAspectRatios: 4:3: 1 5:4: 1 @@ -155,9 +159,9 @@ PlayerSettings: v2Signing: 0 enable360StereoCapture: 0 isWsaHolographicRemotingEnabled: 0 - protectGraphicsMemory: 0 enableFrameTimingStats: 0 useHDRDisplay: 0 + D3DHDRBitDepth: 0 m_ColorGamuts: 00000000 targetPixelDensity: 30 resolutionScalingMode: 0 @@ -166,7 +170,7 @@ PlayerSettings: applicationIdentifier: {} buildNumber: {} AndroidBundleVersionCode: 1 - AndroidMinSdkVersion: 16 + AndroidMinSdkVersion: 19 AndroidTargetSdkVersion: 0 AndroidPreferredInstallLocation: 1 aotOptions: @@ -181,32 +185,16 @@ PlayerSettings: StripUnusedMeshComponents: 1 VertexChannelCompressionMask: 4054 iPhoneSdkVersion: 988 - iOSTargetOSVersionString: 9.0 + iOSTargetOSVersionString: 10.0 tvOSSdkVersion: 0 tvOSRequireExtendedGameController: 0 - tvOSTargetOSVersionString: 9.0 + tvOSTargetOSVersionString: 10.0 uIPrerenderedIcon: 0 uIRequiresPersistentWiFi: 0 uIRequiresFullScreen: 1 uIStatusBarHidden: 1 uIExitOnSuspend: 0 uIStatusBarStyle: 0 - iPhoneSplashScreen: {fileID: 0} - iPhoneHighResSplashScreen: {fileID: 0} - iPhoneTallHighResSplashScreen: {fileID: 0} - iPhone47inSplashScreen: {fileID: 0} - iPhone55inPortraitSplashScreen: {fileID: 0} - iPhone55inLandscapeSplashScreen: {fileID: 0} - iPhone58inPortraitSplashScreen: {fileID: 0} - iPhone58inLandscapeSplashScreen: {fileID: 0} - iPadPortraitSplashScreen: {fileID: 0} - iPadHighResPortraitSplashScreen: {fileID: 0} - iPadLandscapeSplashScreen: {fileID: 0} - iPadHighResLandscapeSplashScreen: {fileID: 0} - iPhone65inPortraitSplashScreen: {fileID: 0} - iPhone65inLandscapeSplashScreen: {fileID: 0} - iPhone61inPortraitSplashScreen: {fileID: 0} - iPhone61inLandscapeSplashScreen: {fileID: 0} appleTVSplashScreen: {fileID: 0} appleTVSplashScreen2x: {fileID: 0} tvOSSmallIconLayers: [] @@ -274,7 +262,6 @@ PlayerSettings: androidGamepadSupportLevel: 0 AndroidValidateAppBundleSize: 1 AndroidAppBundleSizeToValidate: 150 - resolutionDialogBanner: {fileID: 0} m_BuildTargetIcons: [] m_BuildTargetPlatformIcons: [] m_BuildTargetBatching: @@ -293,6 +280,40 @@ PlayerSettings: - m_BuildTarget: WebGL m_StaticBatching: 0 m_DynamicBatching: 0 + m_BuildTargetGraphicsJobs: + - m_BuildTarget: MacStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: Switch + m_GraphicsJobs: 0 + - m_BuildTarget: MetroSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AppleTVSupport + m_GraphicsJobs: 0 + - m_BuildTarget: BJMSupport + m_GraphicsJobs: 0 + - m_BuildTarget: LinuxStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: PS4Player + m_GraphicsJobs: 0 + - m_BuildTarget: iOSSupport + m_GraphicsJobs: 0 + - m_BuildTarget: WindowsStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobs: 0 + - m_BuildTarget: LuminSupport + m_GraphicsJobs: 0 + - m_BuildTarget: CloudRendering + m_GraphicsJobs: 0 + - m_BuildTarget: AndroidPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: WebGLSupport + m_GraphicsJobs: 0 + m_BuildTargetGraphicsJobMode: + - m_BuildTarget: PS4Player + m_GraphicsJobMode: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobMode: 0 m_BuildTargetGraphicsAPIs: - m_BuildTarget: AndroidPlayer m_APIs: 0b00000015000000 @@ -315,7 +336,6 @@ PlayerSettings: openGLRequireES31: 0 openGLRequireES31AEP: 0 openGLRequireES32: 0 - vuforiaEnabled: 0 m_TemplateCustomTags: {} mobileMTRendering: Android: 1 @@ -488,6 +508,7 @@ PlayerSettings: ps4ShareFilePath: ps4ShareOverlayImagePath: ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: ps4NPtitleDatPath: ps4RemotePlayKeyAssignment: -1 ps4RemotePlayKeyMappingDir: @@ -513,6 +534,7 @@ PlayerSettings: ps4UseResolutionFallback: 0 ps4ReprojectionSupport: 0 ps4UseAudio3dBackend: 0 + ps4UseLowGarlicFragmentationMode: 1 ps4SocialScreenEnabled: 0 ps4ScriptOptimizationLevel: 0 ps4Audio3dVirtualSpeakerCount: 14 @@ -529,8 +551,11 @@ PlayerSettings: ps4disableAutoHideSplash: 0 ps4videoRecordingFeaturesUsed: 0 ps4contentSearchFeaturesUsed: 0 + ps4CompatibilityPS5: 0 + ps4GPU800MHz: 1 ps4attribEyeToEyeDistanceSettingVR: 0 ps4IncludedModules: [] + ps4attribVROutputEnabled: 0 monoEnv: splashScreenBackgroundSourceLandscape: {fileID: 0} splashScreenBackgroundSourcePortrait: {fileID: 0} @@ -574,7 +599,8 @@ PlayerSettings: scriptingRuntimeVersion: 1 gcIncremental: 0 gcWBarrierValidation: 0 - apiCompatibilityLevelPerPlatform: {} + apiCompatibilityLevelPerPlatform: + Standalone: 3 m_RenderingPath: 1 m_MobileRenderingPath: 1 metroPackageName: Template_3D @@ -628,8 +654,8 @@ PlayerSettings: XboxOneAllowedProductIds: [] XboxOnePersistentLocalStorageSize: 0 XboxOneXTitleMemory: 8 - xboxOneScriptCompiler: 1 XboxOneOverrideIdentityName: + XboxOneOverrideIdentityPublisher: vrEditorSettings: daydream: daydreamIconForeground: {fileID: 0} @@ -647,13 +673,6 @@ PlayerSettings: luminVersion: m_VersionCode: 1 m_VersionName: - facebookSdkVersion: 7.9.4 - facebookAppId: - facebookCookies: 1 - facebookLogging: 1 - facebookStatus: 1 - facebookXfbml: 0 - facebookFrictionlessRequests: 1 apiCompatibilityLevel: 6 cloudProjectId: framebufferDepthMemorylessMode: 0 diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt index d233b6dd..d53ff41f 100644 --- a/ProjectSettings/ProjectVersion.txt +++ b/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2019.4.23f1 -m_EditorVersionWithRevision: 2019.4.23f1 (3f4e01f1a5ec) +m_EditorVersion: 2019.4.11f1 +m_EditorVersionWithRevision: 2019.4.11f1 (2d9804dddde7) diff --git a/csc.rsp b/csc.rsp new file mode 100644 index 00000000..99afd1ef --- /dev/null +++ b/csc.rsp @@ -0,0 +1 @@ +-r:System.Drawing.dll \ No newline at end of file