2025년 1월 9일 목요일

불 쉐이더

 이펙트 구현하기 위해 돌아다니다가

간단한 불 이펙트를 설명하는 사이트를 찾아서

참고하여 HLSL로 불 느낌나게 만듦


https://realtimevfx.com/t/simple-fire-shader-breakdown/11213




사용하는 텍스처가 딱 한개라 아주 좋아용



원리는 두 텍스처를 서로 교차되는 방향으로 이동시켜 

교차되는 부분을 알파 테스트로 통과하여 불 색을 입히고

발광 수치랑 기타 등등 을 적용하는 내용인데


불 느낌만 내면 상관없기에

불 필요한 계산은 제외하고 내 맘대로 했음  


Texture2D fireTexture : register(t0);
Texture2D noiseTexture : register(t1);
Texture2D alphaTexture : register(t2);
SamplerState SampleTypeWrap : register(s0);

cbuffer NoiseBuffer : register(b0)
{
    float3 padding;
	float frameTime;
}

struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD;
};

float4 main(PixelInputType input) : SV_TARGET
{
    float4 finalColor;
    float noiseColor;
    float noiseColor2;
    float finalNoise;
    float2 noiseCoord;
    float2 noiseCoord2;


    noiseCoord = input.tex;
    noiseCoord.xy *= float2(0.8f, 0.7f);
    noiseCoord.xy += float2(0.1f, 0.5f) * frameTime;

    noiseCoord2 = input.tex;
    noiseCoord2.xy *= float2(1.0f, 0.5f);
    noiseCoord2.xy += float2(-0.2f, 0.3f) * frameTime;

    noiseColor = noiseTexture.Sample(SampleTypeWrap, noiseCoord).r;
    noiseColor2 = noiseTexture.Sample(SampleTypeWrap, noiseCoord2).r;

    finalNoise = noiseColor * noiseColor2;
    //finalNoise = saturate(finalNoise);

    finalColor = fireTexture.Sample(SampleTypeWrap, finalNoise);

    finalColor.a = finalNoise + input.tex.y - 0.3f;

    return finalColor;
}


시간 계수만 받아와 노이즈 텍스처 두개 각각 좌표를 타일링 하고,

속도만큼 이동시켜 샘플링, 어차피 rgb 셋다 동일한 값을 갖는

텍스처라 빨강 값만 가져와 사용,



불 색상은 그라데이션으로 적용하기 위해

노이즈 값을 uv좌표로 활용,

색이 진할 수록 노랑값을 갖고

연할 수록 빨강 값을 갖도록 하였음

알파 테스트는 건너뜀




다만 이거는 빌보드나 X 모양으로 겹쳐서 그려야

그나마 이펙트 기능을 할듯한데 파티클 없이 단독으로 불 효과를 내는건

의미 없어 보임.



c++ thread.h

 c++에서 쓰레드 돌릴려면 thread.h 헤더를 쓰면 되는데 이 친구는 쓰레드가 아직 실행 중인지, 아니면 강제 종료하거나 하는 함수가 없어서 조금 아쉬운 애다. std::thread 는 로컬 변수로 선언하든 new 동적 할당을 하든 start 함...