Constant Buffers
https://catlikecoding.com/unity/tutorials/scriptable-render-pipeline/custom-shaders/
https://docs.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-constants?redirectedfrom=MSDN
https://zhuanlan.zhihu.com/p/35830868
摘自上面的网址。
常量buffer
unity does not provide us with a model-view-projection matrix, because that way a matrix multiplication of the M and VP matrices can be avoided.
besides that, the VP matric can be reused for everything that gets drawn with the same camera during a frame.
同一个相机的,VP矩阵是不变的,可反复使用的。
unity’s shaders takes advantage of that fact adn put the matrices in different constant buffers. unity把这些不变的矩阵,放在一个常量buffer中。
although we define them as variable, their data remains constant during the drawing of a single shape, and often longer than that.
the VP matric gets put in a per-frame buffer, while the M matrix gets put in a per-draw buffer.
这里的per-frame buffer——每帧buffer
per-draw buffer——每次绘制buffer
后者粒度更小,每帧可以画多次,你可以这么理解。
while it is not strictly required to put shader variables in constant buffers, doing so makes it possible for all data in the same buffer to be changed more efficiently. at least, that is the case when it is supported by the graphics API. opengl does not.
没有强制说要把shader的变量放在常量buffer中,但是近来将所有的数据放在同一个buffer中,这样效率会更高。
to be as efficient as possible, we will also make use of constant buffers. unity puts the VP matrix in a UnityPerFrame buffer and the M matrix in a UnityPerDraw buffer.
为了效率的更高,我们将充分利用常量buffer,将VP矩阵放在UnityPerFrame buffer中,而M矩阵放在UnityPerDraw buffer中。
a constant buffer is defined like a struct, except with the cbuffer keyword and the variables remain accessible as before.
写法如下:
cbuffer UnityPerFrame
{
float4x4 unity_MatrixVP;
};
cbuffer UnityPerDraw
{
float4x4 unity_ObjectToWorld;
}
兼容性:
because constant buffers do not benefit all platforms, unity’s shaders rely on macros to only use them when needed.
并不是所有的平台都支持常量buffer,所以unity使用宏来做兼容。
the CBUFFER_START macro with a name parameter is used instead of directly writing cbuffer and accompanying CBUFFER_END macro replaces the end of the buffer.
写法如下:
CBUFFER_START(UnityPerFrame)
float4x4 unity_MatrixVP;
CBUFFER_END
CBUFFER_START(UnityPerDraw)
float4x4 unity_ObjectToWorld;
CBUFFER_END
当然,是这个宏,要进行文件的包含:
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
如何引入这个文件:
参考这段话:
we'll make use of Unity's core library for render pipelines. It can be added to our project via the package manager window. Switch to the All Packages list and enable Show preview packages under Advanced, then select Render-pipelines.core, and install it. I'm using version 4.6.0-preview, the highest version that works in Unity 2018.3.
这个在:D:\Program Files\Unity2018.3.0f2\Unity\Editor\Data\Resources\PackageManager\Editor\package\ShaderLibrary\API\D3D11.hlsl
中有这样类似的定义:
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
这样就完全对应起来喽。。。
cbuffer myObject
{
float4x4 matWorld;
float3 vObjectPosition;
int arrayIndex;
}
cbuffer myScene
{
float3 vSunPosition;
float4x4 matView;
}