Vasara Posted October 5, 2020 Share Posted October 5, 2020 (edited) Резюмирую то, что освоил. Надеюсь новичкам поможет. Движок поддерживает 20 масок, в которые уже добавляются детали (1024 если не ошибаюсь). Хранилище масок поделено на 5 блоков. В каждый блок складывается четырёх канальная картинка RGBA, получаем 5 * 4 = 20 масок. Все маски нужно инициализировать во время генерации файла lmap, тогда же, когда добавляем данные альбедо и высот. Tо есть в метод: OnCreatorCreate(Unigine::LandscapeMapFileCreatorPtr creator, Unigine::LandscapeImagesPtr images, int x, int y) Для каждого блока инициализируется отдельный массив данных! getMask(индекс блока) copy(картинка откуда берутся данные, канал где лежит маска, канал картинки откуда берём данные) getMask(1)->copy(sourceImage, 1, 2) Получаем первый блок, который хранит маски с пятой по девятую. Первый канал(G), в котором лежит шестая маска. Присваиваем второй канал(В) картинки, из который забираем пиксели: { ImagePtr newImage; newImage = Image::create(); newImage->create2DArray(4096, 4096, 1, Image::FORMAT_RGBA8); Image::Pixel pixel; for (int sourceY = 0; sourceY < 4096; sourceY++) { for (int sourceX = 0; sourceX < 4096; sourceX++) { pixel.i.r = 255; pixel.i.g = 0; pixel.i.b = 0; pixel.i.a = 0; newImage->set2DArray(sourceY, sourceX, 0, pixel); } } ImagePtr mask = Image::create(); mask->load("source/sourceRGBA.dds"); images->getMask(0)->create2DArray(lmapTileResolutionX, lmapTileResolutionY, 1, Image::FORMAT_RGBA8); images->getMask(0)->copy(mask, 0, 0); images->getOpacityMask(0)->create2DArray(lmapTileResolutionX, lmapTileResolutionY, 1, Image::FORMAT_RGBA8); images->getOpacityMask(0)->copy(newImage, 0, 0); images->getMask(0)->copy(mask, 1, 1); images->getOpacityMask(0)->copy(newImage, 1, 0); images->getMask(0)->copy(mask, 2, 2); images->getOpacityMask(0)->copy(newImage, 2, 0); images->getMask(0)->copy(mask, 3, 3); images->getOpacityMask(0)->copy(newImage, 3, 0); images->getMask(1)->create2DArray(lmapTileResolutionX, lmapTileResolutionY, 1, Image::FORMAT_RGBA8); images->getMask(1)->copy(mask, 0, 0); images->getOpacityMask(1)->create2DArray(lmapTileResolutionX, lmapTileResolutionY, 1, Image::FORMAT_RGBA8); images->getOpacityMask(1)->copy(newImage, 0, 0); images->getMask(1)->copy(mask, 1, 1); images->getOpacityMask(1)->copy(newImage, 1, 0); images->getMask(1)->copy(mask, 2, 2); images->getOpacityMask(1)->copy(newImage, 2, 0); images->getMask(1)->copy(mask, 3, 3); images->getOpacityMask(1)->copy(newImage, 3, 0); } Надеюсь ничего не упустил. Большое спасибо danvern за оперативную помощь. -------------------------------------------------------------------------------- Добрый день. Не могли бы вы помочь с добавлением маски к террейну. Загружается террейн: lmap = LandscapeLayerMap::create(); lmap->setParent(Landscape::getActiveTerrain()); lmap->setPath(lmapName); lmap->setName(lmapName.get()); lmap->setSize(Math::Vec2(4096,4096)); lmap->setHeightScale(1.0f); lmap->setWorldPosition(Math::Vec3::ZERO); lmap->setWorldRotation(Math::quat(Math::vec3::UP, 45.0f)); Создаётся и описывается маска: TerrainDetailMaskPtr maskDetail; //Код... TerrainDetailPtr detailTerrain; detailTerrain->setDetailMask(maskDetail); А как detailTerrain к террейну применить? С Уважением Константин. П.С. Если позволит время, сделайте пожалуйста небольшой пример для карты 2х2 тайла создание маски, присвоение маске картинки, записи маски в файл карты. Edited October 11, 2020 by Vasara Link to comment
danvern Posted October 6, 2020 Share Posted October 6, 2020 Здравствуйте, маски назначаются на активный ObjectLandscapeTerrain, который можно получить тут Landscape::getActiveTerrain() auto mask = Landscape::getActiveTerrain()->getDetailMask(0); auto detail = mask->addDetail(); //setup detail и ObjectLandscapeTerrain должен быть в мире 18 hours ago, Vasara said: А как detailTerrain к террейну применить? Детейлы автоматически начнут работать Link to comment
Vasara Posted October 6, 2020 Author Share Posted October 6, 2020 падает с ошибкой доступа, видимо я чтото не понимаю до конца: auto mask = Landscape::getActiveTerrain()->getDetailMask(0); auto detail = mask->addDetail(); auto tempImage = Image::create(); tempImage->create2DArray(4096, 4096, 1, Image::FORMAT_RGBA8); if (FileSystem::isFileExist("landscape_grafic_assets/mask_assets/sand/sand.dds")) { tempImage->load("landscape_grafic_assets/mask_assets/sand/sand.dds"); } else { Log::error("Image file does not exist or corrupted. Please create image file first\n"); } auto material = Material::create(); material->setTextureImage(0, tempImage); detail->setMaterial(material); Link to comment
danvern Posted October 6, 2020 Share Posted October 6, 2020 26 minutes ago, Vasara said: auto material = Material::create(); вот тут нужно не просто создать материал а отнаследовать от landscape_terrain_detail_base : Material::findBaseMaterial("landscape_terrain_detail_base")->inherit("my_detail_material"); 26 minutes ago, Vasara said: material->setTextureImage(0, tempImage); а тут нужно сначала найти текстуры которую вы хотите установить например : material->setTextureImage(material->findTexture("albedo"), tempImage); 1 Link to comment
Vasara Posted October 6, 2020 Author Share Posted October 6, 2020 Спасибо большое, теперь только ругается на ассет. Буду разбираться с Materials. Link to comment
Vasara Posted October 6, 2020 Author Share Posted October 6, 2020 Проект запускается без ошибок, но цвет ландшафта не меняется: auto mask = Landscape::getActiveTerrain()->getDetailMask(0); auto detail = mask->addDetail(); auto tempImage = Image::create(); tempImage->create2DArray(4096, 4096, 1, Image::FORMAT_RGBA8); if (FileSystem::isFileExist("landscape_grafic_assets/mask_assets/white_sand/base_white_sand.dds")) { tempImage->load("landscape_grafic_assets/mask_assets/white_sand/base_white_sand.dds"); } else { Log::error("Height image files does not exist or corupted. Please create height image files first\n"); } auto material = Materials::findBaseMaterial("landscape_terrain_detail_base")->inherit("landscape_grafic_assets/mask_assets/white_sand/base_white_sand.mat"); material->setTextureImage(material->findTexture("albedo"), tempImage); detail->setMaterial(material); Это сохранено в base_white_sand.mat : <?xml version="1.0" encoding="utf-8"?> <material version="1.0.0.0" name="base_white_sand" base_material="landscape_terrain_detail_base" manual="1"> </material> Если добавить например параметр: <parameter name="albedo_color">0 0 0 0</parameter> Выдаёт ошибку: Если: <options albedo_color="100,200,0"/> Без ошибки: Как оборачивать в xml параметры по ссылке, совершенно непонятно. Так как описание есть только для редактора. https://developer.unigine.com/en/docs/2.12/content/materials/library/landscape_terrain_detail_base/?rlang=cpp Link to comment
danvern Posted October 7, 2020 Share Posted October 7, 2020 так в этом материале нет такого параметра c таким именем, там есть только парамеметр albedo Link to comment
Vasara Posted October 7, 2020 Author Share Posted October 7, 2020 (edited) Загружается террейн зелёного цвета, мне нужно наложить маску, чтобы поменять цвет на красный. terrain = ObjectLandscapeTerrain::create(); terrain->setActiveTerrain(true); terrain->setCollision(true, 0); lmap = LandscapeLayerMap::create(); lmap->setParent(Landscape::getActiveTerrain()); lmap->setPath(lmapName); lmap->setName(lmapName.get()); lmap->setSize(Math::Vec2(4096, 4096)); lmap->setHeightScale(1.0f); lmap->setWorldPosition(Math::Vec3::ZERO); lmap->setWorldRotation(Math::quat(Math::vec3::UP, 45.0f)); MaterialPtr materialBase = Materials::findBaseMaterial("landscape_terrain_detail_base"); MaterialPtr material = materialBase->inherit("base_white_sand", "landscape_grafic_assets/mask_assets/white_sand/base_white_sand.mat"); material->setTexturePath(material->findTexture("albedo"), "landscape_grafic_assets/mask_assets/white_sand/base_white_sand.dds"); TerrainDetailMaskPtr detailMask; detailMask = terrain->getDetailMask(1); detailMask->setName("mask_base_white_sand"); detailMask->setEnabled(1); TerrainDetailPtr detail; detail = detailMask->addDetail(); detail->setName("detail_base_white_sand"); detail->setEnabled(1); detail->setMaterial(material); Лыжи не едут. Мир зелёный. Что я делаю не так? Edited October 7, 2020 by Vasara Link to comment
danvern Posted October 8, 2020 Share Posted October 8, 2020 а сама маска точно есть в lmap файле? Link to comment
Vasara Posted October 8, 2020 Author Share Posted October 8, 2020 (edited) 2 hours ago, danvern said: а сама маска точно есть в lmap файле? При генерации я добавлял только данные альбедо и высот. Если необходимо както дополнительно инициализировать маски, то видимо нету. Этот вариант приходил в голову, но я в упор не могу сообразить как в lmap маски инициализиривать. Если включить маску в консоли: LandscapeMapFileSettingsPtr settings = LandscapeMapFileSettings::create(); settings->load(FileSystem::getGUID(lmapName)); if (settings->isLoaded()) { settings->setHeightBlending(0); settings->setAlbedoBlending(0); settings->setEnabledHeight(true); settings->setEnabledAlbedo(true); settings->setEnabledOpacityAlbedo(false); settings->setEnabledOpacityHeight(false); settings->setEnabledMask(0, 1); settings->setEnabledMask(1, 1); settings->apply(); } Edited October 8, 2020 by Vasara Link to comment
Vasara Posted October 8, 2020 Author Share Posted October 8, 2020 (edited) Вот это должно быть красным: Я перекопал всё API за эту неделю. Неделя потрачена, результата 0, это плохо. На отсутствие масок движок не ругается: Закрадывается мысль, что это у вас что то не работает... Edited October 8, 2020 by Vasara Link to comment
danvern Posted October 9, 2020 Share Posted October 9, 2020 сделал маленький пример который от начала и до конца показывает как использовать маски папка landscape_data должна лежать в корне data/ sample.zip Link to comment
Vasara Posted October 9, 2020 Author Share Posted October 9, 2020 1 hour ago, danvern said: сделал маленький пример который от начала и до конца показывает как использовать маски Спасибо большое. Ещё один вопрос, как маска устанавливается для многотайловой карты? Возможна ли проблема в моём коде изза того, что террейн 4х4? Link to comment
danvern Posted October 9, 2020 Share Posted October 9, 2020 маски устанавливаются в lmap'у так же по-тайлово, возможно у вас просто не заполнено opacity для маски Link to comment
danvern Posted October 9, 2020 Share Posted October 9, 2020 opacity для масок можно отключить через LandscapeMapFileSettings Link to comment
Vasara Posted October 9, 2020 Author Share Posted October 9, 2020 Да, маску надо добавлять при генерации lmap'ы. Вы правы, масок по факту небыло. Добавил часть кода из примера в генерацию, всё заработало. Большое спасибо за помощь. 1 Link to comment
Recommended Posts