Jump to content

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


photo

Recommended Posts

 

Резюмирую то, что освоил. Надеюсь новичкам поможет.

Движок поддерживает 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
Link to comment

Здравствуйте, маски назначаются на активный 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

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

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
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
Link to comment

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

	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

 

Link to comment

Загружается террейн зелёного цвета, мне нужно наложить маску, чтобы поменять цвет на красный. 

    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
Link to comment
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
Link to comment

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

example.jpg.ac402c9e523ea6b2c71e8aa8b141212b.jpg

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

output.jpg.1e7bb90363c7bbcc0c70a66b2b5e860b.jpg

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

Edited by Vasara
Link to comment

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

sample.zip

Link to comment
1 hour ago, danvern said:

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

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

Link to comment

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

Link to comment

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

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