Золотое правило: не делайте ненужных операций! Вот почему вы вычисляете свою матрицу преобразования на CPU (так как она не изменяется для каждого фрагмента или даже для каждой вершины). Таким образом, вам нужно всего лишь умножить каждую вершину на одну матрицу (одна матричная операция на ЦП часто все же лучше, чем тысячи на ГП). Плохая идея - просто переместить все в фрагментный шейдер, чтобы ограничить GPU приложения. Конечно, если вы выполняете много ненужных операций для каждого фрагмента, вы, вероятно, будете ограничены графическим процессором, но для чего, если избежать этих вычислений, вы увеличите общую производительность с теми же результатами?
Имейте в виду, что простые матричные операции 4x4 также требуют невероятных затрат на ЦП, поскольку они выполняются в худшем случае один раз для объекта. Анимация костей (путем смешивания вершин) - это другое дело. Обычно это делается в вершинном шейдере, так как преобразование изменяется для каждой вершины. Но повторное перемещение этих вычислений в фрагментный шейдер не даст вам ничего, кроме, вероятно, более низкой производительности.
Имейте в виду, что такие вещи, как отбраковка усеченного конуса, сокращают только операции на каждую вершину (и вообще вызывают вызовы рисования), так как после вершинного шейдера и примитивной сборки (и возможного геометрического шейдера) примитивы все равно обрезаются относительно усеченного вида. Поэтому сконцентрируйтесь на крупномасштабном отбраковке на стороне процессора, например отбраковке усеченного конуса и, возможно, отбраковке окклюзии (что также уменьшает оверрейд и, следовательно, вызовы фрагмента шейдера). Но, как сказал Матиас, накладные расходы должны быть сбалансированы с общим приростом производительности.