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

про mipmapping

#0
17:43, 23 фев 2010

При отключенном мипмаппинге, когда камера далеко от поверхности, заметно снижается фпс(с 800 до 160).
На поверхности текстура большого разрешения с "тяжелым" пиксельным шейдером.
При этом пиксели на экране мерцают, что понятно. На один пиксель на экране приходится сразу много текселей.
Так вот я хочу понять механизм, почему падает фпс. То есть просто: отключаем мипмаппинг, "отходим" подальше и смотрим на фпс.

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


Я на самом деле пытаюсь отрисовать кусок земной поверхности с 4-мя диффузными и 4-мя normal  текстурами, за 1 проход.
Вначале 4 текстуры я обьединил в одну и считал текстурные координаты в пиксельном шейдере.
Все было чудесно до мипмаппинга. С мипмаппингом появились артефакты в виде сетки линий толщиной в 1 пиксель(на любом удалении). Эти линии были в тех местах, где происходит резкий переход uv. Если же отражать текстуру зеркально, то никаких багов нет.  Те было типа 0.98,  0.99 и потом - 0.0. Цвет этих линии явно берется из самого маленького mip-уровня. Короче не нравится мимаппингу ручной wrapping текстур.

Кто-нибудь знает метод(или статью) о том, как сделать texture atlas с тайлингом и мип/эмуляцией мип? Очень не хочется делать многопроходность((

#1
19:22, 23 фев 2010

мип-маппинг должен быть включен почти всегда.
тормоза - от того, что кэширование хуже, наверное.

#2
19:44, 23 фев 2010

slava_mib
> тормоза - от того, что кэширование хуже, наверное.
еще как вариант - при отдалении попадает в кадр больше вершинок\полигонов. а то и дипов больше становиться... Ящер, уверен что у тебя в пиксельные шойдеры упирается?


Ящер
> Вначале 4 текстуры я обьединил в одну и считал текстурные координаты в
> пиксельном шейдере.
можно использовать tex2Dlod, выбирая мип-уровень в зависимости от расстояния до края тайла. но выглядеть наверняка будет погано.
> Если же отражать текстуру зеркально, то никаких багов нет
странно. всеравно должны остаться.

еще вариант - это рассчиитывать мип-уровни самостоятельно. но опять будут артифакты из за линейной интерполяции соседних текселей. т.е на каждом мип уровне надо оставлять каемочку в 1 тексель - тогда казалосьбы все идеально, но 1 тексель на 3ем мипуровно - это уже 8текселей на 0вом (иначе надо менять текстурные координаты в зависимости от мипа)

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

ты уверен, что есть смысл паковать в атласы? например на моей карточке 6600GT всякие ddx ddy и tex2Dlod - жутко тормозные инструкции. и гораааааздто дешевле сделать выборки из 4х разных текстур. (да и на других карточках - не думаю что будет какаято выгода, особенно если в программе эти текстуры используются в разных комбирациях.)

#3
20:26, 23 фев 2010

Kloun.
+1

На днях заметил такую же проблему с притормаживанием при  отдалении камеры от поверхности на слабой видеокарте. Ни мипмапинга ни шейдеров к ландшафту не применялось.

#4
20:43, 23 фев 2010

Rom
> На днях заметил такую же проблему с притормаживанием при отдалении камеры от
> поверхности на слабой видеокарте.
ну так вершиныже! а вообще PerfHUD в помощь ;)

#5
22:08, 23 фев 2010

Как проверить не тормозит ли кол-во дипов и/или полики - очевидно. Для этого есть тулзы (тот же перфмон скажем и другие), либо можно пикс. шейдер упростить (убрать все выч. и дискард на всё сделать, скажем).

#6
11:36, 24 фев 2010

>Как проверить не тормозит ли кол-во дипов и/или полики - очевидно. Для этого есть тулзы (тот же перфмон скажем и другие), либо можно пикс. шейдер
>упростить (убрать все выч. и дискард на всё сделать, скажем).
c мипами - 800 фпс не зависят практически от положения камеры, без мипов - меньше 200 при удалении.
Наверное действительно дело в большом количестве обрабатываемой памяти.

Kloun
tex2Dlod это в hlsl texldb? пробовал, ничего не дает - смысла нет
это вроде тот же mipmap bias только в шейдере

>странно. всеравно должны остаться.
>еще вариант - это рассчиитывать мип-уровни самостоятельно. но опять будут артифакты из за линейной интерполяции соседних текселей. т.е на каждом мип >уровне надо оставлять каемочку в 1 тексель - тогда казалосьбы все идеально, но 1 тексель на 3ем мипуровно - это уже 8текселей на 0вом (иначе надо менять >текстурные координаты в зависимости от мипа)

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

делал так(все изображения уменьшены в 2 раза):
(2d texture)
(16 тайлов, мип уровней нет)
падает фпс при удалении, no mip mapping, визуально все замечательно, выбираю уровень сам, в зависимости от расстояния и угла:
http://img208.imageshack.us/img208/4743/16024593.jpg

и даже так:
volume текстура, no mip mapping, никаких артефактов, все чудесно, тормозит еще сильнее
http://img208.imageshack.us/img208/8448/63201629.jpg

сейчас так:
обычная текстура с mip-уровнями, mip mapping on
http://img208.imageshack.us/img208/9914/diffusemap.jpg

скрин с артефактами:
http://img691.imageshack.us/img691/8485/97841993.jpg


Шейдер тяжелый, потому он к тому же пишет в 4 флоат рендертаргета сразу.
- позиция в view space (в альфу индекс материала)
- нормали в view space (в альфу сила спекуляра)
- диффуз
- амбиентная картинка сразу в целевой rt

зато всего 1 раз за кадр вне зависимости от кол-ва источников света


>ты уверен, что есть смысл паковать в атласы? например на моей карточке 6600GT всякие ddx ddy и tex2Dlod - жутко тормозные инструкции. и гораааааздто >дешевле сделать выборки из 4х разных текстур. (да и на других карточках - не думаю что будет какаято выгода, особенно если в программе эти текстуры >используются в разных комбирациях.)

Вообще 4 текстуры мне конечно мало, но больше точно не сделать, либо нужна многопроходность((
>дешевле сделать выборки из 4х разных текстур
Не могу, потому что у меня 4 диффузные и 4 нормал-карты. Всего 8, плюс карта весов для смешения текстур, плюс глобальная карта нормалей, одна на всю землю.
В вершины запихнуть карты нельзя, потому что там нерегулярная сетка (roam). А в формате вершин остается только позиция.


он слегка мусорный, потому что уже 5 раз менялся

    consts
    {
        c0    matrixView
        c5    ambient // .xyz - ambient direction
        c8    positionView
    }

    pixelShader
    {
        ps.2.0
        // direction by z to find tangent vector 
        def c6, 0, 0, -1, 0 

        // xy to convert normal from[0..1] to [-1..1]; .z - material index; .w - tile uv modifier
        def c7, 2, -1, 3, 0.15

        // tile offsets
        def c10, 0.00048828125, 0.00048828125, 0.49902343750, 0.0
        def c11, 0.50048828125, 0.00048828125, 0.49902343750, 0.0
        def c12, 0.00048828125, 0.50048828125, 0.49902343750, 0.0
        def c13, 0.50048828125, 0.50048828125, 0.49902343750, 0.0
        def c15, 0, 1, 0, 0.0625

        def c16, 0.03125, 0, 0.1875, 0.25

        dcl t0     // position in world space
        dcl t1     // global texcoords
        dcl t2     // position in view space
        dcl v0     // 
                   // v0.w - mip level;

        dcl_2d s0  // diffuse map(tiles), .xyz - diffuse, .w - may be albedo, not implemented here ^_^
        dcl_2d s1  // normal map(tiles), .xyz - normal, .w - glossiness
        dcl_2d s2  // world normal map on the whole terrain
        dcl_2d s3  // world blend map
        
        // TILE DIFFUSE TO R2; STORE TILE NORMAL TO R3

        // get blend map (r8)
        texld r8, t1, s3 

        // texcoords //in range [0..0,9999999999]
        mul r0, t0, c7.w
        mov r0.y, -r0.z

        frc r0.xy, r0

        // resize for the FIRST tile 
        mad r1, r0, c10.z, c10


        texld r4, r1, s0 // diffuse tile
        texld r5, r1, s1 // normal tile
        mad r5.xy, r5, c7.x, c7.y // normal from [0..1] to [-1..1] 

        mul r2, r4, r8.x
        mul r3, r5, r8.x

        // resize for the SECOND tile 
        mad r1.xy, r0, c11.z, c11

        texld r4, r1, s0 // diffuse tile
        texld r5, r1, s1 // normal tile
        mad r5.xy, r5, c7.x, c7.y // normal from [0..1] to [-1..1] 

        mad r2, r4, r8.y, r2
        mad r3, r5, r8.y, r3

        // resize for the THIRD tile 
        mad r1.xy, r0, c12.z, c12

        texld r4, r1, s0 // diffuse tile
        texld r5, r1, s1 // normal tile
        mad r5.xy, r5, c7.x, c7.y // normal from [0..1] to [-1..1] 

        mad r2, r4, r8.z, r2
        mad r3, r5, r8.z, r3

        // resize for the FOURTH tile 
        mad r1.xy, r0, c13.z, c13

        texld r6, r1, s0 // diffuse tile
        texld r7, r1, s1 // normal tile
        mad r7.xy, r7, c7.x, c7.y // normal from [0..1] to [-1..1]

        mad r2, r6, r8.w, r2
        mad r4, r7, r8.w, r3

        nrm r3, r4
        /**/

        // GET NORMAL(r1) ---------------------------------->
        // WORLD NORMAL MAP(r9)
        texld r9, t1, s2
        mad r9.xyz, r9, c7.x, c7.y // normal from [0..1] to [-1..1]

        // tangent(x) r6
        crs r7.xyz, c6, r9
        nrm r6, r7

        // binormal(z) r7
        crs r8.xyz, r9, r6
        nrm r7, r8

        // normal to world space
        mul r1, r9, r3.z
        mad r1, r6, r3.x, r1
        mad r1, r7, r3.y, r1

        // OUTPUT RESULTS ------------------------------->

        // POSITION(oC1, r0) - .XYZ, MATERIALID - .W
        mov r0, t2
        mov r0.w, c7.z
        mov oC1, r0

        // NORMAL(oC2, r1) - .XYZ, MATERIALGLOSSINESS - .W
        m3x3 r5.xyz, r1, matrixView // move normal to view space
        mov r5.w, r3.w // glossiness
        mov oC2, r5

        // DIFFUSE(oC3, r2) - .XYZ 
        mov oC3, r2

        // AMBIENT PASS(oC0, r3)
        dp3 r3.w, r5, ambient
        max r3.w, r3.w, -r3.w
        add r3.w, r3.w, ambient.w

        mul r3, r2, r3.w
        mov oC0, r3
    }
ПрограммированиеФорумГрафика

Тема в архиве.