Страница 1 из 2

ChannelBlend'ы

СообщениеДобавлено: 14 окт 2010, 15:32
gnoblin
Difference
Реализация режима смешивания слоев Difference из фотошопа.
Если кто-то видит косяк - говорите [curved_hands] .
Никакого подвига не совершил - скопипастил формулу :).
Планирую покопипастить все остальные режимы смешивания.

Синтаксис:
Используется glsl
Shader "ChannelBlend/DiffuseDifference" {
Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BlendTex ("Texture", 2D) = "white" {}
    }

    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float2 uv_MainTex;

      };
      sampler2D _MainTex;
          sampler2D _BlendTex;

      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;
                               
                o.Albedo.r = abs(o.Albedo.r - blend.r);
                o.Albedo.g = abs(o.Albedo.g - blend.g);
                o.Albedo.b = abs(o.Albedo.b - blend.b);
               
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

Re: ChannelBlend'ы

СообщениеДобавлено: 14 окт 2010, 16:02
gnoblin
Lighten

Интересно, можно ли как-то более оптимально писать
Код: Выделить всё
if(blend.r > o.Albedo.r)
{
   o.Albedo.r = blend.r;
}


Синтаксис:
Используется glsl
Shader "ChannelBlend/DiffuseLighten" {
Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BlendTex ("Texture", 2D) = "white" {}
    }

    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float2 uv_MainTex;

      };
      sampler2D _MainTex;
          sampler2D _BlendTex;

      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;
               
                if(blend.r > o.Albedo.r)
                {
                        o.Albedo.r = blend.r;
                }
                if(blend.g > o.Albedo.g)
                {
                        o.Albedo.g = blend.g;
                }
                if(blend.b > o.Albedo.b)
                {
                        o.Albedo.b = blend.b;
                }
               
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

 

Re: ChannelBlend'ы

СообщениеДобавлено: 14 окт 2010, 16:05
gnoblin
Darken

"Lighten наоборот"

Синтаксис:
Используется glsl
Shader "ChannelBlend/DiffuseDarken" {
Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BlendTex ("Texture", 2D) = "white" {}
    }

    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float2 uv_MainTex;

      };
      sampler2D _MainTex;
          sampler2D _BlendTex;

      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;
               
                if(blend.r < o.Albedo.r)
                {
                        o.Albedo.r = blend.r;
                }
                if(blend.g < o.Albedo.g)
                {
                        o.Albedo.g = blend.g;
                }
                if(blend.b < o.Albedo.b)
                {
                        o.Albedo.b = blend.b;
                }
               
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

Re: ChannelBlend'ы

СообщениеДобавлено: 14 окт 2010, 16:10
gnoblin
Multiply

Синтаксис:
Используется glsl
Shader "ChannelBlend/DiffuseMultiply" {
Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BlendTex ("Texture", 2D) = "white" {}
    }

    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float2 uv_MainTex;

      };
      sampler2D _MainTex;
          sampler2D _BlendTex;

      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;
               
                o.Albedo.r = o.Albedo.r * blend.r;
                o.Albedo.g = o.Albedo.g * blend.g;
                o.Albedo.b = o.Albedo.b * blend.b;
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

Re: ChannelBlend'ы

СообщениеДобавлено: 14 окт 2010, 16:14
gnoblin
Average

Синтаксис:
Используется glsl
Shader "ChannelBlend/DiffuseAverage" {
Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BlendTex ("Texture", 2D) = "white" {}
    }

    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float2 uv_MainTex;

      };
      sampler2D _MainTex;
          sampler2D _BlendTex;

      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;
               
                o.Albedo.r = (o.Albedo.r + blend.r) * 0.5;
                o.Albedo.g = (o.Albedo.g + blend.g) * 0.5;
                o.Albedo.b = (o.Albedo.b + blend.b) * 0.5;
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

Re: ChannelBlend'ы

СообщениеДобавлено: 14 окт 2010, 16:19
gnoblin
Add

Синтаксис:
Используется glsl
Shader "ChannelBlend/DiffuseAdd" {
Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BlendTex ("Texture", 2D) = "white" {}
    }

    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float2 uv_MainTex;

      };
      sampler2D _MainTex;
          sampler2D _BlendTex;

      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;
               
                o.Albedo.r = min(1.0, o.Albedo.r + blend.r);
                o.Albedo.g = min(1.0, o.Albedo.g + blend.g);
                o.Albedo.b = min(1.0, o.Albedo.b + blend.b);
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

Re: ChannelBlend'ы

СообщениеДобавлено: 14 окт 2010, 16:28
gnoblin
Substract

Синтаксис:
Используется glsl
Shader "ChannelBlend/DiffuseSubstract" {
Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BlendTex ("Texture", 2D) = "white" {}
    }

    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float2 uv_MainTex;

      };
      sampler2D _MainTex;
          sampler2D _BlendTex;

      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;
               
                if(o.Albedo.r + blend.r < 1.0)
                {
                        o.Albedo.r = 0.0;
                }
                else
                {
                        o.Albedo.r = o.Albedo.r + blend.r - 1.0;
                }
               
                if(o.Albedo.g + blend.g < 1.0)
                {
                        o.Albedo.g = 0.0;
                }
                else
                {
                        o.Albedo.g = o.Albedo.g + blend.g - 1.0;
                }
               
                if(o.Albedo.b + blend.b < 1.0)
                {
                        o.Albedo.b = 0.0;
                }
                else
                {
                        o.Albedo.b = o.Albedo.b + blend.b - 1.0;
                }
               
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

 

Re: ChannelBlend'ы

СообщениеДобавлено: 14 окт 2010, 16:52
gnoblin
Negation

Синтаксис:
Используется glsl
Shader "ChannelBlend/DiffuseNegation" {
Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BlendTex ("Texture", 2D) = "white" {}
    }

    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float2 uv_MainTex;

      };
      sampler2D _MainTex;
          sampler2D _BlendTex;

      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;
               
                o.Albedo.r = 1.0 - abs(1.0 - o.Albedo.r - blend.r);
                o.Albedo.g = 1.0 - abs(1.0 - o.Albedo.g - blend.g);
                o.Albedo.b = 1.0 - abs(1.0 - o.Albedo.b - blend.b);
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

Re: ChannelBlend'ы

СообщениеДобавлено: 15 окт 2010, 05:25
Faps
gnoblin писал(а):
Синтаксис:
Используется glsl
      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;

                o.Albedo.r = 1.0 - abs(1.0 - o.Albedo.r - blend.r);
                o.Albedo.g = 1.0 - abs(1.0 - o.Albedo.g - blend.g);
                o.Albedo.b = 1.0 - abs(1.0 - o.Albedo.b - blend.b);

      }
  }


помоему так будет оптимальнее (количество вычеслительных операций ограниченно, помоему макс 64 или 63, а операция с переменной [half например] = по затратам операции с массивом [half3]):

Синтаксис:
Используется glsl
      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        half3 blend = tex2D (_BlendTex, IN.uv_MainTex).rgb;

                half3 one = new half3(1.0, 1.0, 1.0);
                o.Albedo = one - abs(one - o.Albedo - blend);
      }
  }

Re: ChannelBlend'ы

СообщениеДобавлено: 15 окт 2010, 10:05
gnoblin
Пасиба!
Чуть позже отредактирую.

Re: ChannelBlend'ы

СообщениеДобавлено: 27 окт 2010, 03:19
gnoblin

Re: ChannelBlend'ы

СообщениеДобавлено: 27 окт 2010, 07:04
olegklk
А кто-нибудь может подсказать как сделать блендинг с тем что уже есть на экране.
Например я хочу наложить картинку с прозрачностью поверх моих спрайтов на сцене в режиме наложения HardLight - как это делается в SurfaceShaders? Т.е. я применяю для этой картинки шейдер подобный вот этим, но мне надо как-то складывать и вычитать текстуру моей картинки с тем что уже срендерено на экране. Как это сделать?

Re: ChannelBlend'ы

СообщениеДобавлено: 27 окт 2010, 15:15
gnoblin
Например через постэффект (см., например, NoiseEffect из стандартной поставки юнити).

Re: ChannelBlend'ы

СообщениеДобавлено: 18 ноя 2010, 14:04
gnoblin
Или сделать полупрозрачный несурфейс шейдер с каким-то режимом блендинга.
Пока ещё раздумываю как можно шейдерлабом сделать хардлайт :-w

Re: ChannelBlend'ы

СообщениеДобавлено: 19 ноя 2010, 01:59
Ert Donuell
gnoblin писал(а):Lighten

Интересно, можно ли как-то более оптимально писать
Код: Выделить всё
if(blend.r > o.Albedo.r)
{
   o.Albedo.r = blend.r;
}


Не уверен что в скриптах шейдера это актуально, но многие языки поддерживают следующую конструкцию:
Код: Выделить всё
$a = ($a == $b) ? 1: 2;

что эквивалентно
Код: Выделить всё
if ($a == $b) {
   $a = 1;
} else {
   $a = 2;
}


То есть в данном случае это будет выглядеть как:
Код: Выделить всё
o.Albedo.r = (blend.r > o.Albedo.r) ? blend.r;