Jump to content

[SOLVED]Добавление новой маски.


photo

Recommended Posts

Posted (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 by Vasara
Posted

Здравствуйте, маски назначаются на активный ObjectLandscapeTerrain, который можно получить тут Landscape::getActiveTerrain()
 

auto mask = Landscape::getActiveTerrain()->getDetailMask(0);
auto detail = mask->addDetail();
//setup detail

и ObjectLandscapeTerrain должен быть в мире

 

18 hours ago, Vasara said:

А как detailTerrain к террейну применить?

Детейлы автоматически начнут работать

Posted

падает с ошибкой доступа, видимо я чтото не понимаю до конца:

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);

Posted
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);

 

  • Like 1
Posted

Спасибо большое, теперь только ругается на ассет. Буду разбираться с Materials.

Posted

Проект запускается без ошибок, но цвет ландшафта не меняется:

	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>

Выдаёт ошибку:

err.thumb.png.257c431bf862adf2e3b54bd2454c47fb.png

Если:

<options albedo_color="100,200,0"/>

Без ошибки:

err2.thumb.png.ef90df12bea00830ad983098332bee35.png

Как оборачивать в xml параметры по ссылке, совершенно непонятно. Так как описание есть только для редактора.

https://developer.unigine.com/en/docs/2.12/content/materials/library/landscape_terrain_detail_base/?rlang=cpp

 

Posted

так в этом материале нет такого параметра c таким именем, там есть только парамеметр albedo

Posted (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 by Vasara
Posted

а сама маска точно есть в lmap файле?

Posted (edited)
2 hours ago, danvern said:

а сама маска точно есть в lmap файле?

При генерации я добавлял только данные альбедо и высот. Если необходимо както дополнительно инициализировать маски, то видимо нету.

Этот вариант приходил в голову, но я в упор не могу сообразить как в lmap маски инициализиривать.

 

Если включить маску в консоли:

mask1.png

 

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 by Vasara
Posted (edited)

Вот это должно быть красным:

example.jpg.ac402c9e523ea6b2c71e8aa8b141212b.jpg

Я перекопал всё API за эту неделю. Неделя потрачена, результата 0, это плохо. На отсутствие масок движок не ругается:

output.jpg.1e7bb90363c7bbcc0c70a66b2b5e860b.jpg

Закрадывается мысль, что это у вас что то не работает...

Edited by Vasara
Posted

сделал маленький пример который от начала и до конца показывает как использовать маски
папка landscape_data должна лежать в корне data/

sample.zip

Posted
1 hour ago, danvern said:

сделал маленький пример который от начала и до конца показывает как использовать маски

Спасибо большое. Ещё один вопрос, как маска устанавливается для многотайловой карты? Возможна ли проблема в моём коде изза того, что террейн 4х4?

Posted

маски устанавливаются в lmap'у так же по-тайлово, возможно у вас просто не заполнено opacity для маски

Posted

opacity для масок можно отключить через LandscapeMapFileSettings

Posted

Да, маску надо добавлять при генерации lmap'ы. Вы правы, масок по факту небыло. Добавил часть кода из примера в генерацию, всё заработало. Большое спасибо за помощь.

  • Like 1
  • Vasara changed the title to [SOLVED]Добавление новой маски.
×
×
  • Create New...