본문 바로가기
Shader CG

2.1 Noise TV 화면 만들어보기

by SimonLee 2023. 8. 6.

Noise effect를 구현해 봅시다.

Noise effect는 Randomness과 확률이 관련 된다.

각 픽셀이 랜덤으로 표시 하되, 특정 패턴이 생기지 않도록 해야 한다.

각 픽셀 마다 픽셀을 나타낼지 말지를 결정하는 확률을 구하는 것으로 보면 된다.

 

 

확률을 구하기 위한 특정 상수가 들어간다

이  값은 Noise를 만드는 여러 예제 소스에서 해당 값을 사용하고 있다.

a = 12.9898

b = 78.233

c = 43758.543123

 

그리고 dot 함수가 등장하는데, 내적이라고 한다.

dot(a, b)면, a b의 각 원소를 쌍쌍히 곱하고 더해서 스칼라 값을 만든다.

예를 들어 a,b가 2차원 벡터라고 하면 다음과 같습니다.

a = vec2(a1, b1)

b = vec2(c1, d1)

dot(a, b) = (a1 * c1) + (b1 * d1)

이러한 내적함수는 몇 차원이든 해당 값들을 잘 반영한 스칼라 값으로 만들어 주기 때문에, 여기서도 사용된다.

 

 

다음은 Random 확률을 구하는 함수의 구현부 입니다.

float random(float2 pt) 
{
    const float a = 12.9898;
    const float b = 78.233;
    const float c = 43758.543123;
    return frac(sin(dot(pt, float2(a, b))) * c);
}

pt 값은 uv 이고, 범위는 0 ~ 1 입니다.

pt 값과 상수 값을 dot 연산을 통하여 스칼라 값을 만들어주고, sin 함수를 통해 -1 ~ 1 값의 볌위가 리턴된다.

그리고 c값을 곱해서 큰 수를 만들고,  frac함수를 통해 분위수 (소수점 부분)만 가져옵니다.

 

frac함수는 항상 소수를 리턴을 합니다.

값이 음수 (-3.4) 일 경우, -4 + 0.6으로 처리됩니다. (정수 부분이 floor 값)

그래서 항상 0 ~ 1 양수의 값을 리턴을 하게 됩니다.

 

해당 값에 색상을 곱하여 표시를 해보면 다음과 같습니다.

Noise effect

테스트를 해보면 C값에 따라 랜덤으로 되기도 하고 안되기도 한다.

C값이 작아질수록 줄무늬 패턴이 넓어지고,

C값이 커지면 점점 줄무늬 패턴이 좁아진다. 

값들을 곱하는 순서도 바꾸어 보고 값도 바꿔가면서 noise가 어떻게 나오는지 

체크를 해봅시다.

 

Tv 화면에 방송이 없는 채널에 나오는 noise effect를 만들기 위해서

랜덤 함수 값을 seed 값을 주어서 계속 변화시켜 봅시다.

float random(float2 pt, float seed) 
{
    const float a = 12.9898;
    const float b = 78.233;
    const float c = 543758.543123;
    return frac(sin(dot(pt, float2(a, b)) * seed) * c);
}

sin의 결과 값에 seed ( _Time.y ) 값을 곱해 줘서 값을 변화 시키되,  -1 ~ 1 범위를 유지시켜준다.

 

Noise

Shader "SimonLee/Shader27Unlit"
{
    Properties
    {
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #define PI 3.14159265359
            #define PI2 6.28318530718


            #include "UnityCG.cginc"

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 screenPos: TEXCOORD2;
                float4 position: TEXCOORD1;
                float2 uv: TEXCOORD0;
            };

            v2f vert(appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.screenPos = ComputeScreenPos(o.vertex);
                o.position = v.vertex;
                o.uv = v.texcoord;
                return o;
            }

            float random(float2 pt) {
                const float a = 12.9898;
                const float b = 78.233;
                const float c = 43758.543123;
                return frac(sin(dot(pt, float2(a, b))) * c);
            }

            float random(float2 pt, float seed) {
                const float a = 12.9898;
                const float b = 78.233;
                const float c = 543758.543123;
                return frac(sin(dot(pt, float2(a, b)) * seed) * c);
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 color = random(i.uv, _Time.y) * fixed3(1,1,1);

                return fixed4(color, 1.0);
            }
            ENDCG
        }
    }
}

'Shader CG' 카테고리의 다른 글

2.3 Noise 미로 만들기  (0) 2023.08.11
2.2 Noise 모자이크 효과  (0) 2023.08.09
1.6 도형 - 라인 그려보기  (0) 2023.07.20
1.5 도형 - Draw Circle 심화  (2) 2023.07.18
1.4 도형 - 타일링  (0) 2023.07.13