Unity 6.3
0 онлайн 54 гостей 3 в системе
Вход

Образец текстуры 3D в шейдере

Чтобы использовать текстуру 3D в пользовательском шейдере, вы можете использовать следующее:

  • Декларация свойства материала 3D для добавления свойства текстуры 3D. Например, _MainTex ("Example 3D texture", 3D) = "white" {};
  • Семплер sampler3D состояние для использования 3D-текстуры как входа для шейдера. Например, sampler3D _MainTex;
  • Метод tex3D HLSL для семплирования текстуры 3D. Например, float4 color = tex3D(_MainTex, float3(0.5f, 0.5f, 0.5f));

Пример

Ниже приведён пример шейдера, который использует raymarching для выборки текстуры 3D и отображения ее как полупрозрачного объема.

Чтобы использовать пример, выполните следующие действия:

  1. В окне Project используйте Добавить > Шейдер > Неосвещённый шейдер для создания нового базового шейдера.
  2. Замените код шейдера примерным кодом.
  3. Щелкните правой кнопкой мыши шейдер в окне Project и выберите Создать > Материал для создания нового материала из шейдера.
  4. Импортируйте или создайте текстуру 3D. Например, используйте примерный код из страницы Создание текстуры 3D на странице сценария.
  5. Перетащите текстуру 3D из окна Project в свойство Texture 3D материала.
  6. Прикрепите материал к GameObject.
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
        {
            HLSLPROGRAM
            #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;
            }
            ENDHLSL
        }
    }
}


Том Unity отображается, если вы используете примерный шейдер с текстурой 3D из Создайте текстуру 3D на странице сценария.

Дополнительные ресурсы