Unity 에서 Shader 공부 그 6 알파 블렌딩과 스텐실 버퍼

9720 단어 ShaderUnity

알파 블렌딩 정보



알파 블렌딩을 하기 위해서는 Shader에 Bend의 기술이 필요.

우선 알파 블렌딩용 Shader를 써 보았다
Shader "Custom/TestShader2" {
    Properties {
        _Color("Color", Color) = (1,1,1,1)
    }

    SubShader {
        Tags { "Queue" = "Transparent" "RenderType" = "Transparent"}
        ZTest LEqual
        ZWrite On
        Blend SrcAlpha OneMinusSrcAlpha

        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            uniform float4 _Color;

            float4 vert(float4 pos : POSITION) : SV_POSITION {
                return mul(UNITY_MATRIX_MVP,pos);
            }

            float4 frag() : SV_TARGET {
                return _Color;
            }
            ENDCG
        }
    }
}

결과 (앞의 핑크 Cube에 Test2Shader를 붙이고있다)
알파 블렌딩이 제대로 작동했습니다.


알파 블렌딩의 방법은 여러가지 있는 것 같다.
Unity Shader는 다음 줄에서 지정합니다.
        Blend SrcAlpha OneMinusSrcAlpha

Blend 하지 않는 경우는 Blend Off (Blend 지정하지 않으면 디폴트로 Off가 된다)
덧붙여서 Blend Off로 하면 이런 느낌


Blend SrcAlpha OneMinusSrcAlpha에 대해 알아보기

이 근처의 사이트가 참고가 되었다.
h tp : // 스쿠 t. 네 t / p 여과 라민 g / c 샤 rp / 오펜 TK01-09. php
htps //wgld. rg / d / u bgl / w029. HTML

Blend SrcAlpha OneMinusSrcAlpha는 fragmet 처리 후의 색을 결정하는 알파 블렌드의 식에 사용되며,
fragment 처리 후 색상 =
깊이 버퍼에 쓰여진 색상 * SrcAlpha + 지금부터 쓰려는 색상 * OneMinusSrcAlpha
된다는 것.

스텐실 버퍼 정보



여기 참조
htps //wgld. rg / d / u bgl / w038. HTML
ぃ tp // m / ed_m18 / ms / 95 a 7f350d1164486 03b

스텐실 버퍼 => 스텐실 테스트에 사용되는 기준값을 기록하는 버퍼
스텐실 테스트 => 깊이 테스트처럼 픽셀에 색상을 칠할지 여부를 결정하는 테스트

우선 코드를 작성해 보았습니다.

TestShader
Shader "Custom/TestShader" {
    Properties {
        _Color("main Color" , Color) = (1,1,1,1)
    }

    SubShader {
        Tags { "Queue" = "Geometry" "RenderType" = "Opaque"}
        ZTest LEqual
        ZWrite On
        Pass {
            Stencil {
                Ref 1
                Comp Always
                Pass replace
            }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            uniform float4 _Color;

            float4 vert(float4 pos : POSITION) : SV_POSITION {
                return mul(UNITY_MATRIX_MVP,pos);
            }

            float4 frag() : SV_TARGET {
                return _Color;
            }
            ENDCG
        }
    }
}

TestShader2
Shader "Custom/TestShader2" {
    Properties {
        _Color("Color", Color) = (1,1,1,1)
    }

    SubShader {
        Tags { "Queue" = "Transparent" "RenderType" = "Transparent"}
        ZTest LEqual
        ZWrite On
        Blend SrcAlpha OneMinusSrcAlpha

        Pass {

            Stencil {
                Ref 1
                Comp Equal
                Pass replace
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            uniform float4 _Color;

            float4 vert(float4 pos : POSITION) : SV_POSITION {
                return mul(UNITY_MATRIX_MVP,pos);
            }

            float4 frag() : SV_TARGET {
                return _Color;
            }
            ENDCG
        }
    }
}

TestShader는 반드시 Ref1을 쓰고 TestShader2는 스텐실 버퍼에 1이 들어있을 때만 그립니다.
그 때문에 TestShader2의 묘화는 배후에 TestShader를 가진 오브젝트가 있을 때만 행해져야 한다.

결과
블루 Cube가 TestShader
핑크 Cube TestShader2
핑크 Cube는 스텐실 테스트에 실패하기 때문에 그려지지 않습니다.


알기 쉽게 파랑 Cube를 크게했다.
뒤에 파란 큐브가 있고 스텐실 버퍼에 1이 기록되어 있기 때문에 핑크 큐브가 스텐실 테스트를 통과했기 때문에 핑크 큐브가 그려졌다.


Shader 처리의 순서는,
fragment 처리 => 스텐실 테스트 => (스텐실 통과의 경우) 깊이 테스트 => (깊이 테스트 통과의 경우) 쓰기
되어 있다.
스텐실 테스트가 실패하면 심도 테스트가 수행됩니까?

결과 : 스텐실 테스트가 실패하면 심도 테스트가 수행되지 않습니다.
핑크 Cube의 스텐실 테스트를 Never로 하여 반드시 불합격으로 하고, 녹색 Cube(핑크 Cube보다 Queue가 크다)를 핑크 Cube보다 안쪽에 배치했다.
녹색 큐브가 그려져 있기 때문에 핑크 큐브의 깊이 테스트가 수행되지 않음을 알 수 있습니다.



스텐실을 사용하여 윤곽선을 작성해 봅니다.



여기를 참조
htps //wgld. rg / d / u bgl / w039. HTML
h tp : // 타로를 rk. 하테나 bぉg. jp/엔트리/2014/07/27/193816

1Pass로 윤곽선용 스텐실을 써
2Pass로 본체 그리기
3Pass로 개요 그리기
Shader "Custom/TestShader2" {
    Properties {
        _Color("Color", Color) = (1,1,1,1)
        _OutlineColor("Outline Color",Color) = (1,1,1,1)
        _OutlineWidth("outline width",Range(0,0.5)) = 0.01

    }

    SubShader {
        Pass {
            Tags { "Queue" = "Geometry-1" "RenderType" = "Opaque"}
            ZTest Off
            ZWrite Off
            ColorMask 0
            Cull Off

            Stencil {
                Ref 2
                CompFront always
                CompBack always
                PassFront replace
                PassBack replace
            }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform float _OutlineWidth;

            float4 vert(float4 pos : POSITION,float3 normal : NORMAL) : SV_POSITION {
                float4 wPos = mul(UNITY_MATRIX_MVP,pos);
                wPos += float4(UnityObjectToWorldNormal(normal) * _OutlineWidth,0);
                return wPos;
            }

            float4 frag() : SV_TARGET {
                return float4(1,1,1,1);
            }
            ENDCG
        }

        Pass {
            Tags { "Queue" = "Geometry" "RenderType" = "Opaque"}
            ZTest LEqual
            ZWrite On
            Stencil {
              Ref 3
              CompFront always
              CompBack always
              PassFront replace
              PassBack replace
              FailFront replace
              FailBack replace
            //ZFailBack replace
            //ZFailFront replace
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            uniform float4 _Color;

            float4 vert(float4 pos : POSITION) : SV_POSITION {
                return mul(UNITY_MATRIX_MVP,pos);
            }

            float4 frag() : SV_TARGET {
                return _Color;
            }
            ENDCG
        }

        Pass {
            Tags { "Queue" = "Ovarlay" "RenderType" = "Opaque"}
            ZTest Off
            ZWrite Off

            Stencil {
                Ref 2
                Comp Equal
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            uniform float4 _OutlineColor;
            uniform float _OutlineWidth;

            float4 vert(float4 pos : POSITION,float3 normal : NORMAL) : SV_POSITION {
                float4 wPos = mul(UNITY_MATRIX_MVP,pos);
                wPos += float4(UnityObjectToWorldNormal(normal) * _OutlineWidth,0);
                return wPos;
            }

            float4 frag() : SV_TARGET {
                return _OutlineColor;
            }
            ENDCG
        }
    }
}

결과:

파란 큐브에 끼워 넣어보기

복수 준비


개요 재미 :)

좋은 웹페이지 즐겨찾기