Version: Unity 6.0 (6000.0)
언어 : 한국어
3D 텍스처 미리보기
스크립트를 통해 3D 텍스처 생성

셰이더에서 샘플 3D 텍스처 샘플링

커스텀 셰이더에서 3D 텍스처를 사용하려면 다음을 사용합니다.

  • 3D 텍스처 프로퍼티를 추가하는 3D 머티리얼 프로퍼티 선언. 예제: _MainTex ("Example 3D texture", 3D) = "white" {};
  • 3D 텍스처를 셰이더 입력으로 사용하도록 하는 sampler3D 샘플러 상태. 예제: sampler3D _MainTex;
  • 3D 텍스처를 샘플링하기 위한 tex3D HLSL 메서드. 예제: float4 color = tex3D(_MainTex, float3(0.5f, 0.5f, 0.5f));

예제

다음은 레이마칭을 사용하여 3D 텍스처를 샘플링하고 반투명 볼륨으로 렌더링하는 셰이더 예시입니다.

예시를 사용하려면 다음 단계를 따르십시오.

  1. 프로젝트 창에서 Add > Shader > Unlit Shader를 사용하여 새로운 기본 셰이더를 생성합니다.
  2. 셰이더 코드를 예시 코드로 교체합니다.
  3. 프로젝트 창에서 셰이더를 오른쪽 클릭하고 Create > Material을 선택하여 셰이더에서 새 머티리얼을 생성합니다.
  4. 3D 텍스처를 임포트하거나 생성합니다. 예를 들어 스크립트에서 3D 텍스처 생성 페이지의 예시 코드를 사용합니다.
  5. 3D 텍스처 에셋을 프로젝트 창에서 머티리얼의 Texture 3D 프로퍼티로 드래그합니다.
  6. 머티리얼을 게임 오브젝트에 연결합니다.
Shader "Unlit/VolumeShader"
{
    Properties
    {
        _MainTex ("Texture", 3D) = "white" {}
        _Alpha ("Alpha", float) = 0.02
        _StepSize ("Step Size", float) = 0.01
    }
    SubShader
    {
        Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
        Blend One OneMinusSrcAlpha
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            // Maximum number of raymarching samples
            #define MAX_STEP_COUNT 128

            // Allowed floating point inaccuracy
            #define EPSILON 0.00001f

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 objectVertex : TEXCOORD0;
                float3 vectorToSurface : TEXCOORD1;
            };

            sampler3D _MainTex;
            float4 _MainTex_ST;
            float _Alpha;
            float _StepSize;

            v2f vert (appdata v)
            {
                v2f o;

                // Vertex in object space. This is the starting point for the raymarching.
                o.objectVertex = v.vertex;

                // Calculate vector from camera to vertex in world space
                float3 worldVertex = mul(unity_ObjectToWorld, v.vertex).xyz;
                o.vectorToSurface = worldVertex - _WorldSpaceCameraPos;

                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            float4 BlendUnder(float4 color, float4 newColor)
            {
                color.rgb += (1.0 - color.a) * newColor.a * newColor.rgb;
                color.a += (1.0 - color.a) * newColor.a;
                return color;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                // Start raymarching at the front surface of the object
                float3 rayOrigin = i.objectVertex;

                // Use vector from camera to object surface to get ray direction
                float3 rayDirection = mul(unity_WorldToObject, float4(normalize(i.vectorToSurface), 1));

                float4 color = float4(0, 0, 0, 0);
                float3 samplePosition = rayOrigin;

                // Raymarch through object space
                for (int i = 0; i < MAX_STEP_COUNT; i++)
                {
                    // Accumulate color only within unit cube bounds
                    if(max(abs(samplePosition.x), max(abs(samplePosition.y), abs(samplePosition.z))) < 0.5f + EPSILON)
                    {
                        float4 sampledColor = tex3D(_MainTex, samplePosition + float3(0.5f, 0.5f, 0.5f));
                        sampledColor.a *= _Alpha;
                        color = BlendUnder(color, sampledColor);
                        samplePosition += rayDirection * _StepSize;
                    }
                }

                return color;
            }
            ENDCG
        }
    }
}


예시 셰이더를 스크립트에서 3D 텍스처 생성 페이지의 3D 텍스처와 함께 사용하는 경우 Unity가 렌더링하는 볼륨입니다.

추가 리소스

3D 텍스처 미리보기
스크립트를 통해 3D 텍스처 생성