Господа ГУРУ помогите новичку в 3D отобразить поверхность.

Работа с 2D и 3D графикой, видео, звуком.

Модератор: Mikle

Alex (2112)
Начинающий
Начинающий
 
Сообщения: 11
Зарегистрирован: 05.04.2008 (Сб) 13:19

Господа ГУРУ помогите новичку в 3D отобразить поверхность.

Сообщение Alex (2112) » 05.04.2008 (Сб) 13:31

Здравствуйте.

Проблема в следующем.
Есть допустим BMP картинка. Цвет каждого пикселя - это карта высот. Он же и цвет поверхности.
Необходимо отобразить её с какого-нибудь ракурса. Чтобы видна была цветная поверхность.
Конешно желательно чтобы её можно было мышкой крутить и приближать :) Но это уже потом.

С уважением
Александр.
Картинку прикрепляю.
У вас нет доступа для просмотра вложений в этом сообщении.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 05.04.2008 (Сб) 14:53

Alex (2112)
Сверху прилеплена тема со ссылкой на книгу, где все это разжевано, и есть готовый пример именно того, что тебе нужно.
Только у тебя цвет RGB, то есть имеет три измерения, а высота - это одно измерение, можно, конечно, поставить высоту в зависимрсть от яркости, но так не делается, лучше карту высот и цветов хранить отдельно.

Alex (2112)
Начинающий
Начинающий
 
Сообщения: 11
Зарегистрирован: 05.04.2008 (Сб) 13:19

Сообщение Alex (2112) » 06.04.2008 (Вс) 12:16

Mikle писал(а):Alex (2112)
Сверху прилеплена тема со ссылкой на книгу, где все это разжевано, и есть готовый пример именно того, что тебе нужно.
Только у тебя цвет RGB, то есть имеет три измерения, а высота - это одно измерение, можно, конечно, поставить высоту в зависимрсть от яркости, но так не делается, лучше карту высот и цветов хранить отдельно.


Спасибо за ответ. Книгу скачал разбираюсь.

Хотел посоветоваться. Картинка то что я прилепил. Это снимок металла под микроскопом. Чем ближе к лампе и объективу тем ярче пиксель. Пореккомендуйте как лучше построить поверхность?
Последний раз редактировалось Alex (2112) 06.04.2008 (Вс) 15:07, всего редактировалось 1 раз.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 06.04.2008 (Вс) 14:58

Alex (2112)
Вовсе незачем было второй раз ту же картинку выкладывать.
Чем ближе к лампе и объективу тем ярче пиксель.

Это не так. Кроме того, что тут боковое освещение, металл еще имеет отражающую способность (reflection), не путать с рассеиванием (diffuse).

Alex (2112)
Начинающий
Начинающий
 
Сообщения: 11
Зарегистрирован: 05.04.2008 (Сб) 13:19

Сообщение Alex (2112) » 06.04.2008 (Вс) 15:06

Mikle писал(а):Alex (2112)
Вовсе незачем было второй раз ту же картинку выкладывать.
Чем ближе к лампе и объективу тем ярче пиксель.

Это не так. Кроме того, что тут боковое освещение, металл еще имеет отражающую способность (reflection), не путать с рассеиванием (diffuse).


Да я согласен, но я сделал это допущение, чтобы научиться строить поверхности.
Я обрыл весь форум но найти исходник для пробразования моей картинки в карту высот TGA так и не смог. А все примеры в книге используют этот формат. Как натянутьтексуту на карту высот (в примере с травой и ландшафтом) я примерно понял.
Буду очень признателен если помощешь с исходником. Преобразования моей картинки в карту высот в соответствии с тем условием что чем больше числовое значение пикселя тем выше гора. Т.е. числовое значение пикселя = его Z координате, т.е. высоте.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 06.04.2008 (Вс) 15:20

Alex (2112)
В TGA можно перевести фотошопом, только обрати внимание, что это не абы какой TGA, а именно GrayScale формат.
Кроме фотошопа есть множество других программ, да и, если разобраться с примерами из книги, то не составит труда переделать их на, например, BMP.
И еще, яркость пикселя в RGB не напрямую зависит от величины числа. Есть формулы для перевода.

Alex (2112)
Начинающий
Начинающий
 
Сообщения: 11
Зарегистрирован: 05.04.2008 (Сб) 13:19

Сообщение Alex (2112) » 08.04.2008 (Вт) 14:03

Mikle писал(а):Alex (2112)
В TGA можно перевести фотошопом, только обрати внимание, что это не абы какой TGA, а именно GrayScale формат.
Кроме фотошопа есть множество других программ, да и, если разобраться с примерами из книги, то не составит труда переделать их на, например, BMP.
И еще, яркость пикселя в RGB не напрямую зависит от величины числа. Есть формулы для перевода.


Огромное спасибо за подсказку.

Применяю вот эту формулу яркости:
Код: Выделить всё
Y = 0,299R + 0,587G + 0,114B.
И вот этот код для преобразования в GrayScale:
Код: Выделить всё
Function GrayScale(ByVal Colr As Long) As Long
  Dim R&, G&, B&
  R = Colr Mod 256
  Colr = Colr \ 256
  G = Colr Mod 256
  Colr = Colr \ 256
  B = Colr Mod 256
  GrayScale = (77 * R + 150 * G + 28 * B) / 255
End Function


Способ применения:
Код: Выделить всё
pictureBW.PSet (I, J), RGB(GrayScale(Сolor), GrayScale(Color), GrayScale(Color))


Но осталась одна проблема которую я никак не могу решить.
Найти пример или просто кусок кода как сохранить картинку в TGA формате.
Помоги те кто нить кодом. Пытался от обратного зделать. Лажа получается.

PS: если файл TGA используется как карта высот, то разрядность цвета должна быть 16, 24 или 32 бита?

ЗЫ: Ко всем проблемам ещё добавилась та, что карта может быть 64*64. Поюзал поиск нашёл обсуждение данной проблемы и вроде как бы проблема была решена:
http://bbs.vbstreets.ru/viewtopic.php?t ... light=1024
Но я так и не нашёл в ветке рабочий кусок кода, имхо часть ссылок не работает.
А у меня карта высот соответсвует пиксельному размеру картинки т.е. 361*289. Вообще так может быть, или карта должна быть обязательно квадратной?

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 09.04.2008 (Ср) 10:31

Alex (2112)
Картинка может быть не обязательно квадратной, соответственно переделай в программе размер массива.
Обрати внимание, TGA в книге читается так:
Код: Выделить всё
  Get #nf, x + z * 64 + 19, b

То есть мы просто читаем байты, начиная с 19-го.
Можешь переделать код так:
Код: Выделить всё
  Get #nf, x + z * 64 + 1, b

А результат вычисления
Код: Выделить всё
Y = 0,299R + 0,587G + 0,114B.

Сохранить в файл с начала без заголовка (Y должен быть байтом!).

Alex (2112)
Начинающий
Начинающий
 
Сообщения: 11
Зарегистрирован: 05.04.2008 (Сб) 13:19

Сообщение Alex (2112) » 09.04.2008 (Ср) 13:49

Mikle писал(а):Alex (2112)
Картинка может быть не обязательно квадратной, соответственно переделай в программе размер массива.
Обрати внимание, TGA в книге читается так:
Код: Выделить всё
  Get #nf, x + z * 64 + 19, b

То есть мы просто читаем байты, начиная с 19-го.
Можешь переделать код так:
Код: Выделить всё
  Get #nf, x + z * 64 + 1, b

А результат вычисления
Код: Выделить всё
Y = 0,299R + 0,587G + 0,114B.

Сохранить в файл с начала без заголовка (Y должен быть байтом!).


Спасибо! Всё работает.

ЗЫ: при попытке изменить размер массива на 361 * 361 получаю оуверфлоу (переполнение) :). Использую 8-й пример из кники.
Переполение вызвано тем что применяется пользовательский тип данных:
Код: Выделить всё
Dim Vert(360 * 288 - 1) As vFormat

а как известно его объём не может привышать 64 кб, а у меня массив получается на 102 кб. А как переписать не заню :(
Проблема ещё в том что в книге используется карта 64*64 и далее по коду не совсем понятно где 64 - х а где 64 - y.

Если учесть что прлепленный файл - это снимок под микроскопом металла. Есть ли какие либо методы преобразования плоского изображения в карту высот. Я применяю метод по яркости пикселя. Может есть другие более точные методы.??? Ведь как то делают 3-х мерные изображения луны марса. По 2-х мерным снимкам со спутника.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 10.04.2008 (Чт) 14:50

Alex (2112)
Код: Выделить всё
360& * 288 - 1

И переполнения не будет :lol:
Есть ли какие либо методы преобразования плоского изображения в карту высот

Однозначно точного метода нет и быть не может. Можно сделать достаточно близкое приближение, если иметь несколько снимков с разной позицией источника света. И то, самозатенение будет мешать.
Ты бы описал задачу по-подробнее, может и решение отыщется.

Alex (2112)
Начинающий
Начинающий
 
Сообщения: 11
Зарегистрирован: 05.04.2008 (Сб) 13:19

Сообщение Alex (2112) » 10.04.2008 (Чт) 15:08

Mikle писал(а):Alex (2112)
Код: Выделить всё
360& * 288 - 1

И переполнения не будет :lol:
Есть ли какие либо методы преобразования плоского изображения в карту высот

Однозначно точного метода нет и быть не может. Можно сделать достаточно близкое приближение, если иметь несколько снимков с разной позицией источника света. И то, самозатенение будет мешать.
Ты бы описал задачу по-подробнее, может и решение отыщется.


Спасибо за помощь.
Если честно так и не понял как влияет
Код: Выделить всё
&
на переполение. Очень хотелось бы узнать.
У тебя есть ICQ я бы постучался и всё объяснил. Чтобы не захламлять форум. :)

Вот что у меня получается.
Код: Выделить всё
Private Sub InitGeometry()
Dim x As Long, z As Long, nf As Integer, b As Byte
Dim v As D3DVECTOR, vX As D3DVECTOR, vZ As D3DVECTOR
Dim Vert(360& * 288 - 1) As vFormat
Dim Ind(359& * 287 * 2 * 3 - 1) As Integer
  vSize = Len(Vert(0))
  numVertex = 360& * 288
  Set vBuf = d3dDevice.CreateVertexBuffer(numVertex * vSize, 0, vFlag, D3DPOOL_DEFAULT)
  nf = FreeFile
  Open "FileDat.tga" For Binary As #nf
  For z = 0 To 287
    For x = 0 To 359
      Get #nf, x + z * 288 + 19, b
      Vert(x + z * 288) = Vertex(x - 31.5, b * 0.05, z - 31.5, &H808080)
    Next x
  Next z
  Close #nf
  D3DVertexBuffer8SetData vBuf, 0, numVertex * vSize, 0, Vert(0)

  numTri = 360& * 288 * 2
  numIndex = numTri * 3
  Set iBuf = d3dDevice.CreateIndexBuffer(numIndex * 2, 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT)
  For z = 0 To 288 - 2
    For x = 0 To 360 - 2
      Ind((z * 287& + x) * 2 * 3 + 0) = (z + 0) * 288& + x + 0
      Ind((z * 287& + x) * 2 * 3 + 1) = (z + 1) * 288& + x + 0
[b]      Ind((z * 287& + x) * 2 * 3 + 2) = (z + 1) * 288& + x + 1[/b]
      Ind((z * 287& + x) * 2 * 3 + 3) = (z + 0) * 288& + x + 0
      Ind((z * 287& + x) * 2 * 3 + 4) = (z + 1) * 288& + x + 1
      Ind((z * 287& + x) * 2 * 3 + 5) = (z + 0) * 288& + x + 1
    Next x
  Next z
  D3DIndexBuffer8SetData iBuf, 0, numIndex * 2, 0, Ind(0)
End Sub


В выделенной строке вылезает математическое переполнение. Хотя размерность массива
Код: Выделить всё
IND
в разы больше. чем индексное произведение переменных.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 10.04.2008 (Чт) 15:28

Alex (2112)
Можно в личку написать, аськой не пользуюсь.
А можно, если это объяснение задачи, и тут. Я не один тут умею на вопросы отвечать, просто остальные, что-то , прячутся :D
В выделенной строке переполняестя уже само Integer значение массива Ind(), поменяй его тип на Long. Соответственно нужно поменять и тип индексного буфера в Direct3D, как конкретно - сейчас не могу написать, при себе нет ни VB, ни SDK.

В VB6 все целые константы, не превышающие 32767, по умолчанию считаются Integer, результат действий +, -, * над ними тоже Integer. Суффикс & обозначает, что константа типа Long, тогда и результат типа Long.

Alex (2112)
Начинающий
Начинающий
 
Сообщения: 11
Зарегистрирован: 05.04.2008 (Сб) 13:19

Сообщение Alex (2112) » 10.04.2008 (Чт) 15:49

Mikle писал(а):Alex (2112)
Можно в личку написать, аськой не пользуюсь.
А можно, если это объяснение задачи, и тут. Я не один тут умею на вопросы отвечать, просто остальные, что-то , прячутся :D
В выделенной строке переполняестя уже само Integer значение массива Ind(), поменяй его тип на Long. Соответственно нужно поменять и тип индексного буфера в Direct3D, как конкретно - сейчас не могу написать, при себе нет ни VB, ни SDK.

В VB6 все целые константы, не превышающие 32767, по умолчанию считаются Integer, результат действий +, -, * над ними тоже Integer. Суффикс & обозначает, что константа типа Long, тогда и результат типа Long.


Не знал эту тонкость про Integer.
Да вроде карта моя относительно заработала. Буду пробовать натянуть текстуру.

При записи в TGA файл пиксели картинки нужно читать в таком порядке и класть последовательно в файл начиная с 19-го байта?

Код: Выделить всё
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 028 029 029
021 022 023 -> ... и т.д. до конца.


А суть задачи просто. Снимок под микроскопом болта после испытания на разрыв. Необходимо в самой верхней точке разрыва понять её структуру. 3-х мерную с текстурой.
Вот и занимаюсь. :(

Не могу переписать никак теперь окраску вертексов.

Код: Выделить всё
  For z = 0 To 287
    For x = 0 To 359
      vX = vec3(2, Vert(((x - 1) And 359) + z * 288).Pos.y - Vert(((x + 1) And 359) + z * 288).Pos.y, 0)
     [b] vZ = vec3(0, Vert(x + ((z - 1) And 359) * 288).Pos.y - Vert((x + ((z + 1) And 359) * 288)).Pos.y, 2)[/b]      D3DXVec3Cross v, vX, vZ
      D3DXVec3Normalize v, v
      If v.x > 0 Then
        Vert(x + z * 288).Color = Int(v.x * 255) * &H10101
      Else
        Vert(x + z * 288).Color = 0
      End If
    Next x
  Next z


Всё вроде ровно но в выделенной строке переполнение.

И ещё трабл в том что размер карты теперь нереального рамера. Очень тормозит и прорисовывается кусками. Можно как то её пропорционально уменьшить. ??? Чтобы влезала в масштабы экрана.


Вернуться в Мультимедиа

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

    TopList