ComputeShader参数详解

/

ComputeBuffer

Description

GPU data buffer, mostly for use with compute shaders.

ComputeShader programs often need arbitrary data to be read & written into memory buffers. ComputeBuffer class is exactly for that - you can create & fill them from script code, and use them in compute shaders or regular shaders.

Compute buffers are always supported in compute shaders. Compute shader support can be queried runtime using SystemInfo.supportsComputeShaders. See the Compute Shaders Manual page for more information about platforms supporting compute shaders. In regular graphics shaders the compute buffer support requires minimum shader model 4.5.

For a C

omputeBuffer that uses a counter, Metal and Vulkan platforms don't have native counters and use separate small buffers that act as counters internally. These small buffers are bound separately from the ComputeBuffer and count towards the limit of possible buffers bound (31 for Metal, based on the device for Vulkan).

On the shader side, ComputeBuffers with default ComputeBufferType map to StructuredBuffer<T> and RWStructuredBuffer<T> in HLSL.

Properties

countNumber of elements in the buffer (Read Only).
nameThe debug label for the compute buffer (setter only).
strideSize of one element in the buffer (Read Only).

Constructors

ComputeBufferCreate a Compute Buffer.

Public Methods

BeginWriteBegins a write operation to the buffer
EndWriteEnds a write operation to the buffer
GetDataRead data values from the buffer into an array. The array can only use blittable types.
GetNativeBufferPtrRetrieve a native (underlying graphics API) pointer to the buffer.
IsValidReturns true if this compute buffer is valid and false otherwise.
ReleaseRelease a Compute Buffer.
SetCounterValueSets counter value of append/consume buffer.
SetDataSet the buffer with values from an array.

Static Methods

CopyCountCopy counter value of append/consume buffer into another buffer.

///

Material.SetBuffer

Declaration

public void SetBuffer(string name, ComputeBuffer value);

Declaration

public void SetBuffer(int nameID, ComputeBuffer value);

Declaration

public void SetBuffer(string name, GraphicsBuffer value);

Declaration

public void SetBuffer(int nameID, GraphicsBuffer value);

Parameters

nameIDProperty name ID, use Shader.PropertyToID to get it.
nameProperty name.
valueThe ComputeBuffer or GraphicsBuffer value to set.

Description

Sets a named buffer value.

/

Shader.SetGlobalBuffer

Declaration

public static void SetGlobalBuffer(string name, ComputeBuffer value);

Declaration

public static void SetGlobalBuffer(int nameID, ComputeBuffer value);

Declaration

public static void SetGlobalBuffer(string name, GraphicsBuffer value);

Declaration

public static void SetGlobalBuffer(int nameID, GraphicsBuffer value);

Parameters

nameIDThe name ID of the property retrieved by Shader.PropertyToID.
nameThe name of the property.
valueThe buffer to set.

Description

Sets a global buffer property for all shaders.

Global properties are used if a shader needs them but the material does not have them defined (for example, if the shader does not expose them in Properties block).

See Also: SetGlobalTextureComputeBuffer class, GraphicsBuffer class, ShaderLab documentation.

//

ComputeBufferType

Description

ComputeBuffer type.

Different types of compute buffers map to different usage and declarations in HLSL shaders. Default type is "structured buffer" (StructuredBuffer<T> or RWStructuredBuffer<T>).

See Also: ComputeBufferComputeShaderMaterial.SetBuffer.

Properties

DefaultDefault ComputeBuffer type (structured buffer).
RawRaw ComputeBuffer type (byte address buffer).
AppendAppend-consume ComputeBuffer type.
CounterComputeBuffer with a counter.
ConstantComputeBuffer that you can use as a constant buffer (uniform buffer).
StructuredComputeBuffer that you can use as a structured buffer.
IndirectArgumentsComputeBuffer used for Graphics.DrawProceduralIndirect, ComputeShader.DispatchIndirect or Graphics.DrawMeshInstancedIndirect arguments.

ComputeBuffer.SetData

Declaration

public void SetData(Array data);

Declaration

public void SetData(List<T> data);

Declaration

public void SetData(NativeArray<T> data);

Parameters

dataArray of values to fill the buffer.

Description

Set the buffer with values from an array.

The input data must follow the data layout rules of the graphics API in use. See Compute Shaders for cross-platform compatibility information.

Note: Because only blittable data types can be copied from the array to the buffer, the array must only contain elements of a blittable type. If you attempt to use non-blittable types, an exception will be raised.

See Also: GetDatacountstride.


Declaration

public void SetData(Array data, int managedBufferStartIndex, int computeBufferStartIndex, int count);

Declaration

public void SetData(List<T> data, int managedBufferStartIndex, int computeBufferStartIndex, int count);

Declaration

public void SetData(NativeArray<T> data, int nativeBufferStartIndex, int computeBufferStartIndex, int count);

Parameters

dataArray of values to fill the buffer.
managedBufferStartIndexThe first element index in data to copy to the compute buffer.
computeBufferStartIndexThe first element index in compute buffer to receive the data.
countThe number of elements to copy.

Description

Partial copy of data values from an array into the buffer.

The input data must follow the data layout rules of the graphics API in use. See Compute Shaders for cross-platform compatibility information.

Note: Because only blittable data types can be copied from the array to the buffer, the array must only contain elements of a blittable type. If you attempt to use non-blittable types, an exception will be raised.

See Also: GetDatacountstride.

ComputeBuffer.GetData

Declaration

public void GetData(Array data);

Parameters

dataAn array to receive the data.

Description

Read data values from the buffer into an array. The array can only use blittable types.

The retrieved data will follow the data layout rules of the graphics API in use. See Compute Shaders for cross-platform compatibility information.

Note that this function reads the data back from the GPU, which can be slow. If any GPU work has been submitted that writes to this buffer, Unity waits for the tasks to complete before it retrieves the requested data, guaranteeing this function returns the most up to date results. For this reason, you should use AsyncGPUReadback instead because it performs the request in the background, and allows you to check when the result is available, without blocking the main thread.

Note: Only blittable data types can be copied from the buffer to the array, the array's type must be a blittable type. If you attempt to use non-blittable types, an exception will be raised.

See Also: SetDatacountstride.


Declaration

public void GetData(Array data, int managedBufferStartIndex, int computeBufferStartIndex, int count);

Parameters

dataAn array to receive the data.
managedBufferStartIndexThe first element index in data where retrieved elements are copied.
computeBufferStartIndexThe first element index of the compute buffer from which elements are read.
countThe number of elements to retrieve.

Description

Partial read of data values from the buffer into an array.

The retrieved data will follow the data layout rules of the graphics API in use. See Compute Shaders for cross-platform compatibility information.

Note: Only blittable data types can be copied from the buffer to the array, the array's type must be a blittable type. If you attempt to use non-blittable types, an exception will be raised.

See Also: SetDatacountstride.

//

ComputeBuffer.BeginWrite

Declaration

public NativeArray<T> BeginWrite(int computeBufferStartIndex, int count);

Parameters

computeBufferStartIndexOffset in number of elements to which the write operation will occur
countMaximum number of elements which will be written

Returns

NativeArray<T> A NativeArray of size count

Description

Begins a write operation to the buffer

Use this to begin a write operation on the buffer. Using this method results in fewer memory copies than using ComputeBuffer.SetData, and is therefore faster. For compatibility reasons, you can only call this method on buffers where the ComputeBufferMode is ComputeBufferMode.SubUpdates. If you call this method on a buffer with a different ComputeBufferMode, Unity will throw an exception.

The returned native array points directly to GPU memory if possible. If it it not possible to write directly to GPU memory, the returned native array points to a temporary buffer in CPU memory. Whether it is possible to write directly to GPU memory depends on many factors, including buffer mode, active graphics device, and hardware support.

Because of this, the contents of the returned array are not guaranteed to reflect the data content of the GPU side buffer. You should therefore use the returned array only for writing to, and not for reading from.

When you have written to the array, call ComputeBuffer.EndWrite to complete the operation and mark the returned NativeArray as unusable.

The performance of this method will vary depending on whether it can write directly to GPU memory or not, but it will always result in fewer memory copies than using SetData.

The data written to the returned native array must follow the data layout rules of the graphics API in use. See [[Compute Shaders]] for cross-platform compatibility information.

See Also: ComputeBuffer.SetDataComputeBuffer.EndWrite

ComputeBuffer.EndWrite

Declaration

public void EndWrite(int countWritten);

Parameters

countWrittenNumber of elements written to the buffer. Counted from the first element.

Description

Ends a write operation to the buffer

This call ends a write operation on the buffer. When you call this method, Unity marks the native array returned by the corresponding ComputeBuffer.BeginWrite call as unusuable, and then disposes of it.

/

ComputeBuffer.GetNativeBufferPtr

Declaration

public IntPtr GetNativeBufferPtr();

Returns

IntPtr Pointer to the underlying graphics API buffer.

Description

Retrieve a native (underlying graphics API) pointer to the buffer.

Use this function to retrieve a pointer/handle corresponding to the compute buffer, as it is represented in the native graphics API. This can be used to enable compute buffer data manipulation from native code plugins.

Note: When you use the Unity APIs to modify the buffer data, it changes the underlying graphics API native pointer. Call GetNativeBufferPtr to get the new native pointer.

The type of data returned depends on the underlying graphics API: ID3D11Buffer on D3D11, ID3D12Resource on D3D12, buffer "name" (as GLuint) on OpenGL/ES, MTLBuffer on Metal. Platforms that do not support compute shaders will always return NULL.

Note that calling this function when using multi-threaded rendering will synchronize with the rendering thread (a slow operation), so best practice is to set up needed buffer pointers only at initialization time.

//

ComputeBuffer.SetCounterValue

Declaration

public void SetCounterValue(uint counterValue);

Parameters

counterValueValue of the append/consume counter.

Description

Sets counter value of append/consume buffer.

Append/consume and counter buffers (see ComputeBufferType.AppendComputeBufferType.Counter) keep track of the number of elements in them with a special counter variable. SetCounterValue explicitly sets the counter value.

This can be used to reset the counter or to set it to a specific value.

Note: SetCounterValue can not be called while the buffer is bound via Graphics.SetRandomWriteTarget.

/

ComputeBuffer.CopyCount

Declaration

public static void CopyCount(ComputeBuffer src, ComputeBuffer dst, int dstOffsetBytes);

Parameters

srcAppend/consume buffer to copy the counter from.
dstA buffer to copy the counter to.
dstOffsetBytesTarget byte offset in dst.

Description

Copy counter value of append/consume buffer into another buffer.

Append/consume and counter buffers (see ComputeBufferType.AppendComputeBufferType.Counter) keep track of the number of elements in them with a special counter variable. CopyCount takes a buffer as src, and copies its counter value into dst buffer at given byte offset.

This is most commonly used in conjunction with Graphics.DrawProceduralIndirect, to render arbitrary number of primitives without reading their count back to the CPU.

On DX11 there is a restriction on the dst buffer - it must have been created with ComputeBufferType.Raw or ComputeBufferType.IndirectArguments type. On other platforms dst can be any type.

/

Compute shaders

Compute shaders are shader
 programs that run on the GPU, outside of the normal rendering pipeline.

They can be used for massively parallel GPGPU algorithms, or to accelerate parts of game rendering. In order to efficiently use them, an in-depth knowledge of GPU architectures and parallel algorithms is often needed; as well as knowledge of DirectComputeOpenGL ComputeCUDA, or OpenCL.

Compute shaders in Unity closely match DirectX 11 DirectCompute technology. Platforms where compute shaders work:

  • Windows and Windows Store, with a DirectX 11 or DirectX 12 graphics API and Shader Model 5.0 GPU

  • macOS and iOS
     using Metal graphics API

  • Android, Linux and Windows platforms with Vulkan API

  • Modern OpenGL platforms (OpenGL 4.3 on Linux or Windows; OpenGL ES 3.1 on Android). Note that Mac OS X does not support OpenGL 4.3

  • Modern consoles

Compute shader support can be queried runtime using SystemInfo.supportsComputeShaders.

Compute shader Assets

Similar to shader assets, compute shader assets are files in your project. with a .compute file extension. They are written in DirectX 11 style HLSL language, with a minimal number of #pragma compilation directives to indicate which functions to compile as compute shader kernels.

Here’s a basic example of a compute shader file, which fills the output texture with red:

// test.compute

#pragma kernel FillWithRed

RWTexture2D<float4> res;

[numthreads(1,1,1)]
void FillWithRed (uint3 dtid : SV_DispatchThreadID)
{
    res[dtid.xy] = float4(1,0,0,1);
}

The language is standard DX11 HLSL, with an additional #pragma kernel FillWithRed directive. One compute shader Asset file must contain at least onecompute kernel that can be invoked, and that function is indicated by the #pragma directive. There can be more kernels in the file; just add multiple #pragma kernel lines.

When using multiple #pragma kernel lines, note that comments of the style // text are not permitted on the same line as the #pragma kernel directives, and cause compilation errors if used.

The #pragma kernel line can optionally be followed by a number of preprocessor macros to define while compiling that kernel, for example:

#pragma kernel KernelOne SOME_DEFINE DEFINE_WITH_VALUE=1337
#pragma kernel KernelTwo OTHER_DEFINE
// ...

Invoking compute shaders

In your script, define a variable of ComputeShader type and assign a reference to the Asset. This allows you to invoke them with ComputeShader.Dispatch function. See Unity documentation on ComputeShader class for more details.

Closely related to compute shaders is a ComputeBuffer class, which defines arbitrary data buffer (“structured buffer” in DX11 lingo). Render Textures
 can also be written into from compute shaders, if they have “random access” flag set (“unordered access view” in DX11). See RenderTexture.enableRandomWrite to learn more about this.

Texture samplers in compute shaders

Textures and samplers aren’t separate objects in Unity, so to use them in compute shaders you must follow one of the following Unity-specific rules:

  • Use the same name as the Texture name, with sampler at the beginning (for example, Texture2D MyTexSamplerState samplerMyTex). In this case, the sampler is initialized to that Texture’s filter/wrap/aniso settings.

  • Use a predefined sampler. For this, the name has to have Linear or Point (for filter mode) and Clamp or Repeat (for wrap mode). For example, SamplerState MyLinearClampSampler creates a sampler that has Linear filter mode and Clamp wrap mode.

For more information, see documentation on Sampler States.

Cross-platform support

As with regular shaders, Unity is capable of translating compute shaders from HLSL to other shader languages. Therefore, for the easiest cross-platform builds, you should write compute shaders in HLSL. However, there are some factors that need to be considered when doing this.

Cross-platform best practices

DirectX 11 (DX11) supports many actions that are not supported on other platforms (such as Metal or OpenGL ES). Therefore, you should always ensure your shader has well-defined behavior on platforms that offer less support, rather than only on DX11. Here are few things to consider:

  • Out-of-bounds memory accesses are bad. DX11 might consistently return zero when reading, and read some writes without issues, but platforms that offer less support might crash the GPU when doing this. Watch out for DX11-specific hacks, buffer sizes not matching with multiple of your thread group size, trying to read neighboring data elements from the beginning or end of the buffer, and similar incompatibilities.

  • Initialize your resources. The contents of new buffers and Textures are undefined. Some platforms might provide all zeroes, but on others, there could be anything including NaNs.

  • Bind all the resources your compute shader declares. Even if you know for sure that the shader does not use resources in its current state because of branching, you must still ensure a resource is bound to it.

Platform-specific differences

  • Metal (for iOS and tvOS platforms) does not support atomic operations on Textures. Metal also does not support GetDimensions queries on buffers. Pass the buffer size info as constant to the shader if needed.

  • OpenGL ES 3.1 (for (Android, iOS, tvOS platforms) only guarantees support for 4 compute buffers at a time. Actual implementations typically support more, but in general if developing for OpenGL ES, you should consider grouping related data in structs rather than having each data item in its own buffer.

HLSL-only or GLSL-only compute shaders

Usually, compute shader files are written in HLSL, and compiled or translated into all necessary platforms automatically. However, it is possible to either prevent translation to other languages (that is, only keep HLSL platforms), or to write GLSL compute code manually.

The following information only applies to HLSL-only or GLSL-only compute shaders, not cross-platform builds. This is because this information can result in compute shader source being excluded from some platforms.

  • Compute shader source surrounded by CGPROGRAM and ENDCG keywords is not processed for non-HLSL platforms.

  • Compute shader source surrounded by GLSLPROGRAM and ENDGLSL keywords is treated as GLSL source, and emitted verbatim. This only works when targeting OpenGL or GLSL platforms. You should also note that while automatically translated shaders follow HLSL data layout on buffers, manually written GLSL shaders follow GLSL layout rules.

Variants and keywords

You can use keywords to produce multiple variants of compute shaders, the same as you can for graphics shaders.

For general information on variants, see Shader variants
. For information on how to implement these features in compute shaders, see Declaring and using shader keywords in HLSL and the ComputeShader API documentation.

//

///

///

GraphicsBuffer

Description

GPU graphics data buffer, for working with geometry or compute shader data.

ComputeShader programs often need to read or write arbitrary data from or to memory buffers, and some rendering algorithms need a lower level access or control over geometry data than what is provided by the Mesh class. You can use GraphicsBuffer for these cases. You create the buffers from C# scripts, and then fill them with data using either C# scripts or compute shader programs.

A graphics buffer is similar to an array in C#, in that it has a number of elements (count) of the same size (stride). You must supply the intended buffer usage (target) when you create a GraphicsBuffer; for example, you must pass GraphicsBuffer.Target.Index for the buffer to be usable as a geometry index buffer.

When you have finished working with the buffer, you must manually release the GPU memory should be released. You can do this using C# dispose pattern, or by calling Release.

See Also: Graphics.DrawProceduralGraphics.CopyBufferComputeShaderShader.SetGlobalBufferMaterial.SetBuffer.

Properties

countNumber of elements in the buffer (Read Only).
nameThe debug label for the graphics buffer (setter only).
strideSize of one element in the buffer (Read Only).
targetUsage target, which specifies the intended usage of this GraphicsBuffer (Read Only).

Constructors

GraphicsBufferCreate a Graphics Buffer.

Public Methods

GetDataRead data values from the buffer into an array. The array can only use blittable types.
GetNativeBufferPtrRetrieve a native (underlying graphics API) pointer to the buffer.
IsValidReturns true if this graphics buffer is valid, or false otherwise.
ReleaseRelease a Graphics Buffer.
SetCounterValueSets counter value of append/consume buffer.
SetDataSet the buffer with values from an array.

Static Methods

CopyCountCopy the counter value of a GraphicsBuffer into another buffer.

/

Unity - Scripting API: GraphicsBuffer

///

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值