How to pass an uint uniform

Help.

How could i pass an uint uniform to fs/cs shader.

By default, Unity materials only support float point and (fairly recently) signed integer values. You can have a shader uniform be a uint and Unity will internally convert whatever float or integer property you have to a uint for you, but that’s not as helpful if you’re looking to pack a lot of data into a uint and not have it get modified at all. But for simple use cases that can work well enough.

// in c#
// auto cast from uint to signed int
myMaterial.SetInteger("_MyUintValue", myUintValue);


// in shader file
// shader property
Properties {
  // note there's also an Int property type, but that's a float masquerading as an integer
  _MyUintValue ("packed uint", Integer) = 0
}

// inside the CGPROGRAM or HLSLPROGRAM, but outside of a function
uint _MyUintValue;

// use as needed in your shader functions

This will work for uint values up to 2,147,483,647, ie: the equivalent of a 31 bit uint, as anything beyond that is outside the range a signed 32 bit integer can represent. But the automatic casting between uint and int shouldn’t loose any information. If you require all 32 bits, then you have to go a slightly more complex route using compute buffers.

// in c#
// create a compute buffer with 1 element, 32 bits wide
ComputeBuffer myComputeBuffer = ComputeBuffer(1, 32);

// create a uint array with a single element with the value you want to pass
uint[] myData = [myUintValue];

// assign the array as the data for the buffer
myComputeBuffer.SetData(myData);

// set buffer on your material
myMaterial.SetBuffer("MyUintValue", myComputeBuffer);
// note, you don't have the set the buffer on the material again if you change the data in the buffer later
// but there's also no harm in doing so


// in shader file
// inside the CGPROGRAM or HLSLPROGRAM, but outside of a function
StructuredBuffer<uint> MyUintValue;

// inside your function
uint myUintValue = MyUintValue[0];
1 Like

bgolus, so cool. Thanks.

Another Question:

if i define a RWTexture Tex in computer shader, and write some value into the Tex,

and then i declare it as RWTexture Tex in a fragment shader after the compute shader finish,

what is the real type?

The “real” type is whatever format you created the texture resource as. But that doesn’t matter since the type specifier is how the data in the texture will be interpreted. AFAIK in the fragment shader using RWTexture<int> tex; will result in the same thing as using RWTexture<uint> tex; and then doing asint(tex[0]) in the code later. The bits are intepreted at an int, regardless of how they were originally encoded or stored.

1 Like

I got it. Thanks, Bro.:slight_smile: