Иконка ресурса

Endothermic - нарушаем третий закон термодинамики в отношении запеченных квадов 2.1.2

Нет прав для скачивания
7,099
324
1,510
hohserg1 добавил(а) новый ресурс:

Endothermic - нарушаем третий закон термодинамики в отношении запеченных квадов - Графическая библиотека

К вопросу актуальности
В последних версиях майнкрафта модели блоков и предметов состоят BakedQuad, запеченных квадов. Для обывателя это выглядит как какие-то массивы интов и вообще непонятно, как с ними работать.
Endothermic - графическая библиотека, сосредоточенная на работе с BakedQuad-ами, как раз решает эту проблему.

Примеры рендеров, сделанных с помощью Endothermic
Gyazo
[ATTACH...

Узнать больше об этом ресурсе...
 
808
3
124
код библиотеки, выполняющийся непосредственно во время рендера может делать максимум по 1 аллокации на 1 квад

Я честно не понимаю, что автор имел ввиду под "кодом выполняющимся непосредственно во время рендера", но предположим, что код, аналогичный его бенчмаркам, то есть вызывающий что-то подобное каждый кадр.
Java:
public class RotationExample implements Function<BakedQuad, BakedQuad> {
    @Override
    public BakedQuad apply(BakedQuad quad) {
        return LazyUnpackedQuad.apply(quad)
                .rotate((float) Math.toRadians(-90), 0, 1, 0)
                .toBakedQuad();
    }
}

У меня глаз от таких утверждений немножко дергается, я пошел и померил сколько же там на самом деле аллоцируется в трех примерах: ColoredExample, RotationExample и SliceExample.

Измерял я переделав примеры как-то так (и вызывая это каждый кадр):
Java:
package hohserg.endothermic.example.java;

import com.sun.management.ThreadMXBean;
import hohserg.endothermic.quad.immutable.LazyUnpackedQuad;
import net.minecraft.client.renderer.block.model.BakedQuad;

import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Function;

public class ColoredExample implements Function<BakedQuad, BakedQuad> {

    @Override
    public BakedQuad apply(BakedQuad quad) {
        ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
        List<BakedQuad> list = new ArrayList<>(1000);
        long threadAllocatedBytes = threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId());
        long time = System.nanoTime();
        for (int i = 0; i < 1000; i++) {
            list.add(LazyUnpackedQuad.apply(quad)
                    .reconstructBuilder()
                    .v1_r(255)//colored first vertex to red
                    .v2_g(255)//colored second vertex to green
                    .v3_b(255)//colored third vertex to blue
                    .build()
                    .toBakedQuad());
        }
        time = System.nanoTime() - time;
        threadAllocatedBytes = threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId()) -
                threadAllocatedBytes;
        System.out.println("Alocated bytes for 1000 iterations: " + threadAllocatedBytes);
        System.out.println("Time spend for 1000 iterations: " + time + " ns");
        return list.get(ThreadLocalRandom.current().nextInt(list.size()));
    }
}


Итак, вот что я намерил (все результаты на трансформацию одного квада, то есть деленные на 1000):
Название тестаАллоцировано, байт/квадЗатрачено времени, нс/квад
ColoredExample2896~2000
RotationExample4456~4200
SliceExample10152~9100


Зачем я это делал? Чтобы подкрепить цифрами два банальных утверждения:
  1. Не надо утверждать сколько там аллокаций не померив
  2. Не надо такое выполнять в кадре, запейкате ваши модельки...
 
7,099
324
1,510
Запустил предложенный бечмарк у себя, также запустил с юзом скаловского reconstruct. Да, результаты примерно такие же.
Аллоцировано, байт/квад
Логично, байт на один квад будет дохрена в любом случае. В статье имелось ввиду количество аллокаций объектов в куче, а не их объем.
Экземпляр LazyUnpackedQuad действительно создается один на один запеченный квад.
Если попробовать профилировать, то можно увидеть, что активность сборщика мусора большую часть времени держится на 0% и никогда не превышает 3%.

Не надо такое выполнять в кадре, запейкате ваши модельки...
Смотрим на первую гифку. В принципе, такой рендер можно сделать линзами, не создавая новые квады. Однако реализация с юзом LazyUnpackedQuad не вызывает фризов или заметных просадок фпс
 
7,099
324
1,510
Если кто-то использует маппинги отличные от дефолтных(snapshot_20171003), то закидывайте в ./libs/ эту собранную версию, вместо использования jitpack
1589294272406.png
 
Сверху