GPU ThreadGroups 할당 연습


.compute


// Each #kernel tells which function to compile; you can have many kernels #pragma kernel CSMain #pragma kernel ScreenCalc struct Offset { float3 position; float3 rotation; }; RWStructuredBuffer<Offset> offsetBuffer; RWTexture2D<float4> Result; float time; float updateSpeed; float rowSize; float waveFrequency; [numthreads(8,1,1)] void CSMain (uint3 id : SV_DispatchThreadID) { float t = time * updateSpeed; float3 pos = offsetBuffer[id.x].position; float3 rot = offsetBuffer[id.x].rotation; pos.x = sin(t); rot.x = cos(t); offsetBuffer[id.x].position = pos; offsetBuffer[id.x].rotation = rot; // TODO: insert actual code here! //Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0); } [numthreads(8,8,1)] void ScreenCalc(uint3 id : SV_DispatchThreadID) { float t = time * updateSpeed; uint width, height; Result.GetDimensions(width, height); float2 uv = id.xy / float2(width, height) + abs(sin(t)*.5); Result[id.xy] = float4(uv, 0, 1); }

.cs

[System.Serializable] private struct Offset { public Vector3 position; public Vector3 rotation; } [SerializeField] private ComputeShader computeShader; [SerializeField] private float updateSpeed = 10f; [SerializeField] private float waveFrequency = 0.5f; [SerializeField] private int size = 10; [Space] [SerializeField] private float rowSize = 32; private ComputeBuffer m_offsetBuffer; [SerializeField]private Offset[] m_offsetDatas; private RenderTexture m_renderTarget; /* private void OnRenderImage(RenderTexture source, RenderTexture destination) { }*/ private void Start() { InitCompute(); } private void Update() { DispatchComputeShader(); GetDataFromComputeShader(); } private void OnRenderImage(RenderTexture source, RenderTexture destination) { Render(destination); } private void Render(RenderTexture destination) { InitRenderTexture(); computeShader.SetTexture(1, "Result", m_renderTarget); int threadGroupsX = Mathf.CeilToInt(Screen.width / 8.0f); int threadGroupsY = Mathf.CeilToInt(Screen.height / 8.0f); computeShader.Dispatch(1, threadGroupsX, threadGroupsY, 1); Graphics.Blit(m_renderTarget, destination); } private void InitRenderTexture() { if(m_renderTarget == null || m_renderTarget.width != Screen.width || m_renderTarget.height != Screen.height) { //release from memory if (m_renderTarget != null) m_renderTarget.Release(); m_renderTarget = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); m_renderTarget.enableRandomWrite = true; m_renderTarget.Create(); } } private void InitCompute() { m_offsetDatas = new Offset[size]; // compute buffer instance create m_offsetBuffer = new ComputeBuffer(8*1*1, sizeof(int)); m_offsetBuffer.SetData(m_offsetDatas); computeShader.SetBuffer(0, "offsetBuffer", m_offsetBuffer); } private void DispatchComputeShader() { computeShader.SetFloat("time", Time.time); computeShader.SetFloat("updateSpeed", updateSpeed); computeShader.SetFloat("rowSize", rowSize); computeShader.SetFloat("waveFrequency", waveFrequency); /* // thread group calc computeShader.GetKernelThreadGroupSizes(0, out uint numX, out _, out _); int numThreadGroups = Mathf.CeilToInt(m_offsetDatas.Length / numX);*/ // dispatch computeShader.Dispatch(0, 8, 8, 1); } private void GetDataFromComputeShader() { m_offsetBuffer.GetData(m_offsetDatas); for(int i =0; i<m_offsetDatas.Length; i++) { Debug.Log(m_offsetDatas[i].position); Debug.Log(m_offsetDatas[i].rotation); } }








댓글

이 블로그의 인기 게시물

About AActor!!! "UObject" has no member "BeginPlay"

UNREAL Android build information

C++ 생성자 위임 (delegating constructor)