낑깡의 게임 프로그래밍 도전기

Unity C# Material Rendering Mode 스크립트로 제어하기 런타임에서 변경 본문

Unity C#

Unity C# Material Rendering Mode 스크립트로 제어하기 런타임에서 변경

낑깡겜플밍 2024. 10. 15. 16:49
반응형

유니티를 활용하다 보니 오브젝트가 Opaque일때와 Transparent일때 색감이 다를 때가 있었다.
*오브젝트가 속이 보이는 에러 같은 현상이 발생하거나 Plan의 색감이 달랐음

그러다보니 평소에는 Opaque로 쓰다가 필요할 때만 Transparent를 쓰고 싶어서 구형 해보려고한다
(물론 더 좋은 방법도 있겠지만 오늘은 이 방법으로! 더 좋은 방법을 아시는분 댓글 달아주시면 감사하겠습니다.)

렌더링 모드의 의미
*렌더링 모드는 기본적으로 Unity에서 객체가 렌더링되는 방식


Opaque (불투명) : 오브젝트가 완전히 불투명하게 렌더링. 투명도는 무시되고, Z-Buffer에 쓰여진 순서대로 그려진다.

Cutout (컷아웃) : 불투명하지만 알파 채널에 따라 픽셀을 잘라내는 방식으로 렌더링된다. 주로 투명한 텍스처를 사용할 때, 픽셀을 "자르기" 위해 사용.
*써본결과 일정 알파값이 내려가면 뿅하고 사라지는 느낌이었다.

Fade (페이드) : 알파 블렌딩을 통해 점차적으로 투명해진다. 물체가 사라지는 효과나 반투명한 표면에 적합. 
* Transparent 와 비슷한 느낌이었다.

Transparent (투명) : 완전히 투명한 객체를 렌더링할 때 사용합니다. 반사와 빛에 반응하는 물체 등 다양한 효과에서 사용

 

renderQueue( Unity에서 렌더링 순서를 제어하는 중요한 속성)
여러 객체가 화면에 렌더링될 때, 어떤 객체가 먼저 그려지고 나중에 그려질지를 결정하는 것.
일반적으로 불투명한 객체는 앞에서부터 그려지며, 투명한 객체는 뒤에서 그려진다. 이 순서를 설정함으로써 투명한 객체가 올바르게 겹쳐 보이도록 할 수 있다.

renderQueue 속성은 머티리얼에 설정되어 있고, 숫자가 낮을수록 먼저 그려지고, 숫자가 높을수록 나중에 그려진다. 이를 통해 그 객체가 어느 시점에 렌더링되는지 결정된다.

기본적인 렌더 큐 값
불투명(Opaque): renderQueue = 2000
불투명한 객체는 Z-버퍼에 의해 깊이 테스트가 이루어지므로 먼저 그려짐.

알파 테스트(Cutout): renderQueue = 2450
알파 컷아웃(잘라내기) 방식으로 렌더링되는 객체는 불투명 객체보다 나중에 그려지지만, 깊이테스트?를 수행한다함.

투명(Fade, Transparent): renderQueue = 3000
투명한 객체는 나중에 그려지므로, 뒤에 그려진 객체가 먼저 보이고 앞의 투명한 객체가 그 뒤를 덮는 것임.

 

상황1 : 단일 머터리얼 렌더링 모드 변경 시

public class Test : MonoBehaviour
{
    public Material material;
    public enum RenderingMode
    {
        Opaque,
        Cutout,
        Fade,
        Transparent
    }
    void Start()
    {
        // 머티리얼의 렌더링 순서를 투명 모드로 설정
        SetRenderingMode(material, RenderingMode.Transparent);
        material.renderQueue = 3100; // 기본 투명 큐 값인 3000보다 나중에 렌더링되도록 설정
    }

    public void SetRenderingMode(Material material, RenderingMode mode)
    {
        switch (mode)
        {
            case RenderingMode.Opaque:
                material.SetFloat("_Mode", 0.0f);
                material.SetOverrideTag("RenderType", "Opaque");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.DisableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 2000;
                break;

            case RenderingMode.Cutout:
                material.SetFloat("_Mode", 1.0f);
                material.SetOverrideTag("RenderType", "Cutout");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.EnableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 2450;
                break;

            case RenderingMode.Fade:
                material.SetFloat("_Mode", 2.0f);
                material.SetOverrideTag("RenderType", "Fade");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.SetInt("_ZWrite", 0);
                material.DisableKeyword("_ALPHATEST_ON");
                material.EnableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
                break;

            case RenderingMode.Transparent:
                material.SetFloat("_Mode", 3.0f);
                material.SetOverrideTag("RenderType", "Transparent");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.SetInt("_ZWrite", 0);
                material.DisableKeyword("_ALPHATEST_ON");
                material.EnableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
                break;
        }

    }
}
반응형

상황2 : 다수의 머터리얼 렌더링 모드 변경 시

public class ChangeRenderingMode : MonoBehaviour
{
    public Material[] materials;  // 인스펙터에서 할당한 30개의 머티리얼
    private Material[] copiedMaterials;  // 복사된 머티리얼을 저장할 배열

    public float startTime;
    float currentTime;

    public enum RenderingMode
    {
        Opaque,
        Cutout,
        Fade,
        Transparent
    }

    void Start()
    {
        // 30개의 머티리얼을 순차적으로 설정
        for (int i = 0; i < materials.Length; i++)
        {
            // 렌더링 모드를 Transparent로 설정
            SetRenderingMode(materials[i], RenderingMode.Opaque);
        }
    }

    public void SetRenderingMode(Material material, RenderingMode mode)
    {
        switch (mode)
        {
            case RenderingMode.Opaque:
                material.SetFloat("_Mode", 0.0f);
                material.SetOverrideTag("RenderType", "Opaque");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.DisableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 2000;
                break;

            case RenderingMode.Cutout:
                material.SetFloat("_Mode", 1.0f);
                material.SetOverrideTag("RenderType", "Cutout");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.EnableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 2450;
                break;

            case RenderingMode.Fade:
                material.SetFloat("_Mode", 2.0f);
                material.SetOverrideTag("RenderType", "Fade");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.SetInt("_ZWrite", 0);
                material.DisableKeyword("_ALPHATEST_ON");
                material.EnableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
                break;

            case RenderingMode.Transparent:
                material.SetFloat("_Mode", 3.0f);
                material.SetOverrideTag("RenderType", "Transparent");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.SetInt("_ZWrite", 0);
                material.DisableKeyword("_ALPHATEST_ON");
                material.EnableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
                break;
        }

    }
}

 

반응형