Войти
ПрограммированиеФорумГрафика

Omni Shadows (6 стр)

Страницы: 1 2 3 4 5 6
#75
9:17, 17 июля 2021

MikeNew
> Взяты ли они один в один из исходников OmniTiledShadows или изменены?
Нет, я долго пытался заставить их работать хоть как-то в Unity. В итоге у меня получился страшный гибрид из 2 статей вперемешку.
Матрицы вида:

        private void CalculateTetrahedronMatrices()
        {
            Matrix4x4 xRotMatrix;
            Matrix4x4 yRotMatrix;
            Matrix4x4 zRotMatrix;
            xRotMatrix = CreateRotationY(180.0f);
            yRotMatrix = CreateRotationX(27.36780516f);
            m_TetrahedronMatrices[0] = yRotMatrix * xRotMatrix;
            xRotMatrix = CreateRotationY(0.0f);
            yRotMatrix = CreateRotationX(27.36780516f);
            zRotMatrix = CreateRotationZ(90.0f);
            m_TetrahedronMatrices[1] = zRotMatrix * yRotMatrix * xRotMatrix;
            xRotMatrix = CreateRotationY(270.0f);
            yRotMatrix = CreateRotationX(-27.36780516f);
            m_TetrahedronMatrices[2] = yRotMatrix * xRotMatrix;
            xRotMatrix = CreateRotationY(90.0f);
            yRotMatrix = CreateRotationX(-27.36780516f);
            zRotMatrix = CreateRotationZ(90.0f);
            m_TetrahedronMatrices[3] = zRotMatrix * yRotMatrix * xRotMatrix;
        }

        private Matrix4x4 CreateRotationX(float angle)
        {
            return Matrix4x4.Rotate(Quaternion.Euler(angle, 0, 0));
        }

        private Matrix4x4 CreateRotationY(float angle)
        {
            return Matrix4x4.Rotate(Quaternion.Euler(0, angle, 0));
        }

        private Matrix4x4 CreateRotationZ(float angle)
        {
            return Matrix4x4.Rotate(Quaternion.Euler(0, 0, angle));
        }
  
        ...
        // здесь какая-то путаница с LHS и RHS матрицами
        // scale подобрал вручную, методом тыка
        private float4x4[] m_PointScaleMatrices = new float4x4[4]
        {
            float4x4.Scale(-1, 1, 1),
            float4x4.Scale(1, -1, 1),
            float4x4.Scale(-1, 1, 1),
            float4x4.Scale(1, -1, 1),
        };
Я кстати, до сих пор не понимаю, почему выворачивает матрицы и их нужно скейлить, если кто-то объяснит, я буду рад.

Вычисление общей матрицы worldToShadow:

            private const float kFov0 = 143.98570868f;
            private const float kFov1 = 125.26438968f;

            m_PointLightTexMatrices[0].c0 = new float4(1, 0.0f, 0.0f, 0.0f);
            m_PointLightTexMatrices[0].c1 = new float4(0.0f, 0.5f, 0.0f, 0.0f);
            m_PointLightTexMatrices[0].c2 = new float4(0.0f, 0.0f, 1.0f, 0.0f);
            m_PointLightTexMatrices[0].c3 = new float4(0, 0.5f, 0.0f, 1.0f);

            m_PointLightTexMatrices[1].c0 = new float4(0.5f, 0.0f, 0.0f, 0.0f);
            m_PointLightTexMatrices[1].c1 = new float4(0.0f, 1, 0.0f, 0.0f);
            m_PointLightTexMatrices[1].c2 = new float4(0.0f, 0.0f, 1.0f, 0.0f);
            m_PointLightTexMatrices[1].c3 = new float4(0.5f, 0, 0.0f, 1.0f);

            m_PointLightTexMatrices[2].c0 = new float4(1, 0.0f, 0.0f, 0.0f);
            m_PointLightTexMatrices[2].c1 = new float4(0.0f, 0.5f, 0.0f, 0.0f);
            m_PointLightTexMatrices[2].c2 = new float4(0.0f, 0.0f, 1.0f, 0.0f);
            m_PointLightTexMatrices[2].c3 = new float4(0, -0.5f, 0.0f, 1.0f);

            m_PointLightTexMatrices[3].c0 = new float4(0.5f, 0.0f, 0.0f, 0.0f);
            m_PointLightTexMatrices[3].c1 = new float4(0.0f, 1, 0.0f, 0.0f);
            m_PointLightTexMatrices[3].c2 = new float4(0.0f, 0.0f, 1.0f, 0.0f);
            m_PointLightTexMatrices[3].c3 = new float4(-0.5f, 0, 0.0f, 1.0f);
            
            private void CalculatePointLightMatrices(ShadowmapEntry entry)
            {
              float filterSize = GetFilterWidth(entry);// размер фильтра PCF, у меня 5x5, т.е. здесь будет просто 5

              float maxNormalBias = .5f;
              float guardAngle0 = CalcGuardAnglePerspective(kFov0, entry.Viewport.width, filterSize, maxNormalBias, 180.0f - kFov0);
              float guardAngle1 = CalcGuardAnglePerspective(kFov1, entry.Viewport.width, filterSize, maxNormalBias, 180.0f - kFov1);

              m_PointShadowProjMatrices[0] = CreatePerspective(new Vector2(kFov0 + guardAngle0, kFov1 + guardAngle1), entry.ShadowNearPlane * .5f, entry.Range);
              m_PointShadowProjMatrices[1] = CreatePerspective(new Vector2(kFov1 + guardAngle1, kFov0 + guardAngle0), entry.ShadowNearPlane * .5f, entry.Range);

              Vector3 lightPos = entry.LocalToWorldMatrix.GetColumn(3);
              float4x4 shadowTranslateMatrix = float4x4.Translate(-lightPos);
              float4x4 shadowViewMatrix;
            
              for (int i = 0; i < 4; i++)
              {
                  shadowViewMatrix = math.mul(m_PointScaleMatrices[i], math.mul(m_TetrahedronMatrices[i], shadowTranslateMatrix));

                  int index = i & 1;
                  var shadowProj = m_PointShadowProjMatrices[index];
                  var worldToShadow = math.mul(m_PointLightTexMatrices[i], math.mul(shadowProj, shadowViewMatrix));
                  // дальше код упаковки матриц в массив, я его вырезал, т.к. не относится к делу
              }
            }

        public static float CalcGuardAnglePerspective(float angleInDeg, float resolution, float filterWidth, float normalBiasMax, float guardAngleMaxInDeg)
        {
            float angleInRad = angleInDeg * 0.5f * Mathf.Deg2Rad;
            float res = 2.0f / resolution;
            float texelSize = Mathf.Cos(angleInRad) * res;
            float beta = normalBiasMax * texelSize * 1.4142135623730950488016887242097f;
            float guardAngle = Mathf.Atan(beta);
            texelSize = Mathf.Tan(angleInRad + guardAngle) * res;
            guardAngle = Mathf.Atan((resolution + Mathf.Ceil(filterWidth)) * texelSize * 0.5f) * 2.0f * Mathf.Rad2Deg - angleInDeg;
            guardAngle *= 2.0f;

            return guardAngle < guardAngleMaxInDeg ? guardAngle : guardAngleMaxInDeg;
        }

        private Matrix4x4 CreatePerspective(Vector2 fov, float n, float f)
        {
            Matrix4x4 result = Matrix4x4.Perspective(fov.y, 1, n, f);
            result.m00 = 1.0f / Mathf.Tan(Mathf.Deg2Rad * fov.x * 0.5f);
            result.m11 = 1.0f / Mathf.Tan(Mathf.Deg2Rad * fov.y * 0.5f);

            result = GL.GetGPUProjectionMatrix(result, true);

            return result;
        }


#76
13:54, 17 июля 2021

Bonus
> m_PointLightTexMatrices[0].c0 = new float4(1, 0.0f, 0.0f, 0.0f);
Блин, вот эти дополнительные матрицы я позабыл сделать. Чтобы писать фейсы в свои отдельные области. Теперь, наконец-то, можно приступить непосредственно к клипам.
Как обычно потеряна куча времени из-за невнимательности.
Bonus
> Нет, я долго пытался заставить их работать хоть как-то в Unity.
> Я кстати, до сих пор не понимаю, почему выворачивает матрицы и их нужно
> скейлить, если кто-то объяснит, я буду рад.
У меня в Вулкане работает фактически без изменений.
Может связано с различием каких-нибудь диапазонов, ну знаешь как оно бывает - в OpenGL (-1,1) в DirectX (0,1) или наоборот.

#77
18:11, 17 июля 2021

MikeNew
> Может связано с различием каких-нибудь диапазонов, ну знаешь как оно бывает - в
> OpenGL (-1,1) в DirectX (0,1) или наоборот
Да, но тогда выворачивало бы все 4 матрицы, а тут только 2.

#78
(Правка: 10:26) 10:25, 18 июля 2021

Bonus
> Да, но тогда выворачивало бы все 4 матрицы, а тут только 2.
Если выворачивает только 2, почему ты скейлишь все 4?

Bonus

Добавил клипинг. Словил пока непонятный мне баг. Вроде как карта теней выглядит правильно, клипы точно по диагоналям:

Запустить видео по клику - Как делать игрыЗапустить видео по клику - Как делать игры

#79
11:48, 18 июля 2021

У тебя одна выборка или пцф? Для фильтра  нужен guard angle

#80
(Правка: 16:56) 16:51, 18 июля 2021

Bonus
> У тебя одна выборка или пцф? Для фильтра нужен guard angle
Одна. У меня какой-то странный косяк с одним-единственным первым фейсом, точнее с его клипингом (остальные в порядке), ищу ошибку. Причем на карте теней все в порядке.

#81
(Правка: 18:40) 18:36, 19 июля 2021

Bonus
Вроде как победил, пока без размытия границ.

Запустить видео по клику - Как делать игрыЗапустить видео по клику - Как делать игры

Bonus
> // здесь какая-то путаница с LHS и RHS матрицами
> // scale подобрал вручную, методом тыка
У меня оказалось подобное, но зеркально отразить пришлось только одну из матриц вида. Причем еще дополнительно поменять знак у одной из компонент. То есть пришлось поломать одну из матриц чтобы оно правильно заработало. Жесть.
Теперь буду атлас городить, чтобы было несколько источников света. Потом фруструм кулинг для оптимизации.
Твой способ клипа оказался очень хорош.

#82
8:39, 20 июля 2021

MikeNew
> У меня оказалось подобное, но зеркально отразить пришлось только одну из матриц
> вида.
Я сейчас вспомнил, у меня было также. Но потом выяснилось, что сломаны 2 матрицы. А выяснил это на тестовой сцене - белая комната с потолком и смотрел тени во всех направлениях.

#83
12:19, 20 июля 2021

Bonus
> Я сейчас вспомнил, у меня было также. Но потом выяснилось, что сломаны 2
> матрицы. А выяснил это на тестовой сцене - белая комната с потолком и смотрел
> тени во всех направлениях.
Я потолок не тестил, очень вероятно что баг второй матрицы вылезет именно на потолке. Надо проверить, ну главное что знаю как фиксить.

Страницы: 1 2 3 4 5 6
ПрограммированиеФорумГрафика