본문 바로가기
개발/Unity) Shader

Unity Shader) 다이아몬드 형태로 프리즘 효과 처리하기

by 테샤르 2024. 12. 8.

다이아몬드 형태로 프리즘 효과 처리하기

 

포켓몬 카드 같은것의 배경같은경우에 다음과 같이 다이아몬드 형태로 타일링되어있는걸 표현해본 쉐이더 코드이다.

 

반응형
반응형

 

< Material 속성 >

다이아몬드 형태의 타일링을 할수 있는 형태로 만들고 해당 타일에 대칭되는 컬러값들을 셋팅하게 했다. 

 

여러가지 효과에 대응되기 위해서 타일 사이즈와 타일의 투명값들을 셋팅하게 했다.


< Shader Code >

Shader"Custom/DiamondTilingShader"
{
    Properties
    {
        _MainTex ("Base Texture", 2D) = "white" { }
        _HexSize ("Tile Size", Float) = 1.0
        _TileAlpha ("Tile Alpha", Range(0, 1)) = 1.0  // Tile transparency (0 to 1 range)
        _ColorTransitionSpeed ("Color Transition Speed", Range(0, 10)) = 1.0  // 색상 전환 속도 (0~10)

        // 6 Prism Colors
        _PrismColor1 ("Prism Color 1", Color) = (1, 0, 0, 1)  // Red
        _PrismColor2 ("Prism Color 2", Color) = (0, 1, 0, 1)  // Green
        _PrismColor3 ("Prism Color 3", Color) = (0, 0, 1, 1)  // Blue
        _PrismColor4 ("Prism Color 4", Color) = (1, 1, 0, 1)  // Yellow
        _PrismColor5 ("Prism Color 5", Color) = (1, 0, 1, 1)  // Magenta
        _PrismColor6 ("Prism Color 6", Color) = (0, 1, 1, 1)  // Cyan
    }
    SubShader
    {
        Tags { "Queue" = "Overlay" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
#include "UnityCG.cginc"

struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
};

struct v2f
{
    float4 pos : POSITION;
    float2 uv : TEXCOORD0;
};

            // Tile and Prism effect related variables
float _HexSize;
float _TileAlpha;
float _ColorTransitionSpeed;

            // 6 Prism Colors
float4 _PrismColor1;
float4 _PrismColor2;
float4 _PrismColor3;
float4 _PrismColor4;
float4 _PrismColor5;
float4 _PrismColor6;

            // Main texture
sampler2D _MainTex;
float4 _MainTex_ST;

            // Random value generation function
float Rand(float2 position)
{
    return frac(sin(dot(position, float2(12.9898, 78.233))) * 43758.5453);
}

            // Vertex shader
v2f vert(appdata v)
{
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    o.uv = v.uv;
    return o;
}

            // Fragment shader
half4 frag(v2f i) : SV_Target
{
                // Calculate UV coordinates
    float2 uv = i.uv;

                // Sample the color from the main texture
    float4 texColor = tex2D(_MainTex, uv);

                // Discard pixels with low alpha
    if (texColor.a < 0.1)
    {
        discard;
    }

                // Transform UV coordinates to tile size
    uv = uv * 2.0 - 1.0;
    uv.x *= _HexSize;
    uv.y *= _HexSize;

                // Apply 45-degree rotation
    float cos45 = 0.70710678118; // cos(45°)
    float sin45 = 0.70710678118; // sin(45°)
    float tempX = uv.x;
    uv.x = cos45 * (uv.x - uv.y);
    uv.y = sin45 * (tempX + uv.y);

                // Draw rhombus tiles
    float2 hexPos = floor(uv);
    float2 fracPos = frac(uv);

                // Check for the boundary of the rhombus
    float dist = length(fracPos - 0.5);
    float hexEdge = step(0.5, dist);
    float edgeThreshold = 0.577; // cos(30°) = 0.577
    bool insideHex = (fracPos.x > 0.5 - edgeThreshold && fracPos.x < 0.5 + edgeThreshold) &&
                                 (fracPos.y > 0.5 - edgeThreshold && fracPos.y < 0.5 + edgeThreshold);

                // Randomize the color based on hex position and random factor
    float randVal = Rand(hexPos);

                // Calculate color index and transition value
    int rowColorIndex = int(abs(fmod(hexPos.y + randVal * 3.0, 6.0))); // Ensure positive result
                
                // Smooth transition with easing, and limit to a range between 0 and 1
    float t = 0.5 + 0.5 * sin(randVal * _ColorTransitionSpeed + 1.57); // Use sine wave for smooth transition

                // Choose colors based on the index, and smoothly transition between them
    float4 colorA, colorB;
    if (rowColorIndex == 0)
    {
        colorA = _PrismColor1;
        colorB = _PrismColor2;
    }
    else if (rowColorIndex == 1)
    {
        colorA = _PrismColor2;
        colorB = _PrismColor3;
    }
    else if (rowColorIndex == 2)
    {
        colorA = _PrismColor3;
        colorB = _PrismColor4;
    }
    else if (rowColorIndex == 3)
    {
        colorA = _PrismColor4;
        colorB = _PrismColor5;
    }
    else if (rowColorIndex == 4)
    {
        colorA = _PrismColor5;
        colorB = _PrismColor6;
    }
    else
    {
        colorA = _PrismColor6;
        colorB = _PrismColor1;
    }

                // Smoothly interpolate between colorA and colorB
    float4 prismColor = lerp(colorA, colorB, t);

                // If TileAlpha is 0, show Main Texture without any color overlay
    if (_TileAlpha <= 0.0)
    {
        return texColor; // Return only the Main Texture color, no alpha effect
    }

                // Alpha blending
    float finalAlpha = texColor.a * (1.0 - _TileAlpha) + _TileAlpha;
    float3 finalColor = (texColor.rgb * (1.0 - _TileAlpha)) + (prismColor.rgb * _TileAlpha);

                // Apply tile color if inside the hexagon
    if (insideHex)
    {
        return half4(finalColor, finalAlpha);
    }

                // Outside hexagon, return the texture color
    return texColor;
}
            ENDCG
        }
    }
FallBack"Diffuse"
}

 

★★★☆☆

 

반응형

댓글