← Назад к вопросам

Как создать текстуру положения вершин?

2.0 Middle🔥 202 комментариев
#Рендеринг и графика

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Создание текстуры положения вершин (Vertex Position Texture) в Unity

Создание текстуры положения вершин (Vertex Position Texture) — это продвинутая техника, которая сохраняет мировые координаты вершин меша в текстуру для последующего использования в шейдерах или вычислениях на CPU/GPU. Это особенно полезно для эффектов постобработки, деколей, взаимодействий с физикой на GPU и систем частиц.

Основные подходы к созданию

Существует два основных метода генерации такой текстуры:

1. Рендеринг в текстуру с помощью камеры

Самый распространенный подход — использовать Render Texture и специальный шейдер, который записывает позиции вершин.

Пример кода на C# для настройки камеры рендеринга:

using UnityEngine;

public class VertexPositionTextureGenerator : MonoBehaviour
{
    public Camera targetCamera;
    public RenderTexture positionTexture;
    public Material positionRenderMaterial; // Шейдер, который выводит позиции
    
    void Start()
    {
        // Создаем Render Texture
        positionTexture = new RenderTexture(1024, 1024, 24, RenderTextureFormat.ARGBFloat);
        positionTexture.enableRandomWrite = true;
        positionTexture.Create();
        
        // Настраиваем камеру
        targetCamera.targetTexture = positionTexture;
        targetCamera.RenderWithShader(positionRenderMaterial.shader, "RenderType");
    }
    
    void OnDestroy()
    {
        if (positionTexture != null)
            positionTexture.Release();
    }
}

2. Вычисление позиций вершин в скрипте

Альтернативный подход — вычисление позиций напрямую из меша и запись в текстуру.

Пример заполнения текстуры данными позиций:

using UnityEngine;

public class MeshPositionTextureGenerator : MonoBehaviour
{
    public Texture2D GeneratePositionTexture(Mesh mesh, int textureSize = 1024)
    {
        Vector3[] vertices = mesh.vertices;
        Texture2D posTex = new Texture2D(textureSize, textureSize, TextureFormat.RGBAFloat, false);
        
        // Преобразуем позиции вершин в цвета
        Color[] pixels = new Color[textureSize * textureSize];
        
        for (int i = 0; i < vertices.Length && i < pixels.Length; i++)
        {
            Vector3 worldPos = transform.TransformPoint(vertices[i]);
            
            // Сохраняем позицию в цветах (x,y,z в r,g,b)
            pixels[i] = new Color(
                worldPos.x, 
                worldPos.y, 
                worldPos.z, 
                1.0f
            );
        }
        
        posTex.SetPixels(pixels);
        posTex.Apply();
        return posTex;
    }
}

Шейдер для рендеринга позиций вершин

Пример шейдера, который выводит мировые позиции:

Shader "Custom/VertexPositionShader"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            
            struct appdata
            {
                float4 vertex : POSITION;
            };
            
            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 worldPos : TEXCOORD0;
            };
            
            v2f vert(appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                return o;
            }
            
            float4 frag(v2f i) : SV_Target
            {
                // Сохраняем мировую позицию в текстуре
                // Добавляем 0.5 и умножаем на 0.5 для преобразования [-1,1] в [0,1]
                float3 normalizedPos = (i.worldPos * 0.5) + 0.5;
                return float4(normalizedPos, 1.0);
            }
            ENDCG
        }
    }
}

Практическое применение

Текстуры позиций вершин используются для:

  • Декольных систем — определение точного положения поверхности для размещения декалей
  • Эффектов постобработки, зависящих от глубины и позиции
  • Интерактивных эффектов — взаимодействие с объектами на GPU
  • Передачи данных между проходами рендеринга в сложных конвейерах

Ключевые соображения

  1. Формат текстуры — используйте RenderTextureFormat.ARGBFloat для максимальной точности
  2. Точность — текстуры с плавающей точкой потребляют больше памяти (16 байт на пиксель)
  3. Производительность — рендеринг в текстуру добавляет дополнительный проход рендеринга
  4. Координатное пространство — определитесь, нужно ли сохранять позиции в мировом или локальном пространстве

Оптимизации

  • Используйте меньший размер текстуры при допустимой потере точности
  • Рассмотрите использование Compute Shaders для генерации на GPU без камеры рендеринга
  • Кэшируйте текстуры позиций для статичных объектов

Создание текстур позиций вершин открывает возможности для сложных визуальных эффектов, где требуется точная геометрическая информация о сцене в текстурах для шейдерных вычислений.