This site uses strictly necessary cookies. More Information

X- Home /

# Get Voxel Intensities by location

I'm wondering if it's possible to get the voxel value at a given position? Here is the code used to fill the voxels:

```
for (int k = 0; k < NumberOfFrames; k++) {
string fname_ = "T" + k.ToString("D2");
Color[] colors = LoadData(Path.Combine (imageDir, fname_+".raw"));
_volumeBuffer.Add (new Texture3D (dim [0], dim [1], dim [2], TextureFormat.RGBAHalf, mipmap));
_volumeBuffer[k].SetPixels(colors);
_volumeBuffer [k].Apply ();
}
GetComponent<Renderer>().material.SetTexture("_Data", _volumeBuffer[0]);
```

Does anybody know how to get a value at a given position in space??

Thanks!

**Answer** by bigvalthoss
·
Feb 24 at 08:58 PM

Took me a little bit, but I've figured it out I think. If there is a flaw in my coding, please let me know :)

```
public Vector3Int GetIndexFromWorld(Vector3 worldPos)
{
Vector3 deltaBounds = rend.bounds.max - rend.bounds.min;
Vector3 OffsetPos = worldPos - rend.bounds.min;
Vector3 normPos = new Vector3(OffsetPos[0] / deltaBounds[0], OffsetPos[1] / deltaBounds[1], OffsetPos[2] / deltaBounds[2]);
Vector3 voxelPositions = new Vector3(normPos[0] * voxelDims[0], normPos[1] * voxelDims[1], normPos[2] * voxelDims[2]);
Vector3Int voxelPos = Vector3Int.FloorToInt(voxelPositions);
return voxelPos;
}
```

@$$anonymous$$o-Khaon I have a dataset that is 512 x 256 x 512. It can be resized, is there any way you could think to find the voxel index from a world position (if it is inside the object).

@whydoidoit Do you have any input on this question?

**Answer** by Eno-Khaon
·
Feb 28 at 08:23 PM

Since you're using *transform.InverseTransformPoint()* to transform a point from world to local space, the most straightforward way to position voxels "physically" is to place them at their absolute positions relative to the *GameObject* (i.e. *(0, 0, 0)*, *(15, 98, 17)*, etc.) so that their positions can inherently be used as-is when converted to 3-dimensional array indices. (Note that this may also call for *Mathf.RoundToInt()* or *Mathf.FloorToInt()* usage, depending on how coordinates are used and whether anything like 0.5 offsets would be applied to positions to "center" the voxels)

If any repositioning or scaling is also applied to the voxels at the construction level (ideally, rotation should be a *Transform*-only modification), then a given block of voxel data would also need its own scaling factor(s) and position offset data.

```
// Reformatting your function as an example
public Vector3Int GetIndexFromWorld(Vector3 worldPos)
{
Vector3 localPos = transform.InverseTransformPoint(worldPos);
// If further scaling needs to be done:
// Where scaleFactor is voxels-per-unit...
// Scale is a Vector3
localPos = Vector3.Scale(localPos, scaleFactor);
// Scale is a float/int
localPos *= scaleFactor;
// voxelOffset would be a factor when the voxel-grid doesn't begin
// at (0, 0, 0) of its containing GameObject/Mesh
Vector3Int voxelPos = Vector3Int.FloorToInt(localPos + voxelOffset);
// Using FloorToInt() on the assumption that there IS NOT an additional
// 0.5-voxel offset baked in that's not part of the main offset
// If there was, RoundToInt() would be the better choice here
return voxelPos;
}
```

All in all, the kinds of modifications that need to be applied are really just based on whether (and how) you want to pack additional data in. If you performed ***ALL*** transformations to the voxel data using the *GameObject*'s *Transform* data instead, your function would look more like this:

```
public Vector3Int GetIndexFromWorld(Vector3 worldPos)
{
Vector3 localPos = transform.InverseTransformPoint(worldPos);
Vector3Int voxelPos = Vector3Int.FloorToInt(localPos);
return voxelPos;
}
```

Thank you very much for the answer, I think your way would probably work. however, I am having trouble coming up with finding the scaling factor and the offset. Would you be able to help me out with that? dim[0-2] are the dimensions of the dataset. The current one I'm using is 512 x 256 x 512.

Here is how the local scale is defined:

```
this.transform.localScale = new Vector3(mhdheader.spacing[0] volScale, mhdheader.spacing[1] volScale dim[1] / dim[0], mhdheader.spacing[2] volScale * dim[2] / dim[0]);
```

Would I just create my offset by doing:

```
Vector3 localPos = transform.InverseTransformPoint(worldPos);
Vector3 localScale = gameObject.transform.localScale;
Vector3 OffsetPos = localPos + localScale / 2;
```

And then I need to find what to scale it by, which is causing me a little grief as well...

In general, the scaling factor and offset don't really need to be tracked using a dual system. While you **could** have something like...

```
Vector3 scale = transform.localScale * myScale;
Vector3 offset = localPos + Vector3.Scale(scale, myOffset);
```

... that's actually not very valuable to have a mishmash of your own script's values ***AND*** *Transform* attributes.

However, that's why I offer the suggestion of performing all transformations using just the *Transform* data of the containing *GameObject*. That way, voxel[0,0,0] would be located at the local (0, 0, 0) of the *Transform*. Then, if you want, say, 5 voxels per unit/meter/etc., you'd just have something like:

```
transform.localScale = Vector3.one / 5.0f;
```

By contrast, if you wanted to ignore the *GameObject*'s *Transform* data entirely (which a Renderer wouldn't love, in terms of position relative to object origin), then you'd want to place the *GameObject* at *Vector3.zero* position, *Quaternion.identity* rotation, and *Vector3.one* scale.

That really would defeat the purpose of having *Transform* data to begin with, though, and would actually be a hindrance (at best).

Basically, if you just store values for your scale, position, and rotation, then apply those to the Transform, that's all you need to do. The rest just depends on how you want to store that data for use.

```
// voxel grid position is stored as world position
transform.position = voxelGridWorldPos;
// alternate: voxel grid position is stored in small integer form
// Vector3 voxelGridSize: (512x512x256)
// Vector3Int voxelGridPos: (i.e. (5, -2, 0))
transform.position = Vector3.Scale(voxelGridSize * voxelScale, voxelGridPos);
// voxel grid position is stored as Quaternion
transform.rotation = voxelGridRot;
// alternate: rotation is stored as XYZ Euler values
transform.rotation = Quaternion.Euler(vgrX, vgrY, vgrZ);
// voxel grid scale is a single value for uniform scaling
transform.localScale = Vector3.one * voxelScale;
// alternate: voxel grid scale is stored directly as a Vector3
transform.localScale = voxelScaleVector3;
// alternate: scale is stored as 3 axis scalars
transform.localScale = new Vector3(scaleX, scaleY, scaleZ);
// alternate: scale is stored as voxels-per-unit (Vector3 example)
transform.localScale = new Vector3(1f / vpu.x, 1f / vpu.y, 1f / vpu.z);
```

Would it be at all possible to like call over google meet about this? I don't think I entirely follow... It would help a lot

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

Create a memory buffer for delayed rendering 0 Answers

Confusion With Voxel Based Games 1 Answer

Is MapMagic (asset) Voxel based? 0 Answers

Will my VR project (currently using mouse) run correctly when I return to a PC with a headset? 1 Answer

Oculus "PerEyeCameras" showing blackscreen only when LWRP or URP is enabled 0 Answers