Merge pull request #16 from mlavik1/texture-formats

#14: Texture formats
This commit is contained in:
Matias Lavik 2020-02-26 19:03:27 +01:00 коммит произвёл GitHub
Родитель ebda446929 01e47a3052
Коммит 34f31ce8a0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 156 добавлений и 72 удалений

Просмотреть файл

@ -148,9 +148,8 @@ namespace UnityVolumeRendering
tf2d.GenerateTexture();
needsRegenTexture = false;
}
// TODO:
volRendObject.GetComponent<MeshRenderer>().sharedMaterial.SetTexture("_TFTex", tf2d.GetTexture());
volRendObject.GetComponent<MeshRenderer>().sharedMaterial.EnableKeyword("TF2D_ON");
volRendObject.SetTransferFunctionMode(TFRenderMode.TF2D);
return;
}

Просмотреть файл

@ -189,9 +189,7 @@ namespace UnityVolumeRendering
GUI.skin.label.wordWrap = false;
GUI.Label(new Rect(0.0f, bgRect.y + bgRect.height + 85.0f, 700.0f, 30.0f), "Left click to select and move a control point. Right click to add a control point, and ctrl + right click to delete.");
// TEST!!! TODO
volRendObject.GetComponent<MeshRenderer>().sharedMaterial.SetTexture("_TFTex", tfTexture);
volRendObject.GetComponent<MeshRenderer>().sharedMaterial.DisableKeyword("TF2D_ON");
volRendObject.SetTransferFunctionMode(TFRenderMode.TF1D);
GUI.color = oldColour;
}

Просмотреть файл

@ -10,7 +10,7 @@ namespace UnityVolumeRendering
{
VolumeRenderedObject myTarget = (VolumeRenderedObject)target;
RenderMode oldRenderMode = myTarget.GetRemderMode();
RenderMode oldRenderMode = myTarget.GetRenderMode();
RenderMode newRenderMode = (RenderMode)EditorGUILayout.EnumPopup("Render mode", oldRenderMode);
if (newRenderMode != oldRenderMode)

Просмотреть файл

@ -18,7 +18,8 @@ namespace UnityVolumeRendering
public TransferFunction()
{
texture = new Texture2D(TEXTURE_WIDTH, TEXTURE_HEIGHT, TextureFormat.RGBAFloat, false);
TextureFormat texformat = SystemInfo.SupportsTextureFormat(TextureFormat.RGBAHalf) ? TextureFormat.RGBAHalf : TextureFormat.RGBAFloat;
texture = new Texture2D(TEXTURE_WIDTH, TEXTURE_HEIGHT, texformat, false);
tfCols = new Color[TEXTURE_WIDTH * TEXTURE_HEIGHT];
}

Просмотреть файл

@ -24,7 +24,8 @@ namespace UnityVolumeRendering
public TransferFunction2D()
{
texture = new Texture2D(TEXTURE_WIDTH, TEXTURE_HEIGHT, TextureFormat.RGBAFloat, false);
TextureFormat texformat = SystemInfo.SupportsTextureFormat(TextureFormat.RGBAHalf) ? TextureFormat.RGBAHalf : TextureFormat.RGBAFloat;
texture = new Texture2D(TEXTURE_WIDTH, TEXTURE_HEIGHT, texformat, false);
}
public void AddBox(float x, float y, float width, float height, Color colour, float alpha)

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9805df7fa7b5e1b4cbc7c9c9fb18d2d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -10,16 +10,25 @@ namespace UnityVolumeRendering
private int minDataValue = int.MaxValue;
private int maxDataValue = int.MinValue;
private Texture3D texture = null;
private Texture3D dataTexture = null;
private Texture3D gradientTexture = null;
public Texture3D GetTexture()
public Texture3D GetDataTexture()
{
if (texture == null)
if (dataTexture == null)
{
texture = new Texture3D(dimX, dimY, dimZ, TextureFormat.RGBAFloat, false);
texture.wrapMode = TextureWrapMode.Clamp;
dataTexture = CreateTextureInternal();
}
return texture;
return dataTexture;
}
public Texture3D GetGradientTexture()
{
if (gradientTexture == null)
{
gradientTexture = CreateGradientTextureInternal();
}
return gradientTexture;
}
public int GetMinDataValue()
@ -48,5 +57,69 @@ namespace UnityVolumeRendering
maxDataValue = Math.Max(maxDataValue, val);
}
}
private Texture3D CreateTextureInternal()
{
TextureFormat texformat = SystemInfo.SupportsTextureFormat(TextureFormat.RHalf) ? TextureFormat.RHalf : TextureFormat.RFloat;
Texture3D texture = new Texture3D(dimX, dimY, dimZ, texformat, false);
texture.wrapMode = TextureWrapMode.Clamp;
int minValue = GetMinDataValue();
int maxValue = GetMaxDataValue();
int maxRange = maxValue - minValue;
Color[] cols = new Color[data.Length];
for (int x = 0; x < dimX; x++)
{
for (int y = 0; y < dimY; y++)
{
for (int z = 0; z < dimZ; z++)
{
int iData = x + y * dimX + z * (dimX * dimY);
cols[iData] = new Color((float)(data[iData] - minValue) / maxRange, 0.0f, 0.0f, 0.0f);
}
}
}
texture.SetPixels(cols);
texture.Apply();
return texture;
}
private Texture3D CreateGradientTextureInternal()
{
TextureFormat texformat = SystemInfo.SupportsTextureFormat(TextureFormat.RGBAHalf) ? TextureFormat.RGBAHalf : TextureFormat.RGBAFloat;
Texture3D texture = new Texture3D(dimX, dimY, dimZ, texformat, false);
texture.wrapMode = TextureWrapMode.Clamp;
int minValue = GetMinDataValue();
int maxValue = GetMaxDataValue();
int maxRange = maxValue - minValue;
Color[] cols = new Color[data.Length];
for (int x = 0; x < dimX; x++)
{
for (int y = 0; y < dimY; y++)
{
for (int z = 0; z < dimZ; z++)
{
int iData = x + y * dimX + z * (dimX * dimY);
int x1 = data[Math.Min(x + 1, dimX - 1) + y * dimX + z * (dimX * dimY)] - minValue;
int x2 = data[Math.Max(x - 1, 0) + y * dimX + z * (dimX * dimY)] - minValue;
int y1 = data[x + Math.Min(y + 1, dimY - 1) * dimX + z * (dimX * dimY)] - minValue;
int y2 = data[x + Math.Max(y - 1, 0) * dimX + z * (dimX * dimY)] - minValue;
int z1 = data[x + y * dimX + Math.Min(z + 1, dimZ - 1) * (dimX * dimY)] - minValue;
int z2 = data[x + y * dimX + Math.Max(z - 1, 0) * (dimX * dimY)] - minValue;
Vector3 grad = new Vector3((x2 - x1) / (float)maxRange, (y2 - y1) / (float)maxRange, (z2 - z1) / (float)maxRange);
cols[iData] = new Color(grad.x, grad.y, grad.z, (float)(data[iData] - minValue) / maxRange);
}
}
}
texture.SetPixels(cols);
texture.Apply();
return texture;
}
}
}

Просмотреть файл

@ -6,4 +6,10 @@
MaximumIntensityProjectipon,
IsosurfaceRendering
}
public enum TFRenderMode
{
TF1D,
TF2D
}
}

Просмотреть файл

@ -14,41 +14,6 @@ namespace UnityVolumeRendering
volObj.dataset = dataset;
int dimX = dataset.dimX;
int dimY = dataset.dimY;
int dimZ = dataset.dimZ;
int minValue = dataset.GetMinDataValue();
int maxValue = dataset.GetMaxDataValue();
int maxRange = maxValue - minValue;
Color[] cols = new Color[dataset.data.Length];
for (int x = 0; x < dataset.dimX; x++)
{
for (int y = 0; y < dataset.dimY; y++)
{
for (int z = 0; z < dataset.dimZ; z++)
{
int iData = x + y * dimX + z * (dimX * dimY);
int x1 = dataset.data[Math.Min(x + 1, dimX - 1) + y * dataset.dimX + z * (dataset.dimX * dataset.dimY)] - minValue;
int x2 = dataset.data[Math.Max(x - 1, 0) + y * dataset.dimX + z * (dataset.dimX * dataset.dimY)] - minValue;
int y1 = dataset.data[x + Math.Min(y + 1, dimY - 1) * dataset.dimX + z * (dataset.dimX * dataset.dimY)] - minValue;
int y2 = dataset.data[x + Math.Max(y - 1, 0) * dataset.dimX + z * (dataset.dimX * dataset.dimY)] - minValue;
int z1 = dataset.data[x + y * dataset.dimX + Math.Min(z + 1, dimZ - 1) * (dataset.dimX * dataset.dimY)] - minValue;
int z2 = dataset.data[x + y * dataset.dimX + Math.Max(z - 1, 0) * (dataset.dimX * dataset.dimY)] - minValue;
Vector3 grad = new Vector3((x2 - x1) / (float)maxRange, (y2 - y1) / (float)maxRange, (z2 - z1) / (float)maxRange);
cols[iData] = new Color(grad.x, grad.y, grad.z, (float)(dataset.data[iData] - minValue) / maxRange);
}
}
}
Texture3D tex = dataset.GetTexture();
tex.SetPixels(cols);
tex.Apply();
const int noiseDimX = 512;
const int noiseDimY = 512;
Texture2D noiseTexture = NoiseTextureGenerator.GenerateNoiseTexture(noiseDimX, noiseDimY);
@ -62,7 +27,8 @@ namespace UnityVolumeRendering
TransferFunction2D tf2D = TransferFunctionDatabase.CreateTransferFunction2D();
volObj.transferFunction2D = tf2D;
meshRenderer.sharedMaterial.SetTexture("_DataTex", tex);
meshRenderer.sharedMaterial.SetTexture("_DataTex", dataset.GetDataTexture());
meshRenderer.sharedMaterial.SetTexture("_GradientTex", null);
meshRenderer.sharedMaterial.SetTexture("_NoiseTex", noiseTexture);
meshRenderer.sharedMaterial.SetTexture("_TFTex", tfTexture);

Просмотреть файл

@ -13,7 +13,8 @@ namespace UnityVolumeRendering
[HideInInspector]
public VolumeDataset dataset;
private RenderMode remderMode;
private RenderMode renderMode;
private TFRenderMode tfRenderMode;
public SlicingPlane CreateSlicingPlane()
{
@ -24,7 +25,7 @@ namespace UnityVolumeRendering
MeshRenderer sliceMeshRend = sliceRenderingPlane.GetComponent<MeshRenderer>();
sliceMeshRend.material = new Material(sliceMeshRend.sharedMaterial);
Material sliceMat = sliceRenderingPlane.GetComponent<MeshRenderer>().sharedMaterial;
sliceMat.SetTexture("_DataTex", dataset.GetTexture());
sliceMat.SetTexture("_DataTex", dataset.GetDataTexture());
sliceMat.SetTexture("_TFTex", transferFunction.GetTexture());
sliceMat.SetMatrix("_parentInverseMat", transform.worldToLocalMatrix);
sliceMat.SetMatrix("_planeMat", Matrix4x4.TRS(sliceRenderingPlane.transform.position, sliceRenderingPlane.transform.rotation, Vector3.one)); // TODO: allow changing scale
@ -34,37 +35,63 @@ namespace UnityVolumeRendering
public void SetRenderMode(RenderMode mode)
{
remderMode = mode;
renderMode = mode;
UpdateMaaterialProperties();
}
switch (mode)
public void SetTransferFunctionMode(TFRenderMode mode)
{
tfRenderMode = mode;
UpdateMaaterialProperties();
}
public RenderMode GetRenderMode()
{
return renderMode;
}
private void UpdateMaaterialProperties()
{
MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
bool useGradientTexture = tfRenderMode == TFRenderMode.TF2D || renderMode == RenderMode.IsosurfaceRendering;
meshRenderer.sharedMaterial.SetTexture("_GradientTex", useGradientTexture ? dataset.GetGradientTexture() : null);
if(tfRenderMode == TFRenderMode.TF2D)
{
meshRenderer.sharedMaterial.SetTexture("_TFTex", transferFunction2D.GetTexture());
meshRenderer.sharedMaterial.EnableKeyword("TF2D_ON");
}
else
{
meshRenderer.sharedMaterial.SetTexture("_TFTex", transferFunction.GetTexture());
meshRenderer.sharedMaterial.DisableKeyword("TF2D_ON");
}
switch (renderMode)
{
case RenderMode.DirectVolumeRendering:
{
GetComponent<MeshRenderer>().sharedMaterial.EnableKeyword("MODE_DVR");
GetComponent<MeshRenderer>().sharedMaterial.DisableKeyword("MODE_MIP");
GetComponent<MeshRenderer>().sharedMaterial.DisableKeyword("MODE_SURF");
meshRenderer.sharedMaterial.EnableKeyword("MODE_DVR");
meshRenderer.sharedMaterial.DisableKeyword("MODE_MIP");
meshRenderer.sharedMaterial.DisableKeyword("MODE_SURF");
break;
}
case RenderMode.MaximumIntensityProjectipon:
{
GetComponent<MeshRenderer>().sharedMaterial.DisableKeyword("MODE_DVR");
GetComponent<MeshRenderer>().sharedMaterial.EnableKeyword("MODE_MIP");
GetComponent<MeshRenderer>().sharedMaterial.DisableKeyword("MODE_SURF");
meshRenderer.sharedMaterial.DisableKeyword("MODE_DVR");
meshRenderer.sharedMaterial.EnableKeyword("MODE_MIP");
meshRenderer.sharedMaterial.DisableKeyword("MODE_SURF");
break;
}
case RenderMode.IsosurfaceRendering:
{
GetComponent<MeshRenderer>().sharedMaterial.DisableKeyword("MODE_DVR");
GetComponent<MeshRenderer>().sharedMaterial.DisableKeyword("MODE_MIP");
GetComponent<MeshRenderer>().sharedMaterial.EnableKeyword("MODE_SURF");
meshRenderer.sharedMaterial.DisableKeyword("MODE_DVR");
meshRenderer.sharedMaterial.DisableKeyword("MODE_MIP");
meshRenderer.sharedMaterial.EnableKeyword("MODE_SURF");
break;
}
}
}
public RenderMode GetRemderMode()
{
return remderMode;
}
}
}

Просмотреть файл

@ -3,6 +3,7 @@
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
@ -53,6 +54,7 @@
};
sampler3D _DataTex;
sampler3D _GradientTex;
sampler2D _NoiseTex;
sampler2D _TFTex;
@ -79,13 +81,13 @@
// Gets the density at the specified position
float getDensity(float3 pos)
{
return tex3Dlod(_DataTex, float4(pos.x, pos.y, pos.z, 0.0f)).a;
return tex3Dlod(_DataTex, float4(pos.x, pos.y, pos.z, 0.0f));
}
// Gets the gradient at the specified position
float3 getGradient(float3 pos)
{
return tex3Dlod(_DataTex, float4(pos.x, pos.y, pos.z, 0.0f)).rgb;
return tex3Dlod(_GradientTex, float4(pos.x, pos.y, pos.z, 0.0f)).rgb;
}
// Converts local position to depth value

Просмотреть файл

@ -54,7 +54,7 @@ Shader "VolumeRendering/SliceRenderingShader"
fixed4 frag (v2f i) : SV_Target
{
float3 dataCoord = i.relVert +float3(0.5f, 0.5f, 0.5f);
float dataVal = tex3D(_DataTex, dataCoord).a;
float dataVal = tex3D(_DataTex, dataCoord);
float4 col = tex2D(_TFTex, float2(dataVal, 0.0f));
col.a = 1.0f;