Вы не используете ни дескриптор вершины, ни параметр [[stage_in]]
для своего вершинного шейдера.Итак, Metal не выбирает / собирает данные вершин для вас.Вы просто индексируете в буфер, который размечен вашими данными вершин уже в нужном вам формате.Все в порядке.См. Мой ответ здесь для получения дополнительной информации о дескрипторе вершины.
Однако, учитывая, что параметр vertexStart
вызова draw влияет только на значение параметра вашей вершинной функции с[[vertex_id]]
атрибут.Ваша вершинная функция не имеет такого параметра, не говоря уже о его использовании.Вместо этого он использует параметр [[instance_id]]
для индексации в буфере вершинных данных.Вы можете прочитать другой мой ответ здесь для быстрого ознакомления с вызовами отрисовки и с тем, как они приводят к вызовам вашей функции вершинного шейдера.
Существует несколько способов изменить ситуацию наНарисуйте только половину очков.Вы можете изменить используемый вызов отрисовки на:
renderEncoder.drawPrimitives(type: .point,
vertexStart: 0,
vertexCount: 1,
instanceCount: emitter.currentParticles / 2,
baseInstance: emitter.currentParticles / 2)
Это не потребует никаких изменений в вершинном шейдере.Он просто изменяет диапазон значений, передаваемых параметру instance
.Однако, поскольку это не похоже на случай инстансинга, я рекомендую вам изменить шейдер и ваш вызов отрисовки.Для шейдера переименуйте параметр instance
в vertex
или vid
и измените его атрибут с [[instance_id]]
на [[vertex_id]]
.Затем измените вызов draw на:
renderEncoder.drawPrimitives(type: .point,
vertexStart: emitter.currentParticles / 2,
vertexCount: emitter.currentParticles / 2)
По правде говоря, в этом случае они в основном ведут себя одинаково, но последний лучше представляет то, что вы делаете (и вызов draw проще, чтохорошо).