Bacher 사용해보기 |
일괄 처리는 Draw Call을 결합하여 CPU와 GPU간의 통신에 소요되는 시간을 줄이는 프로세스입니다.
드로우콜의 양을 줄이고 GPU에 있는 머테리얼 속성을 캐싱하므로 모든 그리기 호출을 보낼 필요가 없습니다.
이를 적용하려면 SRP일괄 처리기를 활성화하면 되지만 호환되는 쉐이더에서만 작동하므로 셰이더가 균일한 데이터에 대해 엄격한 구조를 고수하는 경우에만 작동합니다.
모든 재질 속성은 적역이 아닌 메모리 버퍼 내부에 정의되어야 합니다.
정의하는 방법은 아래와 같습니다.
cbuffer UnityPerMaterial {
float _BaseColor;
};
모든 플렛폼에서 상수 버퍼가 지원되는 것이 아니므로 매크로를 사용하여 호환성을 높입니다.
CBUFFER_START(UnityPerMaterial)
float4 _BaseColor;
CBUFFER_END
※ 매크로는 Core RP Library를 통해 확인할 수 있습니다.
Unity_ObjectToWorld, unity_WorldToObject 및 unity_WorldTransformParams에 대해서도 이 작업을 수행해야 하고..
변환그룹의 unity_LODFade를 사용하지 않더라도 집어 넣습니다.
CBUFFER_START(UnityPerDraw)
float4x4 unity_ObjectToWorld;
float4x4 unity_WorldToObject;
float4 unity_LODFade;
real4 unity_WorldTransformParams;
CBUFFER_END
아래와 같이 되면 배처를 사용할 수 있는 셰이더 입니다.
마지막으로 CustomRenderPipeline에서 배처를 사용하겠다고 선언하면 끝!
public CustomRenderPipeline () {
GraphicsSettings.useScriptableRenderPipelineBatching = true;
}
배처가 성공하더라도 단 하나의 드로우 콜이 아니라 최적화된 시퀀스라는 것을 잊지 말아야 합니다.
Shader "StudySRP/Catlike1"
{
Properties{
_BaseColor("Color", Color) = (1.0, 1.0, 1.0, 1.0)
}
SubShader{
Pass {
HLSLPROGRAM
#include "Catlike1Pass.hlsl"
#include "UnityInput.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#define UNITY_MATRIX_M unity_ObjectToWorld
#define UNITY_MATRIX_I_M unity_WorldToObject
#define UNITY_MATRIX_V unity_MatrixV
#define UNITY_MATRIX_VP unity_MatrixVP
#define UNITY_MATRIX_P glstate_matrix_projection
#ifndef CUSTOM_UNITY_INPUT_INCLUDED
#define CUSTOM_UNITY_INPUT_INCLUDED
CBUFFER_START(UnityPerDraw)
float4x4 unity_ObjectToWorld;
float4x4 unity_WorldToObject;
float4 unity_LODFade;
real4 unity_WorldTransformParams;
CBUFFER_END
float4x4 unity_MatrixVP;
float4x4 unity_MatrixV;
float4x4 glstate_matrix_projection;
#endif
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl"
#pragma vertex vert
#pragma fragment frag
#ifndef CUSTOM_UNLIT_PASS_INCLUDED
#define CUSTOM_UNLIT_PASS_INCLUDED
#endif
CBUFFER_START(UnityPerMaterial)
float4 _BaseColor;
CBUFFER_END
float4 vert(float3 positionOS : POSITION) : SV_POSITION {
float3 positionWS = TransformObjectToWorld(positionOS.xyz);
return TransformWorldToHClip(positionWS);
}
float4 frag() : SV_TARGET{
return _BaseColor;
}
ENDHLSL
}
}
}
bacher에 색상 지정하기 |
instace형식으로 지원하지는 않지만 스크립트로 인스턴스 형식으로 사용할 수 있다고합니다.
씬이 로드되거나 컴포넌트를 편집할 때 호출되는 onValde를 사용하여 지정할 수 있습니다.
using UnityEngine;
[DisallowMultipleComponent]
public class InstanceColorScript : MonoBehaviour
{
static int baseColorId = Shader.PropertyToID("_BaseColor");
static MaterialPropertyBlock block;
[SerializeField] Color baseColor;
void Awake() {
OnValidate();
}
void OnValidate() {
if (block == null) {
block = new MaterialPropertyBlock();
}
block.SetColor(baseColorId, baseColor);
GetComponent<Renderer>().SetPropertyBlock(block);
}
}
참조 : 링크