본문 바로가기

유니티/쉐이더

[Unity Shader] 비눗방울 쉐이더 만들기

이런 느낌으로 만들어보겠습니다

 

기본코드

Smoothness는 1, Metallic은 0으로 해뒀습니다.

 

Shader "Custom/Bubble"
{
    Properties
    {
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard alpha:fade
        #pragma target 3.0

        half _Glossiness;
        half _Metallic;


        struct Input
        {
            float3 viewDir;
        };


        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            o.Alpha = 1;

            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 


Alpha값 조정

  • 바깥으로 갈수록 밝다.
  • 가운데도 살짝 불투명하다.
void surf (Input IN, inout SurfaceOutputStandard o)
{
    float rim = dot(o.Normal, IN.viewDir);
    o.Alpha = saturate(pow(1 - rim, 1) + 0.1);

    o.Metallic = _Metallic;
    o.Smoothness = _Glossiness;
}

완전 투명한곳이 없으니 0.1을 더해주고 1을 초과할 수 있어서 saturate를 써줬습니다.

 

 


색 조정

worldPos를 시드값으로 알록달록하게 만들어줬습니다.

struct Input
{
    float3 viewDir;
    float3 worldPos;
};


void surf (Input IN, inout SurfaceOutputStandard o)
{
    float3 col = sin(_Time.w + IN.worldPos * 10) * 0.3 + 0.7;
    o.Albedo = col;

    float rim = dot(o.Normal, IN.viewDir);
    o.Alpha = saturate(pow(1 - rim, 1) + 0.1);

    o.Metallic = _Metallic;
    o.Smoothness = _Glossiness;
}

Input 구조체worldPos를 추가해줍니다.

worldPos를 이용해 색을 정해주고 sin함수로 -1~1로 만들어줍니다.

밝게 해주기 위해 계산된 값에 *0.3 + 0.7을 해줘서 0.4 ~ 1값으로 나오게 합니다.


Vertex Shader

꾸물꾸물거리는 느낌을 만들어줍니다.

#pragma surface surf Standard vertex:vert alpha:fade
#pragma target 3.0

float getAddPos(float pos, int offset) {
    float speed = 0.5 + offset * 0.25;
    return sin(pos * 10 + _Time.y * speed) * 0.02;
}

void vert(inout appdata_full v) {
    v.vertex.x += getAddPos(v.vertex.x, 0);
    v.vertex.y += getAddPos(v.vertex.y, 1);
    v.vertex.z += getAddPos(v.vertex.z, 2);
}

offset을 줘서 방향마다 조금 다르게 움직이게 해줬습니다.

 

완성!

 


전체코드

Shader "Custom/Bubble"
{
    Properties
    {
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard vertex:vert alpha:fade
        #pragma target 3.0

        float getAddPos(float pos, int offset) {
            float speed = 0.5 + offset * 0.25;
            return sin(pos * 10 + _Time.y * speed) * 0.02;
        }

        void vert(inout appdata_full v) {
            v.vertex.x += getAddPos(v.vertex.x, 0);
            v.vertex.y += getAddPos(v.vertex.y, 1);
            v.vertex.z += getAddPos(v.vertex.z, 2);
        }

        struct Input
        {
            float3 viewDir;
            float3 worldPos;
        };

        half _Glossiness;
        half _Metallic;

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            float3 col = sin(_Time.w + IN.worldPos * 10) * 0.3 + 0.7;
            o.Albedo = col;

            float rim = dot(o.Normal, IN.viewDir);
            o.Alpha = saturate(pow(1 - rim, 1) + 0.1);

            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
        }

        ENDCG
    }
    FallBack "Diffuse"
}