пятница, 24 января 2014 г.

VisualWebSiteOptimizer баг с вариантами.

Признаюсь сразу что это не совсем баг а всего лишь кривая вёрстка команды заказчика
Подолгу службы мне иногда приходится общаться с клиентами моей фирмы, недавно к нам обратился человек у которого варианты лэндинга не работали на продакшене и не были видны в превью. Это не приятная ситуация и мне поручили с ней разобраться. Первым делом я обратился в саппорт, мне ответили следующее:

Thank you for contacting us. I have checked the test and would like to tell you that there is an iframe element when the webpage is loaded in the VWO editor which is causing the CSS selector path to be different when the visitor lands on the webpage directly and hence VWO is not able to find the element and apply the changes (please check the screenshot 1 attached). 

So I would recommend that you either insert an ID on the DIV element after the opening body tag so that the CSS selector path is calculated from that element or you can create an MVT test and add the CSS selector path (font.actiontitle>center) manually (as shown in the screenshot2) and then disable all the variations except for the control and the last variation in the test.
  Я как нормальный человек понял мало. Но взглянул на лэндинг которые сверстали фрилансеры, я впал в не большую фрустрацию с большим желанием выпить ещё одну чашку кофе. Дело в том, что на КАЖДЫЙ тег приходился свой собственный id, самое забавное что это не генерированная странница а свёрстанная вполне реальным человеком с вполне функциональными руками (ну по крайней мере в ухе ими поковыряться можно). Из-за такой "пёрстости" страницы, ломались селекторы. Проблема решалась заклчением всей страницы в див с id = VWOWrapper, под всей страницей я имею ввиду конечно-же всё от ‹ body › и до ‹ /body › .
Надеюсь Вам это помогло!

Кастомизация Unity Web Player [Preloader]


четверг, 9 января 2014 г.

Хостинг Unity Web Player

Написал основу за выходные, сейчас тружусь над улучшением сервиса :) 

Хостинг Unity Web Player

Пишем Dissolve Shader [Хабра]

Введение

Перед новым годом, я решил попробовать себя в написании шейдеров. В качестве цели я избрал для себя шейдер растворяющегося объекта, 31 декабря я его успешно закончил и теперь пришло время что-то с ним делать. На ассет сторе сказали что всё отлично но уже парочка похожих есть, по этому я постараюсь разобрать его в этой статье. В итоге у нас должно получиться вот это:

  Путей реализации есть несколько:
  • Alpha
  • CutOff
  • Grab Texture
В итоге у нас получится 3 шейдера, 2 использующие только альфу и которые могут взлететь на моб. девайсах и один с AlphaTest который выглядит посимпатичней но более прожорливый. Благодаря AlphaTest мы можем отключить отсечение невидимых полигонов и не получать наслоение. Но заплатить придётся шейдерной моделью 2.0 и использовать 3.0 из-за чего нельзя будет использовать на моб. девайсах.

Каркас

Общий алгоритм примерно такой:
  • Берём яркость пикселя с маски разрушения или прямо с главной текстуры
  • Сравниваем эту яркость с N
  • Если яркость больше N то альфу пикселя ставим в нолик
В итоге получится не так красиво как на первом видео.
Нам не хватает карт нормалей, и самого крутого. Линий! Алгоритм инлайнов у меня такой:
  • Берём яркость пикселя с маски разрушения, но с оффсетом по UV + LineSize. И ещё один но оффсет уже UV - LineSize
  • Если хотя бы один из пикселей меньше N, то мы устанавливаем цвет пикселя из текстуры для линий
  • Иначе ставим альфу в ноль (Это как замена аналогичной операции в первом алгоритме)
Резюмирую выше сказанное, мы получаем отсечение по маске и если пиксели отсекаем то проверяем нету ли впритык к нему не отсечённые, если они есть мы становимся краем и ставим себе определённый цвет.

Ближе к телу коду

Если прибавить ко всему выше сказанному наложение нормалек и смещение текстуры линии ещё по синусоидальному времени, получится вот такое вот полотно.
 Shader "HolyMonkey/Dissolve/Bumped" {

 Properties {
     _MainColor ("Main Color", Color) = (1,1,1,1)
  _MainTex ("Base (RGB)", 2D) = "white" {}
  _Mask("Mask To Dissolve", 2D) = "white" {}
  _LineTexture("Line Texture", 2D) = "white" {}
  _Range ("Range", Range(0,3)) = 0
  _LineSize ("LineSize", Float) = 0.001
  _Color ("Line Color", Color) = (1,1,1,1)
  _BumpMap ("Normalmap", 2D) = "bump" {}
  _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
 }
 
 SubShader {
  Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
  LOD 300
  ZWrite On
  Cull Off
  CGPROGRAM 
  #pragma target 3.0
  #include "UnityCG.cginc"
  #pragma surface surf Lambert alphatest:_Cutoff
        

  sampler2D _MainTex;
  sampler2D _LineTexture;
  sampler2D _BumpMap;
  sampler2D _Mask;
  half4 _Color;
  half4 _MainColor;
  float _Range;
  float _LineSize;
             
  struct Input {
   float2 uv_MainTex;
   float2 uv_BumpMap;
                        float2 uv_Detail;
  };
            
  void surf (Input IN, inout SurfaceOutput o) {
   half4 c = tex2D (_MainTex, IN.uv_MainTex);
   half4 m = tex2D (_Mask, IN.uv_MainTex);
          half4 lc =  tex2D (_Mask, IN.uv_MainTex - _LineSize);
          half4 lc2 = tex2D (_Mask, IN.uv_MainTex + _LineSize);
   half4 lc3 = tex2D(_LineTexture, IN.uv_MainTex + _SinTime) * _Color;    
    
          o.Albedo = c *  _MainColor;
          o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
          o.Alpha = 1;
      
   float factor = m.rgb.x + m.rgb.y + m.rgb.z;
   if(factor >= _Range)
   {
      float factor2 = lc.rgb.x + lc.rgb.y + lc.rgb.z;
      float factor3 = lc2.rgb.x + lc2.rgb.y + lc2.rgb.z;
      if(factor2 < _Range || factor3 < _Range)
      {
         o.Albedo = lc3;
      }
      else
      {
                  o.Alpha = 0.0;
               }
            }
  }
  ENDCG
 } 
 Fallback "Diffuse"
}
Ещё можно поиграться с не которыми аспектами и получить следующее
Shader "HolyMonkey/Dissolve/Culling-Mobile" {

 Properties {
     _MainColor ("Main Color", Color) = (1,1,1,1)
  _MainTex ("Base (RGB)", 2D) = "white" {}
  _Mask("Mask To Dissolve", 2D) = "white" {}
  _LineTexture("Line Texture", 2D) = "white" {}
  _Range ("Range", Range(0,3)) = 0
  _LineSize ("LineSize", Float) = 0.001
  _Color ("Line Color", Color) = (1,1,1,1)
  _BumpMap ("Normalmap", 2D) = "bump" {}
 }
 
 SubShader {
  Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
  LOD 300
  CGPROGRAM 
  #pragma target 2.0
  #include "UnityCG.cginc"
  #pragma surface surf Lambert alpha 
        

  sampler2D _MainTex;
  sampler2D _LineTexture;
  sampler2D _BumpMap;
  sampler2D _Mask;
  half4 _Color;
  half4 _MainColor;
  float _Range;
  float _LineSize;
             
  struct Input {
   float2 uv_MainTex;
   float2 uv_BumpMap;
            float2 uv_Detail;
  };
            
  void surf (Input IN, inout SurfaceOutput o) {
   half4 c = tex2D (_MainTex, IN.uv_MainTex);
   half4 m = tex2D (_Mask, IN.uv_MainTex);
      half4 lc =  tex2D (_Mask, IN.uv_MainTex - _LineSize);
      half4 lc2 = tex2D (_Mask, IN.uv_MainTex + _LineSize);
   half4 lc3 = tex2D(_LineTexture, IN.uv_MainTex + _SinTime) * _Color;    
    
      o.Albedo = c *  _MainColor;
      o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
      o.Alpha = 1;
      
   float factor = m.rgb.x + m.rgb.y + m.rgb.z;
   if(factor >= _Range)
   {
      float factor2 = lc.rgb.x + lc.rgb.y + lc.rgb.z;
      float factor3 = lc2.rgb.x + lc2.rgb.y + lc2.rgb.z;
      if(factor2 < _Range || factor3 < _Range)
      {
         o.Albedo = lc3;
      }
      else
      {
                  o.Alpha = 0.0;
               }
            }
  }
  ENDCG
 } 
 Fallback "Diffuse"
}
Shader "HolyMonkey/Dissolve/NotTransparent" {

 Properties {
     _MainColor ("Main Color", Color) = (1,1,1,1)
  _MainTex ("Base (RGB)", 2D) = "white" {}
  _BackTexture ("Back Texture", 2D) = "white" {}
  _Mask("Mask To Dissolve", 2D) = "white" {}
  _LineTexture("Line Texture", 2D) = "white" {}
  _Range ("Range", Range(0,3)) = 0
  _LineSize ("LineSize", Float) = 0.001
  _Color ("Line Color", Color) = (1,1,1,1)
  _BumpMap ("Normalmap", 2D) = "bump" {}
 }
 
 SubShader {
  LOD 300
  ZWrite On
  Cull Off
  
  CGPROGRAM 
  #pragma target 2.0
  #include "UnityCG.cginc"
  #pragma surface surf Lambert
        

  sampler2D _MainTex;
  sampler2D _LineTexture;
  sampler2D _BumpMap;
  sampler2D _Mask;
  sampler2D _BackTexture;
  half4 _Color;
  half4 _MainColor;
  float _Range;
  float _LineSize;
             
  struct Input {
   float2 uv_MainTex;
   float2 uv_BumpMap;
            float2 uv_Detail;
  };
            
  void surf (Input IN, inout SurfaceOutput o) {
   half4 c = tex2D (_MainTex, IN.uv_MainTex);
   half4 m = tex2D (_Mask, IN.uv_MainTex);
      half4 lc =  tex2D (_Mask, IN.uv_MainTex - _LineSize);
      half4 lc2 = tex2D (_Mask, IN.uv_MainTex + _LineSize);
   half4 lc3 = tex2D(_LineTexture, IN.uv_MainTex + _SinTime) * _Color;    
   half4 bc  = tex2D(_BackTexture, IN.uv_MainTex);
      o.Albedo = c *  _MainColor;
      o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
      
   float factor = m.rgb.x + m.rgb.y + m.rgb.z;
   if(factor >= _Range)
   {
      float factor2 = lc.rgb.x + lc.rgb.y + lc.rgb.z;
      float factor3 = lc2.rgb.x + lc2.rgb.y + lc2.rgb.z;
      if(factor2 < _Range || factor3 < _Range)
      {
         o.Albedo = lc3;
      }
      else
      {
         o.Albedo = bc;
         o.Normal = float3(1,1,1);
      }
            }
  }
  ENDCG
 } 
 Fallback "Diffuse"
}

Заключение

Написать получилось мало, но думаю дедуктивный код это искупает. Там используются простые вещи, и на хабре есть статьи с их ним разбором. Исходники со всеми нужными ресурсами Вы можете скачать из репозитория на GitHub