Получение позиции вершины из скрипта

Шейдеры и все-все-все.

Получение позиции вершины из скрипта

Сообщение kripto289 28 июн 2015, 20:43

День добрый.
Пытаюсь прикрутить к воде плавание объектов.
Думал можно просто получить вершину текущего меша, но столкнулся с проблемой. Волны на воде изменяются с помощью вершинного шейдера. Сам меш всегда статичен, поэтому и вертексы не меняют координат.
Как получить позицию вершины которая изменяется в шейдере?
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт

Re: Получение позиции вершины из скрипта

Сообщение kripto289 29 июн 2015, 04:21

Судя по тому, что в инете нет решения, и везде советуют переносить код, то пришлось переносить расчёт из шейдера в c# и рассчитывать точку вручную.
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт

Re: Получение позиции вершины из скрипта

Сообщение artk 01 июл 2015, 11:13

часть кода ProWater
Синтаксис:
Используется csharp
public Vector3 GetHeightOffsetAt(Vector3 pos)
        {      
                Vector3 vertex = new Vector3(pos.x,pos.y,pos.z);
               
                // local space vertex
                vertex = transform.InverseTransformPoint(vertex);      
               
                // apply only world positioning so we can patch toegther several water meshes
                float xOfs = transform.position.x/transform.localScale.x; //10.0f;
                float zOfs = transform.position.z/transform.localScale.z;//*10.0f;     
               
                Vector4 displacement4 = Water3Manager.Instance().GetMaterialVector("_Displacement");
                Vector4 displacementXz = Water3Manager.Instance().GetMaterialVector("_DisplacementXz");
               
                vertex.x += xOfs;
                vertex.z += zOfs;              
               
                float tiling = displacement4.x;
                float speed = displacement4.z;

                float tiling2 = displacement4.y;
                float speed2 = displacement4.w;
               
                float valX = Mathf.Sin(tiling * vertex.x + Water3Manager.Instance().m_Timer * speed);
                float valY = Mathf.Sin(tiling2 * vertex.z + Water3Manager.Instance().m_Timer  * speed2);
               
                vertex.y = 0.0F + displacementXz.x/transform.localScale.x * valX + displacementXz.z/transform.localScale.z * valY;
               
                // the displace mesh amount needs to be added, too
                vertex.y += Water3Manager.Instance().GetDisplaceMeshAmountAt(vertex, transform);
               
                vertex.x -= xOfs;
                vertex.z -= zOfs;
                vertex = transform.TransformPoint(vertex);
                               
                return vertex;
        }
Аватара пользователя
artk
Старожил
 
Сообщения: 749
Зарегистрирован: 22 май 2011, 12:22

Re: Получение позиции вершины из скрипта

Сообщение kripto289 01 июл 2015, 18:15

artk писал(а):часть кода ProWater
Синтаксис:
Используется csharp
public Vector3 GetHeightOffsetAt(Vector3 pos)
        {      
                Vector3 vertex = new Vector3(pos.x,pos.y,pos.z);
               
                // local space vertex
                vertex = transform.InverseTransformPoint(vertex);      
               
                // apply only world positioning so we can patch toegther several water meshes
                float xOfs = transform.position.x/transform.localScale.x; //10.0f;
                float zOfs = transform.position.z/transform.localScale.z;//*10.0f;     
               
                Vector4 displacement4 = Water3Manager.Instance().GetMaterialVector("_Displacement");
                Vector4 displacementXz = Water3Manager.Instance().GetMaterialVector("_DisplacementXz");
               
                vertex.x += xOfs;
                vertex.z += zOfs;              
               
                float tiling = displacement4.x;
                float speed = displacement4.z;

                float tiling2 = displacement4.y;
                float speed2 = displacement4.w;
               
                float valX = Mathf.Sin(tiling * vertex.x + Water3Manager.Instance().m_Timer * speed);
                float valY = Mathf.Sin(tiling2 * vertex.z + Water3Manager.Instance().m_Timer  * speed2);
               
                vertex.y = 0.0F + displacementXz.x/transform.localScale.x * valX + displacementXz.z/transform.localScale.z * valY;
               
                // the displace mesh amount needs to be added, too
                vertex.y += Water3Manager.Instance().GetDisplaceMeshAmountAt(vertex, transform);
               
                vertex.x -= xOfs;
                vertex.z -= zOfs;
                vertex = transform.TransformPoint(vertex);
                               
                return vertex;
        }

Это уже не актуально.
Переписал код water4 для c#, дабы получить волну по Герстенеру. Может кому пригодится :-?

Синтаксис:
Используется csharp
Vector3 GerstnerOffset4(Vector2 xzVtx, Vector4 _GSteepness, Vector4 _GAmplitude, Vector4 _GFrequency, Vector4 _GSpeed, Vector4 _GDirectionAB, Vector4 _GDirectionCD)
    {
        Vector3 offsets = new Vector3();
        var stepAmpXX = _GSteepness.x * _GAmplitude.x;
        var stepAmpYY = _GSteepness.y * _GAmplitude.y;
        Vector4 AB = new Vector4(stepAmpXX * _GDirectionAB.x,
                                 stepAmpXX * _GDirectionAB.y,
                                 stepAmpYY * _GDirectionAB.z,
                                 stepAmpYY * _GDirectionAB.w);
        Vector4 CD = new Vector4(_GSteepness.z * _GAmplitude.z * _GDirectionCD.x,
                                _GSteepness.z * _GAmplitude.z * _GDirectionCD.y,
                                _GSteepness.w * _GAmplitude.w * _GDirectionCD.z,
                                _GSteepness.w * _GAmplitude.w * _GDirectionCD.w);

        float dotA = Vector2.Dot(new Vector2(_GDirectionAB.x, _GDirectionAB.y), xzVtx);
        float dotB = Vector2.Dot(new Vector2(_GDirectionAB.z, _GDirectionAB.w), xzVtx);
        float dotC = Vector2.Dot(new Vector2(_GDirectionCD.x, _GDirectionCD.y), xzVtx);
        float dotD = Vector2.Dot(new Vector2(_GDirectionCD.z, _GDirectionCD.w), xzVtx);
        Vector4 dotABCD = new Vector4(dotA * _GFrequency.x, dotB * _GFrequency.y, dotC * _GFrequency.z, dotD * _GFrequency.w);

        Vector4 TIME = new Vector4((Time.time * _GSpeed.x) % 6.2831f,
                                    (Time.time * _GSpeed.y) % 6.2831f,
                                    (Time.time * _GSpeed.z) % 6.2831f,
                                    (Time.time * _GSpeed.w) % 6.2831f);

        Vector4 COS = new Vector4(Mathf.Cos(dotABCD.x + TIME.x),
                                  Mathf.Cos(dotABCD.y + TIME.y),
                                  Mathf.Cos(dotABCD.z + TIME.z),
                                  Mathf.Cos(dotABCD.w + TIME.w));
        Vector4 SIN = new Vector4(Mathf.Sin(dotABCD.x + TIME.x),
                                  Mathf.Sin(dotABCD.y + TIME.y),
                                  Mathf.Sin(dotABCD.z + TIME.z),
                                  Mathf.Sin(dotABCD.w + TIME.w));

        offsets.x = Vector4.Dot(COS, new Vector4(AB.x, AB.z, CD.x, CD.z));
        offsets.z = Vector4.Dot(COS, new Vector4(AB.y, AB.w, CD.y, CD.w));
        offsets.y = Vector4.Dot(SIN, _GAmplitude);

        return offsets;

    }


Более того, у меня ещё и динамические волны, которые так же привносят изменения в высоту вершин воды. Но там уже код - это перевод из координат точки пространства в координату текстуры волн.
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт


Вернуться в Shader Lab

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2