Обновить
65
Андрей Мишкинис@AndreyMI

Indie Game Developer

26
Подписчики
Отправить сообщение
Карта прозрачности готовится прямо в Unity в самописном редакторе.
Но она легко может меняться даже непосредственно в игре.
Да, именно так
Шейдер как раз и разрабатывался для изометрической 2D стратегии.
С островками никаких проблем нет, мы просто рисуем их на карте прозрачности слоев.
Карта прозрачности



В основном для наглядности, в конечном шейдере нет условных переходов.

Не вижу mix в Cg, наверно lerp?
Очень просто. Добавьте еще один слой в графики:)
Или, как уже заметил mayorovp, последовательное расширение.



В шейдере для своей игрушки я смешиваю 4 разных текстуры вместе с картами нормалей и одну карту шума.
После игр с математическими операциями мне даже удалось уложиться в ограничения SM2.0.
Оригинальный шейдер является частью коммерческого проекта, поэтому его исходников не будет.
Но если вы хотите повторить эксперимент в Unity 3D, то создайте сцену с плоскостью и назначьте ей следующий шейдер:
Код шейдера из статьи
Shader "Custom/Demo" {
	Properties {
		_Tex1 ("Texture 1 (RGB) Depth (A)", 2D) = "white" {}
		_Tex2 ("Texture 2 (RGB) Depth (A)", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _Tex1;
		sampler2D _Tex2;

		struct Input {
			float2 uv_Tex1;
			float2 uv_Tex2;
		};

		float3 blend(float4 texture1, float a1, float4 texture2, float a2)
		{
			float depth = 0.2;
			float ma = max(texture1.a + a1, texture2.a + a2) - depth;
			float b1 = max(texture1.a + a1 - ma, 0);
			float b2 = max(texture2.a + a2 - ma, 0);
			return (texture1.rgb * b1 + texture2.rgb * b2) / (b1 + b2);
		}

		void surf (Input IN, inout SurfaceOutput o) {
			half4 c1 = tex2D (_Tex1, IN.uv_Tex1);
			half4 c2 = tex2D (_Tex2, IN.uv_Tex2);
			o.Albedo = blend(c1, IN.uv_Tex2.x, c2, 1 - IN.uv_Tex2.x);
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

Сократить маркетинговые издержки и получить аудиторию, которая точно скачает первый эпизод вашей игры, можно, используя IP

А что такое IP?
А зачем в последнем блоке кода использовать switch, если можно обойтись массивом int[] colors?
Правда я на linq to sql проверял…
Странно, у меня этот код сформировал корректный sql
SELECT [t0].[Id], [t0].[Revision]
FROM [Item] AS [t0]
WHERE (([t0].[Id] = @p0) AND ([t0].[Revision] = @p1)) OR (([t0].[Id] = @p2) AND ([t0].[Revision] = @p3))
А так разве не выйдет?
var ids = new[]{
    new {Id = 1, Revision= 2},
    new {Id = 1, Revision= 4},
    ...
};

var q = from i in context.Items
        where ids.Contains(new {i.Id, i.Revision})
        select i;
Фокусники владеющие телекинезом будут в восторге:)
Лишь бы расширения от этого в «тихую» не отваливались…
bool value = true;
if (value.ToString().Length == 4);
// ваш хокку лучший
Да, все уже написано до нас:)
Просто хотелось показать путь размышлений, как можно прийти к этому алгоритму.
На всякий случай распишу подробнее:

[RRRR RGGG GGGB BBBB RRRR RGGG GGGB BBBB] = P // 2 пикселя
[0000 0111 1110 0000 1111 1000 0001 1111] = 0x07E0F81F
[0000 0GGG GGG0 0000 RRRR R000 000B BBBB] = P & 0x07E0F81F = P' // выделяем нечетные компоненты

[A AAAA] = a // коэффициент прозрачности состоит из 5-ти бит

[0000 0AAA AA00 0000 AAAA A000 000A AAAA] = oddA // выравниваем α по нечетным компонентам
[GGGG GGGG GGGR RRRR RRRR R0BB BBBB BBBB] = P' * oddA // после умножения компоненты начинают занимать выделенные пространства
[0000 0GGG GGGG GGGG RRRR RRRR RR0B BBBB] = P' * oddA >> 5 = P" // выравниваем полученные значения
[0000 0GGG GGG0 0000 RRRR R000 000B BBBB] = P" & 0x07E0F81F // очищаем место для вставки четных компонент
Тогда рекомендую опробовать оба способа. На некоторых устройствах способ с двумя умножениями на пиксель показывал чуть большую производительность. ;)

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность