Страница 1 из 1

Тайлинг текстуры относительно скейла объекта

СообщениеДобавлено: 30 июн 2020, 01:26
Cylau
Только начал погружаться в эти ваши шейдеры и тут же столкнулся с проблемой.
Хочу, чтобы текстура тайлилась на каждую грань в зависимости от скейла объекта. Если X Y Z одинаковые, то проблем не возникает.
Скрытый текст:
Изображение

Но если задать какие-нибудь произвольные значения для скейла, то всё начинает плыть.
Скрытый текст:
Изображение
Изображение

Возможно ли сделать так, чтобы текстура тайлилась на любую форму меша так же, как на первом скрине?

Фрагмент шейдера, отвечающий за тайлинг текстуры
Скрытый текст:
Изображение
И сама текстура
Изображение

Re: Тайлинг текстуры относительно скейла объекта

СообщениеДобавлено: 30 июн 2020, 09:52
Tolking
Невозможно сделать чтобы текстура тайлилась на ЛЮБУЮ форму меша. Нельзя листом бумаги обернуть мячик, чтобы на бумаге не было складок.

Re: Тайлинг текстуры относительно скейла объекта

СообщениеДобавлено: 01 июл 2020, 01:32
alew
С помощью UV координат можно это сделать
Изображение


Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class uvScale : MonoBehaviour
{
    GameObject g;
    Mesh mesh;
    Material m;
    Texture2D texture2d;
    public Vector2[] uv;
    Vector2[] uvLast;
    bool loadTexture = false;
   
    void Start()
    {
        g = GameObject.CreatePrimitive(PrimitiveType.Cube);
        mesh = g.GetComponent<MeshFilter>().mesh;
        StartCoroutine(textureLoad());
        uv = mesh.uv;
        uvLast = mesh.uv;
       
    }

    // Update is called once per frame
    void Update()
    {
        if (loadTexture)
        {
            if (!uv.Equals(uvLast))
            {
                mesh.SetUVs(0, uv);
                uvLast = mesh.uv;
            }
   
            if (Input.GetKey(KeyCode.S))
            {
                ScaleUV(.01f);
            }
            if (Input.GetKey(KeyCode.X))
            {
                ScaleUV(-.01f);
            }
            MoveUVHorizontal(Input.GetAxis("Horizontal")*0.01f);
            MoveUVVertical(Input.GetAxis("Vertical")*0.01f);
            }
        void ScaleUV(float s)
        {
            Vector2 v = uv[6];
            v.x += s;
            v.y += -s;
            uv[6]  =v;
            v = uv[7];
            v.x += -s;
            v.y +=- s;
            uv[7] = v;
            v = uv[10];
            v.x += s;
            v.y += s;
            uv[10] = v;
            v = uv[11];
            v.x += -s;
            v.y += s;
            uv[11] = v;
        }
        void MoveUVHorizontal(float s)
        {
            Vector2 v = uv[6];
            v.x += s;
            uv[6] = v;
            v = uv[7];
            v.x += s;
            uv[7] = v;
            v = uv[10];
            v.x += s;
            uv[10] = v;
            v = uv[11];
            v.x += s;
            uv[11] = v;
        }
        void MoveUVVertical(float s)
        {
            Vector2 v = uv[6];
            v.y += s;
            uv[6] = v;
            v = uv[7];
            v.y += s;
            uv[7] = v;
            v = uv[10];
            v.y += s;
            uv[10] = v;
            v = uv[11];
            v.y += s;
            uv[11] = v;
        }
    }
    private void OnGUI()
    {
        GUILayout.Label("press S,X to scale");
        GUILayout.Label("press arrows to move");
    }
    IEnumerator textureLoad()
    {
        UnityWebRequest request = UnityWebRequestTexture.GetTexture("https://opengameart.org/sites/default/files/styles/medium/public/preview_874.png");
        yield return request.SendWebRequest();
        if (request.isHttpError || request.isNetworkError)
            print("егор, наверно нет текстуры");
        else
            texture2d = DownloadHandlerTexture.GetContent(request);
        loadTexture = true;
        texture2d.filterMode = FilterMode.Point;
        m = new Material(Shader.Find("Unlit/Texture"));
        m.SetTexture(1, texture2d);
        g.GetComponent<MeshRenderer>().material = m;
    }
}

 

Re: Тайлинг текстуры относительно скейла объекта

СообщениеДобавлено: 01 июл 2020, 02:43
Tolking
На кубический меш можно. На ЛЮБУЮ форму меша - нет.

Re: Тайлинг текстуры относительно скейла объекта

СообщениеДобавлено: 03 июл 2020, 08:19
jetyb
Посмотрите как сделан трипланарный шейдер:
есть точка и ось координат Oxyz
берется три плоскости Oxy, Oyz, Oxz
для каждой плоскости находится проекция мировой позиции точки - двумерная координата UV_z, UV_x, UV_y
затем считаются веса: скалярные произведения нормали точки на нормали этих плоскостей w_z, w_x, w_y
веса нормируются
UV = w_z * UV_z + w_x * UV_x + w_y * UV_y
полученное UV - проскэйленная координата

Если кубик как-то развернут, то можно брать за ось Oxyz локальные координаты кубика (определяются через мировую матрицу модели - параметр _Object2World). Не забудьте поставить тэг DisableBatching, чтобы батчинг не похерил мировую матрицу модели.