XNA Layered Sprite проблема - PullRequest
       5

XNA Layered Sprite проблема

2 голосов
/ 29 января 2011

У меня есть игровой объект, который управляет несколькими объектами спрайтов. Каждый из спрайтов немного перекрывает друг друга, и рисование их выглядит очень хорошо, когда они имеют непрозрачность 100%. Если я установлю их непрозрачность, скажем, 50%, то есть когда все идет в банк, потому что любая перекрывающаяся область не является непрозрачной на 50% из-за нескольких слоев.

РЕДАКТИРОВАТЬ: Ой! Почему-то я думал, что не могу загрузить изображения. Во всяком случае ....

http://postimage.org/image/2fhcmn6s/ -> Вот оно. Думаю, мне нужно больше представителей для правильного включения.

Слева направо:
1. Несколько спрайтов, непрозрачность 100%. Отлично!
2. Оба значения составляют 50%, но обратите внимание, как область перекрытия различает их как два спрайта.
3. Это желаемое поведение. Они на 50% непрозрачны, но с точки зрения составного изображения.

Как лучше всего решить эту проблему? Является ли цель рендера хорошей идеей? Что если у меня есть сотни таких «мультиспрайтов»?

Надеюсь, это имеет смысл. Спасибо!

Ответы [ 3 ]

2 голосов
/ 29 января 2011

Метод 1:

Если вы заботитесь об индивидуальной непрозрачности каждого спрайта, то визуализируйте изображение на фоне с текстурой рендеринга цели того же размера, используя 50% или любую непрозрачностьВы хотите, чтобы спрайт был на фоне.Затем нарисуйте эту цель рендеринга с непрозрачностью 100%.

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

Метод 2:

Если вам не нужна настройка непрозрачности каждого спрайта, вы можете просто нарисовать все спрайты со 100% непрозрачностью для цели рендеринга.Затем нарисуйте цель рендеринга над фоном с непрозрачностью 50%.


Проблемы производительности:

Я упомянул два примера отрисовки для целей рендеринга, каждый для своей цели.Эффект.

Метод 1:

Вы хотите иметь возможность указать различную непрозрачность для каждого спрайта.Если это так, вам нужно визуализировать каждый спрайт в rendertarget, а затем нарисовать текстуру rendertarget в окончательной текстуре.Фактически, это та же самая стоимость, что и рисование в два раза больше спрайтов, сколько вам нужно.В этом случае это 400 вызовов отрисовки, что может быть очень дорого.

Если вы пакетируете вызовы и используете одну большую цель рендеринга для всех спрайтов, вам может потребоваться всего 2 вызова отрисовки (в зависимости от размера ваших спрайтов и максимального размера текстуры).

Метод 2:

Вам не нужна разная непрозрачность для каждого спрайта.В этом случае вы почти наверняка сможете обойтись всего двумя вызовами отрисовки, независимо от размера спрайта.Просто пакетируйте все вызовы отрисовки спрайтов (с непрозрачностью 100%), чтобы нарисовать цель рендеринга.Это один розыгрыш.Теперь нарисуйте эту цель визуализации поверх фонового изображения с желаемой непрозрачностью (например, непрозрачность 50%), и у всех спрайтов будет эта непрозрачность.Этот случай проще реализовать.

0 голосов
/ 29 января 2011

Сначала вы должны попробовать материал из ответа Эндрю, но если это не сработает, вы все равно можете отрендерить все спрайты (при условии, что все они имеют одинаковую непрозрачность) на RenderTarget (2D) со 100% непрозрачностью, и затем рендеринг этой RenderTarget на экран с 50%.

Примерно так в XNA 4.0:

RenderTarget2D rt = new RenderTarget2D(graphicsDevice, 
                                       graphicsDevice.PresentationParameters.BackBufferWidth,
                                       graphicsDevice.PresentationParameters.BackBufferHeight);
GraphicsDevice.SetRenderTarget(rt);
//Draw sprites
GraphicsDevice.SetRenderTarget(null);
//Then draw rt (also a Texture2D) with 50% opacity. For example:
spriteBatch.Begin();
spriteBatch.Draw(rt, Vector2.Zero, Color.FromArgb(128, Color.White));
spriteBatch.End();
0 голосов
/ 29 января 2011

Первое, что напомнили мне ваши примеры изображений, это проблема «буфера глубины и полупрозрачных поверхностей».

В 3D-игре вы должны сортировать ваши полупрозрачные поверхности сзади-спереди и рисовать только ихпосле рендеринга остальной части вашей сцены - все с включенным углубленным чтением и письмом.Если вы этого не сделаете, у вас получится изображение 3 rd , когда вы обычно хотите, чтобы ваше изображение 2 nd было прозрачным поверх стекла того, что находится за ним.

Но вы хотите изображение 3 rd - с некоторыми прозрачными поверхностями, скрывающими другие - так что вы можете просто сознательно вызвать эту проблему глубины!

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

Для достиженияв XNA 4.0 вам нужно передать SpriteBatch.Begin DepthStencilState с DepthBufferFunction, установленным на CompareFunction.Less (по умолчанию оно меньше или равно) и DepthBufferEnable и DepthBufferWriteEnable установлено в true.

Могут быть взаимодействия с параметром layerDepth спрайта (я не могу вспомнить, как он отображается на глубину по умолчанию).

Вы можете такженеобходимо использовать BasicEffect в качестве шейдера для пакета спрайтов - в частности, чтобы вы могли установить проектионная матрица с соответствующими ближними и дальними плоскостями. Эта статья объясняет, как это сделать.И вам также может потребоваться очистить буфер глубины перед раздачей.

Наконец, вам нужно нарисовать свои спрайты в правильном порядке - сначала с необработанным спрайтом.

Я не полностью уверен, что это будет работать и будет ли это работать надежно (возможно, у вас возникнет какая-то проблема глубокой борьбы, я не уверен).Но я думаю, что стоит попробовать, учитывая, что вы можете оставить свой код рендеринга практически нормальным и просто настроить состояние рендеринга.

...