250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- TDableton
- TouchDesigner
- 터치디자이너 python
- 터치디자이너 replicator
- touchdesigner GPU
- 터치디자이너 Instancing
- 터치디자이너 timeline
- 터치디자이너 에이블톤
- 터치디자이너 참조
- touchdesinger
- 터치디자이너 강의
- 터치디자이너 오퍼레이터
- 터치디자이너 인터페이스
- touchdesigner displace
- 파이썬reference
- 터치디자이너 클론
- 터치디자이너
- touchdesigner particle
- 터치디자이너 reference
- 터치디자이너 파이썬
- displace
- 터치디자이너 list
- 터치디자이너 if
- 파이썬 if
- particleGPU
- ableton live 10
- 터치디자이너 interface
- 터치디자이너 튜토리얼
- 터치디자이너 함수
- 파이썬
Archives
- Today
- Total
caLAB
[Compute Shader 02] 버퍼의 사용 본문
728x90
오늘은 C# 스크립트와 compute shader 사이에 데이터를 주고 받는 것을 배웠다.
C# 스크립트에서 buffer에 데이터를 배열로 저장하고, 이를 compute shader에 전달해서 compute shader에서 연산해서 그리는게 기본적인 구조이다.
C# 코드
using UnityEngine;
using System.Collections;
public class BufferJoy : MonoBehaviour
{
public ComputeShader shader;
public int texResolution = 1024;
Renderer rend;
RenderTexture outputTexture;
int circlesHandle;
int clearHandle;
public Color clearColor = new Color();
public Color circleColor = new Color();
struct Circle
{
public Vector2 origin;
public Vector2 velocity;
public float radius;
}
int count = 10;
Circle[] circleData; //circle 정보
ComputeBuffer buffer; //comptebuffer 선언
void Start()
{
outputTexture = new RenderTexture(texResolution, texResolution, 0);
outputTexture.enableRandomWrite = true;
outputTexture.Create();
rend = GetComponent<Renderer>();
rend.enabled = true;
InitData();
InitShader();
}
private void InitData()
{
circlesHandle = shader.FindKernel("Circles");
uint threadGroupSizeX; //스레드 그룹 사이즈
shader.GetKernelThreadGroupSizes(circlesHandle, out threadGroupSizeX, out _, out _);
int total = (int)threadGroupSizeX * count;
circleData = new Circle[total]; //circleData 사이즈 지정
float speed = 100;
float halfSpeed = speed * 0.5f;
float minRadius = 10.0f;
float maxRadius = 30.0f;
float radiusRange = maxRadius - minRadius;
//circle data 계산
for(int i=0; i<total; i++)
{
Circle circle = circleData[i];
circle.origin.x = Random.value * texResolution;
circle.origin.y = Random.value * texResolution;
circle.velocity.x = (Random.value * speed) - halfSpeed;
circle.velocity.y = (Random.value * speed) - halfSpeed;
circle.radius = Random.value * radiusRange + minRadius;
circleData[i] = circle;
}
}
private void InitShader()
{
clearHandle = shader.FindKernel("Clear");
shader.SetVector( "clearColor", clearColor );
shader.SetVector( "circleColor", circleColor );
shader.SetInt( "texResolution", texResolution );
int stride = (2 + 2 + 1) * 4; //circle 구조체 정보의 크기 float2 + float2 + float * float의 크기(4바이트)
buffer = new ComputeBuffer(circleData.Length, stride);
buffer.SetData(circleData);
shader.SetBuffer(circlesHandle, "circlesBuffer", buffer);
shader.SetTexture( circlesHandle, "Result", outputTexture );
shader.SetTexture( clearHandle, "Result", outputTexture );
rend.material.SetTexture("_MainTex", outputTexture);
}
private void DispatchKernel(int count)
{
shader.Dispatch(clearHandle, texResolution/8, texResolution/8, 1);
shader.SetFloat("time", Time.time);
shader.Dispatch(circlesHandle, count, 1, 1);
}
void Update()
{
DispatchKernel(10);
}
private void OnDestroy()
{
buffer.Dispose();
}
}
compute shader 코드
#pragma kernel Circles
#pragma kernel Clear
shared RWTexture2D<float4> Result;
//circle 구조체 선언
struct circle
{
float2 origin;
float2 velocity;
float radius;
};
//circleBuffer 생성
StructuredBuffer<circle> circlesBuffer;
float4 clearColor;
float4 circleColor;
int texResolution;
int clearScreen = 0;
float time;
//연산 함수
float random(float value, float seed = 0.546){
float random = (frac(sin(value + seed) * 143758.5453));
return random;
}
float2 random2(float value){
return float2(
random(value, 3.9812),
random(value, 7.1536)
);
}
void plot1( int x, int y, int2 centre){
Result[uint2(centre.x + x, centre.y + y)] = circleColor;
}
void plot8( int x, int y, int2 centre ) {
plot1( x, y, centre ); plot1( y, x, centre );
plot1( x, -y, centre ); plot1( y, -x, centre );
plot1( -x, -y, centre ); plot1( -y, -x, centre );
plot1( -x, y, centre ); plot1( -y, x, centre );
}
void drawCircle( int2 centre, int radius){
int x = 0;
int y = radius;
int d = 1 - radius;
while (x < y){
if (d < 0){
d += 2 * x + 3;
}else{
d += 2 * (x - y) + 5;
y--;
}
plot8(x, y, centre);
x++;
}
}
//circle 생성 함수
[numthreads(32,1,1)]
void Circles (uint3 id : SV_DispatchThreadID)
{
int2 centre = (int2)(circlesBuffer[id.x].origin + circlesBuffer[id.x].velocity * time);
while (centre.x>texResolution) centre.x -= texResolution;
while (centre.x<0) centre.x += texResolution;
while (centre.y>texResolution) centre.y -= texResolution;
while (centre.y<0) centre.y += texResolution;
uint radius = (int)circlesBuffer[id.x].radius;
drawCircle( centre, radius );
}
//배경
[numthreads(8,8,1)]
void Clear (uint3 id : SV_DispatchThreadID)
{
Result[id.xy] = clearColor;
}
728x90
반응형
'Unity > 유니티 Shader' 카테고리의 다른 글
[유니티 그래픽] 유니티에서 Anti-Aliasing(안티앨리어싱) 설정하기(feat. 계단 현상 방지) (2) | 2021.12.27 |
---|---|
[유니티 hdrp] HDRP 사용시 Material 깨짐 해결 (0) | 2021.11.04 |
[Compute Shader 01] 컴퓨터 쉐이더의 기본 (0) | 2021.07.29 |
Cel Shader (0) | 2020.09.07 |
유니티 Compute Shader 01 (3) | 2020.04.29 |
Comments