
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[34.239.152.207] |
![]() |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Есть ландшафт, построенный на карте высот. Его нужно текстурирование: снег/трава/камни. Пытаюсь понять Volume Texture(может есть более лучший вариант?), возникли вопросы: как правильно вычислить уровень w и координаты u и v текстуры для полигона. Если с уровнем w немного понятно: 0 - камни, 1 - трава и 2 - снег.
![]() ![]() if( (height) < 42.5f ) w = 0; else if( (height) < 205.0f ) w = 1; else w = 2; Если добавить переходы, то число уровней возрастет в несколько раз, то все равно нужно будет вручную вычислять высоты для каждого уровня? Как правильно вычислить координаты текстуры? В Volume Texture уровни смешиваются? От этого результат не пострадает? Terrain.7z |
![]() |
Сообщ.
#2
,
|
|
Цитата В Volume Texture уровни смешиваются? Если включить мипфильтр, то смешиваются, то есть между травой и камнями, например, будет плавная граница. Для этого лучше убрать блок if, и просто умножать height на подобранную константу. |
Сообщ.
#3
,
|
|
|
Цитата Mikle @ умножать height на подобранную константу Можно поподробнее? Добавлено Для загрузки текстур в уровни использовать D3DXCreateVolumeTextureFromFileEx? |
![]() |
Сообщ.
#4
,
|
|
Зачем вообще зашивать в вертекс текстурные координаты, если у нас регулярная сетка?
Получаем U, умножая X на KU: U=X*KU соответственно остальные: V=Z*KV W=(Y-MinY)*KW Всё это в шейдере. KU, KV, DW и KW - константы. Чем больше KU и KV - тем мельче текстура (чаще повторяется). KW=1/(MaxY-MinY) MinY и MaxY - минимальная и максимальная высота. D3DSAMP_ADDRESSW лучше сделать равным D3DTADDRESS_MIRROR или D3DTADDRESS_CLAMP. Цитата Для загрузки текстур в уровни использовать D3DXCreateVolumeTextureFromFileEx? Почему нет, если у тебя есть готовый DDS с набором текстур? Если нет - грузим каждую текстуру самостоятельно, потом Lock - и перенос в Volume. |
Сообщ.
#5
,
|
|
|
Mikle, текстуры в разных dds. Как это без вшивания в вершину? Хоть и в моем проекты я не вшивал, но другому способу текстурирования я не знаю
![]() |
![]() |
Сообщ.
#6
,
|
|
insolent
Если возможности шейдеров, вплоть до PS1_3 включительно, ПОЧТИ полностью можно повторить на FFP, то PS1_4, а тем более PS2_0 и выше, уже на FFP не сымитируешь. Примерно то же с вертексными шейдерами, только там бОльшая гибкость была уже даже в VS1_0. Пора переходить на шейдеры ![]() |
Сообщ.
#7
,
|
|
|
ОМГ! Мне, пока, хотя бы с обыкновенным разобраться, а уже за шейдеры браться(Я учусь по книге Луна и шейдеры там на последок). Я же могу при генерации вершин так же вычислять координаты для текстуры или, как вы мне объяснили только для всего полигона? А в каких пределах брать KU, KV, DW и KW. + нужно разобраться в VolumeTexture
|
![]() |
Сообщ.
#8
,
|
|
Можно вычислить текстурные координаты и при создании вертексного буфера, только это бкдет не две, а три координаты на вершину. Вычислять по той же формуле, KU и KV для начала поставь =1, потом будешь вручную подбирать, откуда брать KW - я написал, DW там нет, это я лишнюю константу скопипастил
![]() Цитата insolent @ вычислять координаты для текстуры или, как вы мне объяснили только для всего полигона? Вопрос непонятен - текстурные координаты вычисляют не для текстуры и не для полигона, а для каждого вертекса. |
Сообщ.
#9
,
|
|
|
Mikle, вот моя структура вершины:
![]() ![]() struct TerrainVertex { // Описываем структуру для хранения данных вершин // и приводим описание настраивамого формата вершин для этой структуры // Структура вершин содержит только информацию о // местоположении вершины и текстуре TerrainVertex(){} TerrainVertex(float x, float y, float z, float u, float v, float w) { _x = x; _y = y; _z = z; _u = u; _v = v; _w = w; } float _x, _y, _z; float _u, _v, _w; // координаты текстуры static const DWORD FVF; }; const DWORD Terrain::TerrainVertex::FVF = D3DFVF_XYZ | D3DFVF_TEX1; Вот моя процедура вычисления вершин: ![]() ![]() HRESULT hr = 0; hr = _device->CreateVertexBuffer( _NumVertices * sizeof(TerrainVertex), D3DUSAGE_WRITEONLY, TerrainVertex::FVF, D3DPOOL_MANAGED, &_vb, 0); if(FAILED(hr)) return false; // Координаты, с которых начинается генерация вершин int startX = -_Width / 2; int startZ = _Depth / 2; // Координаты, на которых завершается генерация вершин int endX = _Width / 2; int endZ = -_Depth / 2; float KW = 1/(MaxY-MinY); float KU = 1; float KV = 1; float U=X*KU; float V=Z*KV; float W=(Y-MinY)*KW; TerrainVertex* v = 0; _vb->Lock(0, 0, (void**)&v, 0); int i = 0; for(int z = startZ; z >= endZ; z -= _CellSpacing) { int j = 0; for(int x = startX; x <= endX; x += _CellSpacing) { // Вычисляем правильный индекс в буфер вершин // и карты высот на основании счетчиков вложенных циклов int index = i * _NumVertsPerRow + j; v[index] = TerrainVertex( (float)x, (float)_Heightmap[index], (float)z, (float)U, (float)V, (int)W); j++; // Следующий столбец } i++; // Следующая строка } _vb->Unlock(); |
![]() |
Сообщ.
#10
,
|
|
Цитата insolent @ FVF = D3DFVF_XYZ | D3DFVF_TEX1; Для Volume нужно ещё D3DFVF_TEXCOORDSIZE указывать. |
Сообщ.
#11
,
|
|
|
Так как я так и не понял, как загружать на каждый уровень текстуру я в DirectX Texture Tool создал текстуру из 3 уровней и загружал в программе.
![]() ![]() Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); //Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); Device->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 ); Device->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); Device->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); Device->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_MODULATE2X ); Device->SetSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_MIRROR); Текстура налаживается по идиотски, смешиваются + Нужно что-то добавить в ф-лу W=(Y-MinY)*KW, т.к. у меня макс. высота - 255 и на другие уровни оно плохо переходит. ![]() |
![]() |
Сообщ.
#12
,
|
|
Что-то не правильно...
Ты правильно понял, тут X, Y и Z - координаты (позиция) вертекса, а не индексы: ![]() ![]() U=X*KU V=Z*KV W=(Y-MinY)*KW KW=1/(MaxY-MinY) Дай весь код генерации вертексного и индексного буферов. |
Сообщ.
#13
,
|
|
|
Mikle, вот:
![]() ![]() bool Terrain::ComputeVertices() { HRESULT hr = 0; hr = _device->CreateVertexBuffer( _NumVertices * sizeof(TerrainVertex), D3DUSAGE_WRITEONLY, TerrainVertex::FVF, D3DPOOL_MANAGED, &_vb, 0); if(FAILED(hr)) return false; // Координаты, с которых начинается генерация вершин int startX = -_Width / 2; int startZ = _Depth / 2; // Координаты, на которых завершается генерация вершин int endX = _Width / 2; int endZ = -_Depth / 2; float KW = 1.0/(float)(_MaxY-_MinY); float KU = 1.0; float KV = 1.0; // Вычисляем приращение координат текстуры // при переходе от одной вершины к другой //float uCoordIncrementSize = 1.0f / (float)_NumCellsPerRow; //float vCoordIncrementSize = 1.0f / (float)_NumCellsPerCol; TerrainVertex* v = 0; _vb->Lock(0, 0, (void**)&v, 0); int i = 0; for(int z = startZ; z >= endZ; z -= _CellSpacing) { int j = 0; for(int x = startX; x <= endX; x += _CellSpacing) { // Вычисляем правильный индекс в буфер вершин // и карты высот на основании счетчиков вложенных циклов int index = i * _NumVertsPerRow + j; float U=x*KU; float V=z*KV; float W=(float)(_Heightmap[index]-_MinY)*KW*2.0; v[index] = TerrainVertex( (float)x, (float)_Heightmap[index], (float)z, (float)U, (float)V, ceil(W)); j++; // Следующий столбец } i++; // Следующая строка } _vb->Unlock(); return true; } bool Terrain::ComputeIndices() { HRESULT hr = 0; hr = _device->CreateIndexBuffer( _NumTriangles * 3 * sizeof(WORD), // 3 индекса на треугольник D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &_ib, 0); if(FAILED(hr)) return false; WORD* indices = 0; _ib->Lock(0, 0, (void**)&indices, 0); // Индекс, с которого начинается группа из 6 индексов, // описывающая два треугольника, образующий квадрат int baseIndex = 0; // В цикле вычисляется треугольник для каждого квадрата for(int i = 0; i < _NumCellsPerCol; i++) { for(int j = 0; j < _NumCellsPerRow; j++) { indices[baseIndex] = i * _NumVertsPerRow + j; indices[baseIndex + 1] = i * _NumVertsPerRow + j + 1; indices[baseIndex + 2] = (i+1) * _NumVertsPerRow + j; indices[baseIndex + 3] = (i+1) * _NumVertsPerRow + j; indices[baseIndex + 4] = i * _NumVertsPerRow + j + 1; indices[baseIndex + 5] = (i+1) * _NumVertsPerRow + j + 1; // Следующий квадрат baseIndex += 6; } } _ib->Unlock(); return true; } W я ещё умножаю на 2, т.к. без умножения, вообще, одна текстура - результат смешивания всех уровней Вот процедура загрузки текстуры: ![]() ![]() bool Terrain::LoadTexture(std::string fileName) { HRESULT hr = 0; /*hr = D3DXCreateTextureFromFile( _device, fileName.c_str(), &_tex);*/ hr = D3DXCreateVolumeTextureFromFile( _device, fileName.c_str(), &_tex); if(FAILED(hr)) return false; return true; } |
![]() |
Сообщ.
#14
,
|
|
insolent
Не вижу ошибок... Что это: ![]() ![]() ceil(W)); |
Сообщ.
#15
,
|
|
|
Mikle, ceil. Может, я не правильно текстуру делаю, вы можете показать, как вручную загружать текстуры в volume texture.
ЗЫЖ а какие могут быть варианты такое плохого смешивания и наложения текстуры? |