Calculate Shaders 3D Input Float Array

Writing a computational shader for use in Unity 4. I am trying to get 3d noise.

The goal is to get a multidiminant array of float3 into my computational shader from my C # code. Is this possible in a simple way (using some kind of declaration) or can only be achieved using Texture3D objects?

Currently, I have an implementation of simplex noise working at individual points of float3, outputting one float -1 to 1. I ported the found code here for a computational shader.

I would like to expand this to work on a three-dimensional array of float3 (I believe that the closest comparison in C # would be Vector3[,,]) by applying a noise operation to every point of float3 in the array.

I tried a few other things, but they seem weird and completely overlook the use of a parallel approach. Above was what I think it should look like.

I also managed to get Scrawk's . The work is performed in the form of vertex shaders. Scrawk got the 3D array float4 into the shader using Texture3D . But I could not extract the floats from the texture. Does Compute Shaders work? Drawing on textures? I probably missed something regarding getting values ​​from the Texture. This user seems to be receiving data in this message . A similar question to me, but not quite what I'm looking for.

New to shaders in general, and I feel like I'm missing something quite fundamental in Compute Shaders and how they work. The goal is to (as I’m sure you guessed it) get noise generation and grid calculation using marching cubes on the GPU using Compute Shaders (or any other shader is best suited for this kind of work).

Limitations - This is a free trial edition of Unity 4.

Here is the skeleton of the C # code I'm using:

    int volumeSize = 16; 
    compute.SetInt ("simplexSeed", 10); 

    // This will be a float[,,] array with our density values. 
    ComputeBuffer output = new ComputeBuffer (/*s ize goes here, no idea */, 16);
    compute.SetBuffer (compute.FindKernel ("CSMain"), "Output", output);  

    // Buffer filled with float3[,,] equivalent, what ever that is in C#. Also what is 'Stride'? 
    // Haven't found anything exactly clear. I think it the size of basic datatype we're using in the buffer?
    ComputeBuffer voxelPositions = new ComputeBuffer (/* size goes here, no idea */, 16); 
    compute.SetBuffer (compute.FindKernel ("CSMain"), "VoxelPos", voxelPositions);    


    compute.Dispatch(0,16,16,16);
    float[,,] res = new float[volumeSize, volumeSize, volumeSize];

    output.GetData(res); // <=== populated with float density values

    MarchingCubes.DoStuff(res); // <=== The goal (Obviously not implemented yet)

And here is the Compute Shader

#pragma kernel CSMain

uniform int simplexSeed;
RWStructuredBuffer<float3[,,]> VoxelPos;  // I know these won't work, but it what I'm trying
RWStructuredBuffer<float[,,]> Output;     // to get in there. 

float simplexNoise(float3 input)
{
    /* ... A bunch of awesome stuff the pastebin guy did ...*/

    return noise;
}

/** A bunch of other awesome stuff to support the simplexNoise function **/
/* .... */

/* Here the entry point, with my (supposedly) supplied input kicking things off */
[numthreads(16,16,16)] // <== Not sure if this thread count is correct? 
void CSMain (uint3 id : SV_DispatchThreadID)
{
    Output[id.xyz] = simplexNoise(VoxelPos.xyz); // Where the action starts.     
}
+3
source share
2 answers

Using the 1D buffer, index it as 3D, by special indexing, on the CPU and GPU.

HLSL . / N- (, 3D 2D) 1D, 1D-.

3D- [z][y][x] (. # 1 ) array[Z_MAX][Y_MAX][X_MAX], [z][y][x] [i].

...

, ( ), xy - /, z, . z () , x (width) * y (height). , : y ( , ) , x (width), . , x, . 1D.

i = z * (Y_MAX * X_MAX) + y * (X_MAX) + x; //you may need to use "*_MAX - 1" instead

# 1 , , y z. [z][y][x] ; . . Unity [z][y][x] [y][z][x] ( , .)

# 2 uint3 id : SV_DispatchThreadID uint3 threadID : SV_GroupThreadID uint3 groupID : SV_GroupID. . :

SV_DispatchThreadID - SV_GroupID * numthreads GroupThreadID.

... , , .

# 3 , N- C .

+1

- ... ? , .

, (16 x 16 x 16 ) .

, , 2d. seodo CPU code ...

for(x)
  for(z)
    fill all voxels below ( GenerateY(x,z) )

, , ...

16 x 16 x 16 , 1024 , , 1024 .

[numthreads(16,16,16)] // <== Not sure if this thread count is correct? 

, , [numthreads (16,1,16)], 16 x 16 x maxHeight, .

:

compute.Dispatch(0,1,0,0);

... , 16 x 16 . , .

, , , , , .

, , - , mesh/scene . , , - AppendBuffers.

!

:

, , 128 * 128 * 128 , 32 * 32 * 32 , ...

//cpu code 
var size = 128*128*128;
var stride = sizeof(float);
ComputeBuffer output = new ComputeBuffer (size, stride);
computeShader.SetBuffer (0, "voxels", output);
computeshader.Dispatch(0, 4,4,4);

//gpu code
#pragma kernel compute
RWStructuredBuffer<float> voxels;

[numthreads(32,1,32)] // group is your chunk index, thread is you voxel within the chunk
void compute (uint3 threadId : SV_GroupThreadID, uint3 groupId : SV_GroupID)
{
    uint3 threadIndex =  groupId * uint3(32, 1, 32) + threadId;
   //TODO: implement any marching cubes / dual contouring functions in
   //      here somewhere
   uint3 endIndex = uint(32, 0, 32) + threadIndex;

   float height = Noise();
   int voxelPos = voxPos.x+ voxPos.y*size+voxPos.z*size*size;

   // chunks are 32 * 32 blocks of columns the whole height of the volume
   for(int y = threadIndex.y; y < endIndex.y; y++)
   {
      if(y < height)
      {
         voxels[voxelPos] = 1; // fill this voxel
      }
          else
          {
                 voxels[voxelPos] = 0; // dont fill this voxel
          }
   }

( , ) 128 * 128 * 128 voxel , - "".

, , , , "if" , xyz threadIndex ( ).

, , , .

( ) - ...

... - . voxelbuffer.

( )...

0

All Articles