#32: Box cutout.
This commit is contained in:
Родитель
e2eb365c6b
Коммит
3d57289996
|
@ -80,5 +80,13 @@ namespace UnityVolumeRendering
|
|||
Debug.LogError("Directory doesn't exist: " + dir);
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem("Volume Rendering/Box cutout")]
|
||||
static void SpawnCutoutBox()
|
||||
{
|
||||
VolumeRenderedObject[] objects = GameObject.FindObjectsOfType<VolumeRenderedObject>();
|
||||
if (objects.Length == 1)
|
||||
VolumeObjectFactory.SpawnCutoutBox(objects[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ Material:
|
|||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: CrossSectionPlaneMat
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_Shader: {fileID: 4800000, guid: be13da9a7b1929348b18627a539ef497, type: 3}
|
||||
m_ShaderKeywords: SLICEPLANE_ON _ALPHAPREMULTIPLY_ON
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
|
@ -40,7 +40,7 @@ Material:
|
|||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Texture: {fileID: 2800000, guid: dd8e5417cf6e38d40b0c31c547f985ac, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
|
@ -59,19 +59,19 @@ Material:
|
|||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _DstBlend: 10
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _Mode: 3
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
- _ZWrite: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _Color: {r: 0.9150943, g: 0.07338022, b: 0.07338022, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
|
|
|
@ -11,7 +11,6 @@ GameObject:
|
|||
- component: {fileID: 3122546165893029993}
|
||||
- component: {fileID: 7621817265638011433}
|
||||
- component: {fileID: 4756273696276402491}
|
||||
- component: {fileID: 4727509710722438312}
|
||||
- component: {fileID: 2049453483492477609}
|
||||
m_Layer: 0
|
||||
m_Name: CrossSectionPlane
|
||||
|
@ -81,20 +80,6 @@ MeshRenderer:
|
|||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
--- !u!64 &4727509710722438312
|
||||
MeshCollider:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5697153076470531463}
|
||||
m_Material: {fileID: 0}
|
||||
m_IsTrigger: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 4
|
||||
m_Convex: 0
|
||||
m_CookingOptions: 30
|
||||
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!114 &2049453483492477609
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3923763609855477888
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6395997655089519251}
|
||||
- component: {fileID: 4693973390399920385}
|
||||
- component: {fileID: 486768037272836538}
|
||||
- component: {fileID: 9069229388242967652}
|
||||
m_Layer: 0
|
||||
m_Name: CutoutBox
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &6395997655089519251
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3923763609855477888}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0.05694554, y: -0.02139771, z: -0.022755325}
|
||||
m_LocalScale: {x: 0.3, y: 0.3, z: 0.3}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!33 &4693973390399920385
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3923763609855477888}
|
||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!23 &486768037272836538
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3923763609855477888}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: 6e564749dcca6944ca78723ffd119eca, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
--- !u!114 &9069229388242967652
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3923763609855477888}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 7401967f0dd72374ea6df35ee454fb53, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
targetObject: {fileID: 0}
|
||||
cutoutType: 0
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cc908a3bf1d415e4c9e3b478efe32102
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -17,7 +17,7 @@ namespace UnityVolumeRendering
|
|||
private void OnDisable()
|
||||
{
|
||||
if (targetObject != null)
|
||||
targetObject.meshRenderer.sharedMaterial.DisableKeyword("SLICEPLANE_ON");
|
||||
targetObject.meshRenderer.sharedMaterial.DisableKeyword("CUTOUT_PLANE");
|
||||
}
|
||||
|
||||
private void Update()
|
||||
|
@ -27,7 +27,7 @@ namespace UnityVolumeRendering
|
|||
|
||||
Material mat = targetObject.meshRenderer.sharedMaterial;
|
||||
|
||||
mat.EnableKeyword("SLICEPLANE_ON");
|
||||
mat.EnableKeyword("CUTOUT_PLANE");
|
||||
mat.SetMatrix("_CrossSectionMatrix", transform.worldToLocalMatrix * targetObject.transform.localToWorldMatrix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UnityVolumeRendering
|
||||
{
|
||||
public enum CutoutType
|
||||
{
|
||||
Inclusive, Exclusive
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cutout box.
|
||||
/// Used for cutting a model (cutout view).
|
||||
/// </summary>
|
||||
[ExecuteInEditMode]
|
||||
public class CutoutBox : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Volume dataset to cut.
|
||||
/// </summary>
|
||||
public VolumeRenderedObject targetObject;
|
||||
|
||||
public CutoutType cutoutType = CutoutType.Exclusive;
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (targetObject != null)
|
||||
{
|
||||
targetObject.meshRenderer.sharedMaterial.DisableKeyword("CUTOUT_BOX_INCL");
|
||||
targetObject.meshRenderer.sharedMaterial.DisableKeyword("CUTOUT_BOX_EXCL");
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (targetObject == null)
|
||||
return;
|
||||
|
||||
Material mat = targetObject.meshRenderer.sharedMaterial;
|
||||
|
||||
mat.DisableKeyword(cutoutType == CutoutType.Inclusive ? "CUTOUT_BOX_EXCL" : "CUTOUT_BOX_INCL");
|
||||
mat.EnableKeyword(cutoutType == CutoutType.Exclusive ? "CUTOUT_BOX_EXCL" : "CUTOUT_BOX_INCL");
|
||||
mat.SetMatrix("_CrossSectionMatrix", transform.worldToLocalMatrix * targetObject.transform.localToWorldMatrix);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7401967f0dd72374ea6df35ee454fb53
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -61,6 +61,19 @@ namespace UnityVolumeRendering
|
|||
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.Selection.objects = new UnityEngine.Object[] { quad };
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void SpawnCutoutBox(VolumeRenderedObject volobj)
|
||||
{
|
||||
GameObject obj = GameObject.Instantiate((GameObject)Resources.Load("CutoutBox"));
|
||||
obj.transform.rotation = Quaternion.Euler(270.0f, 0.0f, 0.0f);
|
||||
CutoutBox cbox = obj.gameObject.GetComponent<CutoutBox>();
|
||||
cbox.targetObject = volobj;
|
||||
obj.transform.position = volobj.transform.position;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.Selection.objects = new UnityEngine.Object[] { obj };
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
CGPROGRAM
|
||||
#pragma multi_compile MODE_DVR MODE_MIP MODE_SURF
|
||||
#pragma multi_compile __ TF2D_ON
|
||||
#pragma multi_compile __ SLICEPLANE_ON
|
||||
#pragma multi_compile __ CUTOUT_PLANE CUTOUT_BOX_INCL CUTOUT_BOX_EXCL
|
||||
#pragma multi_compile __ LIGHTING_ON
|
||||
#pragma multi_compile DEPTHWRITE_ON DEPTHWRITE_OFF
|
||||
#pragma vertex vert
|
||||
|
@ -31,6 +31,8 @@
|
|||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
#define CUTOUT_ON CUTOUT_PLANE || CUTOUT_BOX_INCL || CUTOUT_BOX_EXCL
|
||||
|
||||
struct vert_in
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
|
@ -62,7 +64,7 @@
|
|||
float _MinVal;
|
||||
float _MaxVal;
|
||||
|
||||
#if SLICEPLANE_ON
|
||||
#if CUTOUT_ON
|
||||
float4x4 _CrossSectionMatrix;
|
||||
#endif
|
||||
|
||||
|
@ -114,15 +116,22 @@
|
|||
#endif
|
||||
}
|
||||
|
||||
bool isSliceCulled(float3 currPos)
|
||||
bool IsCutout(float3 currPos)
|
||||
{
|
||||
#if SLICEPLANE_ON
|
||||
#if CUTOUT_ON
|
||||
// Move the reference in the middle of the mesh, like the pivot
|
||||
float3 pos = currPos - float3(0.5f, 0.5f, 0.5f);
|
||||
|
||||
// Convert from model space to plane's vector space
|
||||
float3 planeSpacePos = mul(_CrossSectionMatrix, float4(pos, 1.0f));
|
||||
|
||||
#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
|
||||
|
@ -163,8 +172,8 @@
|
|||
break;
|
||||
|
||||
// Perform slice culling (cross section plane)
|
||||
#ifdef SLICEPLANE_ON
|
||||
if(isSliceCulled(currPos))
|
||||
#ifdef CUTOUT_ON
|
||||
if(IsCutout(currPos))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
|
@ -233,8 +242,8 @@
|
|||
if (currPos.x < -0.0001f || currPos.x >= 1.0001f || currPos.y < -0.0001f || currPos.y > 1.0001f || currPos.z < -0.0001f || currPos.z > 1.0001f) // TODO: avoid branch?
|
||||
break;
|
||||
|
||||
#ifdef SLICEPLANE_ON
|
||||
if (isSliceCulled(currPos))
|
||||
#ifdef CUTOUT_ON
|
||||
if (IsCutout(currPos))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
|
@ -277,8 +286,8 @@
|
|||
if (currPos.x < 0.0f || currPos.x >= 1.0f || currPos.y < 0.0f || currPos.y > 1.0f || currPos.z < 0.0f || currPos.z > 1.0f) // TODO: avoid branch?
|
||||
continue;
|
||||
|
||||
#ifdef SLICEPLANE_ON
|
||||
if (isSliceCulled(currPos))
|
||||
#ifdef CUTOUT_ON
|
||||
if (IsCutout(currPos))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче