|
С# Средство разработки на платформе .Net |
26.03.2011, 18:00
|
#1
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Рисование примитивов XNA
Привет!
У меня возникла проблема с коректной отрисовкой примитивов, а точнее полигональной сеткой:
На рисунках видно не коректную работу AlphaBlending... И еще неверное количество отрисованых треугольников...
Вот код метода построения полигональной сетки:
public Vector3 Initialize3DMesh(int width, int height, int depth)
{
vertexDeclaration = new VertexDeclaration(GraphicsDevice, VertexPositionTexture.VertexElements);
pointListNX = new VertexPositionTexture[depth * 2 * 2];
pointListNY = new VertexPositionTexture[width * 2 * 2];
pointListNZ = new VertexPositionTexture[height * 2 * 2];
for (int ny = 0; ny < depth; ny++)
{
for (int nx = 0; nx < 2; nx++)
{
for (int nz = 0; nz < 2; nz++)
{
pointListNX[(ny * 4) + (nx * 2) + nz] = new VertexPositionTexture(new Vector3((float)nx, (float)(1.0f / depth) * ny, (float)nz), new Vector2((float)nx, (float)nz));
}
}
}
for (int nx = 0; nx < width; nx++)
{
for (int ny = 0; ny < 2; ny++)
{
for (int nz = 0; nz < 2; nz++)
{
pointListNY[(nx * 4) + (ny * 2) + nz] = new VertexPositionTexture(new Vector3((float)(1.0f / width) * nx, (float)ny, (float)nz), new Vector2((float)ny, (float)nz));
}
}
}
for (int nz = 0; nz < height; nz++)
{
for (int nx = 0; nx < 2; nx++)
{
for (int ny = 0; ny < 2; ny++)
{
pointListNZ[(nz * 4) + (nx * 2) + ny] = new VertexPositionTexture(new Vector3((float)nx, (float)ny, (float)(1.0f / height) * nz), new Vector2((float)nx, (float)ny));
}
}
}
triangleStripIndicesNX = LayerBank(depth);
triangleStripIndicesNY = LayerBank(width);
triangleStripIndicesNZ = LayerBank(height);
return new Vector3(width, height, depth);
}
private int[] LayerBank(int numberLayers)
{
int[] triangleStripIndices = new int[numberLayers * 4];
for (int y = 0; y < numberLayers; y++)
{
for (int i = 0; i < 4; i++)
{
triangleStripIndices[(y * 4) + i] = (y * 4) + i;
}
}
return triangleStripIndices;
}
Припустим я создаю полигональную сетку 4 х 4 х 4:
protected override void LoadContent()
{
VolumeMesh = Initialize3DMesh(4, 4, 4);
}
Все по ходу работает нормально:
Ну и естественно подходим к блоку Draw:
protected override void Draw(GameTime gameTime)
{
InitializeTransform(0, rotY, 0);
GraphicsDevice.Clear(Color.DarkBlue);
GraphicsDevice.VertexDeclaration = vertexDeclaration;
GraphicsDevice.RenderState.FillMode = FillMode.Solid;
GraphicsDevice.RenderState.CullMode = CullMode.None;
effect.Parameters["WorldViewProj"].SetValue(worldViewProj);
effect.CurrentTechnique = effect.Techniques["BasicView"];
GraphicsDevice.RenderState.AlphaBlendEnable = true;
GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
DrawTriangleStrip(VolumeMesh);
base.Draw(gameTime);
}
private void DrawTriangleStrip(Vector3 sizes)
{
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
for (int nx = 0; nx < sizes.Y; nx++)
{
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(
PrimitiveType.TriangleStrip,
pointListNX,
nx * 4, // vertex buffer offset to add to each element of the index buffer
4, // number of vertices to draw
triangleStripIndicesNX,
nx * 4, // first index element to read
2 // number of primitives to draw
);
}
for (int ny = 0; ny < sizes.X; ny++)
{
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(
PrimitiveType.TriangleStrip,
pointListNY,
ny * 4, // vertex buffer offset to add to each element of the index buffer
4, // number of vertices to draw
triangleStripIndicesNY,
ny * 4, // first index element to read
2 // number of primitives to draw
);
}
for (int nz = 0; nz < sizes.Z; nz++)
{
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(
PrimitiveType.TriangleStrip,
pointListNZ,
nz * 4, // vertex buffer offset to add to each element of the index buffer
4, // number of vertices to draw
triangleStripIndicesNZ,
nz * 4, // first index element to read
2 // number of primitives to draw
);
}
pass.End();
}
effect.End();
}
Функция пиксель шейдера:
return float4(1,1,1,0.1f);
В принципе DrawTriangleStrip() Должен рисовать 4 х 4 х 4 слоя в сетке. А он рисует 2 х 2 х 2...
Почему так?
И как исправить плохой AlphaBlending???
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
26.03.2011, 18:11
|
#2
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Рисование примитивов XNA
полигоны надо сортировать от дальних к ближним, чтобы альфа работала
учитывая что они у тебя пересекаются все друг другом... то придётся изначально в геометрии каждый разделить на кучу маленьких полигонов, полученных при пересечениях и сортировать уже их
либо авось сойдёт просто сортировать и рендерить без записи Z
|
(Offline)
|
|
26.03.2011, 18:38
|
#3
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Рисование примитивов XNA
Я бы попробовал выключить zwrite и рисовать в два прохода - сначала внутренние грани, потом наружные.
|
(Offline)
|
|
26.03.2011, 22:54
|
#4
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Рисование примитивов XNA
Сообщение от Mr_F_
полигоны надо сортировать от дальних к ближним, чтобы альфа работала
учитывая что они у тебя пересекаются все друг другом... то придётся изначально в геометрии каждый разделить на кучу маленьких полигонов, полученных при пересечениях и сортировать уже их
либо авось сойдёт просто сортировать и рендерить без записи Z
|
1. А как сортировать полигоны? Ти имееш в виду, чтоб DrawTriangleStrip() Отрисововала в первую очередь полигодны которие поближе к камере?? Или ето надо чото с шейдером сделать...?
2. А как ето без записи Z???
Сообщение от pax
Я бы попробовал выключить zwrite и рисовать в два прохода - сначала внутренние грани, потом наружные.
|
Как выключить zwrite?? И на счет граней - Использовать:
GraphicsDevice.RenderState.CullMode = CullMode.CullClockwiseFace;
GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
???
Как решить проблему с неверной отрисовкой полигонов?
Когда я попробовал сделать так:
private void DrawTriangleStrip(Vector3 sizes)
{
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
for (int nx = 0; nx < sizes.Y; nx++)
{
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(
PrimitiveType.TriangleStrip,
pointListNX,
nx * 4, // vertex buffer offset to add to each element of the index buffer
4, // number of vertices to draw
triangleStripIndicesNX,
nx, // first index element to read
4 // number of primitives to draw
);
}
for (int ny = 0; ny < sizes.X; ny++)
{
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(
PrimitiveType.TriangleStrip,
pointListNY,
ny * 4, // vertex buffer offset to add to each element of the index buffer
4, // number of vertices to draw
triangleStripIndicesNY,
ny, // first index element to read
4 // number of primitives to draw
);
}
for (int nz = 0; nz < sizes.Z; nz++)
{
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionTexture>(
PrimitiveType.TriangleStrip,
pointListNZ,
nz * 4, // vertex buffer offset to add to each element of the index buffer
4, // number of vertices to draw
triangleStripIndicesNZ,
nz, // first index element to read
4 // number of primitives to draw
);
}
pass.End();
}
effect.End();
}
Оно отрисовало верное количество полигонов, но нарисовало и много лишнего:
Что здесь не так я не понимаю... Прежняя версия DrawTriangleStrip() на мой взгляд правильная, но неправильно работает... Посоветуйте мне что нибудь на счет етого...
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
26.03.2011, 23:02
|
#5
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Рисование примитивов XNA
Сообщение от ІГРОГРАЙКО
2. А как ето без записи Z???
|
когда ты пишешь Z - у тебя передняя геометрия не дает отрисоваться геометрии, которая дальше. вот и проблема на твоем первом скриншоте.
UPD: может тут про сорировку найдешь что-то полезное.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
27.03.2011, 00:33
|
#6
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Рисование примитивов XNA
Благодарю тебя PAX за хорошие советы!
Дело в том что я на ету полигональную сетку буду клеить 3Д текстуру, так как метод предложеный в VolumeRayCasting_101 - 202 мне не подходит. А с полигональной сеткой работает:
Код шейдера выглядит:
float4x4 WorldViewProj;
texture3D Volume;
sampler3D SVolume = sampler_state
{
Texture = <Volume>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = LINEAR;
};
struct VS_INPUT
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float4 pos : TEXCOORD1;
};
VS_OUTPUT PositionVS(VS_INPUT input)
{
VS_OUTPUT output;
output.Position = mul(input.Position, WorldViewProj);
output.TexCoord = input.TexCoord;
output.pos = input.Position;
return output;
}
float4 PixelShaderFunction(VS_OUTPUT input) : COLOR0
{
float4 outColor = tex3D(SVolume,input.pos);
return outColor * float4(1,1,1,0.2f);
}
technique BasicView
{
pass Pass1
{
// TODO: set renderstates here.
VertexShader = compile vs_1_1 PositionVS();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}
Но ети проблемы с отрисовкой полигонов меня затормозили
...Если камеру опустить пониже:
Видно неудавшиеся попытки отрисоватса следующим слоям после первого... А ето никуда не годится!
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
27.03.2011, 17:54
|
#7
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Рисование примитивов XNA
Я пробовал отключать Z - buffer вот результат:
GraphicsDevice.RenderState.DepthBufferWriteEnable = true;
GraphicsDevice.RenderState.DepthBufferWriteEnable = false;
Постоянно изменяется последовательность отображаемых слоёв. Вернее не последовательность, а приоритет отображения (один момент все хорошо, второй - видима часть внутрених слоёв, третий - задних и т. д. в произвольном порядке) Как ето можно исправить?
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
27.03.2011, 19:35
|
#8
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Рисование примитивов XNA
Сортировка тебя спасет
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
05.04.2011, 00:55
|
#9
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Рисование примитивов XNA
Привет!
Посмотрел что такое BSP и решыл отказатса от доработки подобной полигональной сетки...
Но увидил другую!
На вид оч проста. Но как ее зделать не знаю
Вот:
Как можна оптимально сделать последовательность полигонов внутри бокса, так чтобы все полигоны отрисововались перпендикулярно к камере??
Помогите пожалуйста!
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
05.04.2011, 10:26
|
#10
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Рисование примитивов XNA
Сообщение от ІГРОГРАЙКО
Как можна оптимально сделать последовательность полигонов внутри бокса, так чтобы все полигоны отрисововались перпендикулярно к камере??
|
Не вижу на скриншоте перпендикулярных экрану полигонов. Куб разбит "перпендикулярными" экрану плоскостями, но полигоны имеют те же нормали что и у исходного куба.
|
(Offline)
|
|
05.04.2011, 16:33
|
#11
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Рисование примитивов XNA
Сообщение от pax
Не вижу на скриншоте перпендикулярных экрану полигонов. Куб разбит "перпендикулярными" экрану плоскостями, но полигоны имеют те же нормали что и у исходного куба.
|
Эсли я понял то что ты хотел сказать, то ты РАХ не прав. Если ето всего навсего разбиение граней Бокса плоскостями, то 3Д текстура внутри бокса бы не отрисовалась (не было бы на чём).
Но суть не в етом.
Меня больше всего беспокоит как релизовать постоянное перестроение етих "плоскостей" или полигонов, как вам удобней, ограниченых гранями бокса при передвижении камеры. Ето что придетса перетаскивать каждую точку каждого полигона в определенное место что вычисляетса какой то страшной матиматической формулой?
Помогите! Пишите все что придет на ум...
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
05.04.2011, 16:55
|
#12
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Рисование примитивов XNA
Так у тебя же вроде не полуичлось создать 3d текстуру? как ты планируешь на такие плигоны, ориентированные на камеру свою текстуру/текстуры вешать.
Я предположил, что ты хочешь разбить свою модель на части и отсортировать их. Значит я ошибся и не так понял, т.к. по скриншоту понятно не было.
Если бы я сам хотел решить такую задачу, то я бы поступил следующим образом:
1. Задал бы расстояние мужду плоскостями.
2. Для каждой грани имеющихся полигонов посчитал точки, лежащие на гранях, соответствующие шагам плоскостей.
3. Объединил бы все найденные точки в группы по удаленности и составил бы для каждой группы новые полигоны.
4. Вместе с этим делом надо было бы считать uvw с трехмерной текстуры.
5. Далее отрисовка.
Но сначала я бы погуглил и поискал алгоритмы, релизующие такой принцип.
Последний раз редактировалось pax, 05.04.2011 в 19:42.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
05.04.2011, 20:42
|
#13
|
ПроЭктировщик
Регистрация: 20.06.2009
Адрес: Україна
Сообщений: 152
Написано 10 полезных сообщений (для 24 пользователей)
|
Ответ: Рисование примитивов XNA
Сообщение от pax
Так у тебя же вроде не полуичлось создать 3d текстуру? как ты планируешь на такие плигоны, ориентированные на камеру свою текстуру/текстуры вешать.
Я предположил, что ты хочешь разбить свою модель на части и отсортировать их. Значит я ошибся и не так понял, т.к. по скриншоту понятно не было.
|
Получилось рах Я использую класс Texture3D и функицию в шейдере tex3D(), но только без лишних вычислений (т.е. не делаю никакой выборки из симплера).
Спасибо за совет!
Дело в том, что я не знаю как називаетса такой тип построения полигональной сетки. Но если найду, сам выкладу и распишу все как надо...
Есть чёто похожое но не то: http://www.xnadev.ru/articles.php?article_id=12
Тем кто знает больше - пишите! Не стесняйтесь..
__________________
Blitz3D, XNA, WebGL, OpenGL, Unity3D
PC: ASUS A55VM Core i3 (2.4Ghz), 6 Gb RAM, Nvidia GF 630M GT 2Gb
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 17:12.
|