Edge Detection (Sobel)

Шейдеры и все-все-все.

Edge Detection (Sobel)

Сообщение gnoblin 22 окт 2010, 07:06

Шейдер, который выделяет края на текстуре объекта используя фильтр Собеля.

Я кривовато скопипастил шейдер, поэтому он не скомпилился для sm2.0 (т.е. работает только с shader model 3.0) - юнити написало что-то про 5 texture indirections.
Будет неплохо, если кто-то со мной подискутирует на тему как это можно оптимизнуть.

Синтаксис:
Используется glsl
Shader "ImageProc EdgeDetectionSobel" {
 Properties {
      _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
          #pragma target 3.0
               
      struct Input {
          float2 uv_MainTex;
      };
     
      sampler2D _MainTex;
      void surf (Input IN, inout SurfaceOutput o)
      {
         
          float off = 1.0/1024;
          // Sample the neighbor pixels
                        float s00 = tex2D(_MainTex, IN.uv_MainTex + float2(-off, -off));
                        float s01 = tex2D(_MainTex, IN.uv_MainTex + float2( 0, -off));
                        float s02 = tex2D(_MainTex, IN.uv_MainTex + float2( off, -off));
                        float s10 = tex2D(_MainTex, IN.uv_MainTex + float2(-off, 0));
                        float s12 = tex2D(_MainTex, IN.uv_MainTex + float2( off, 0));
                        float s20 = tex2D(_MainTex, IN.uv_MainTex + float2(-off, off));
                        float s21 = tex2D(_MainTex, IN.uv_MainTex + float2( 0, off));
                        float s22 = tex2D(_MainTex, IN.uv_MainTex + float2( off, off));
                        // Sobel filter in X and Y direction
                        float sobelX = s00 + 2 * s10 + s20 - s02 - 2 * s12 - s22;
                        float sobelY = s00 + 2 * s01 + s02 - s20 - 2 * s21 - s22;
                        // Find edge using a threshold of 0.07 which works generally
                        // well for general edge detection.
                        float edgeSqr = (sobelX * sobelX + sobelY * sobelY);
                       
                        float threshold = 0.0049;//0.07*0.07;
                       
                        half3 tmp = half3(0,0,0);
                        half3 one = half3(1,1,1);
                        if(edgeSqr > threshold)
                        {
                                tmp = one;
                        }
                                                                       
                        o.Albedo = one-tmp;    
      }
      ENDCG
    }
    Fallback "Diffuse"
  }
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Edge Detection (Sobel)

Сообщение Battle Angel Alita 22 окт 2010, 07:56

texture indirections - это когда текстуры читаются не по текстурным координатам пришедшим из вершинного шейдера, а по вычисленным координатам. В данном случае это
IN.uv_MainTex + float2(-off, -off)
и т.д.
Мозг рака
Изображение
Аватара пользователя
Battle Angel Alita
UNIверсал
 
Сообщения: 476
Зарегистрирован: 25 ноя 2009, 14:52

Re: Edge Detection (Sobel)

Сообщение gnoblin 22 окт 2010, 14:06

Ясненько, спасибо.
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Edge Detection (Sobel)

Сообщение gnoblin 30 окт 2010, 01:30

Пару улучшений к похожему шейдеру здесь: viewtopic.php?f=35&t=2757&p=23795#p23795
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Edge Detection (Sobel)

Сообщение PAX 11 ноя 2010, 10:39

А если попробовать в вершинном шейдере рассчитать массив UV и его использовать для выборок? Только надо не сурфеейсный шейдер.
Примерно как тут:
Синтаксис:
Используется glsl
struct v2f {
        float4 pos : POSITION;
        float4 uv[4] : TEXCOORD0;
};
 
Blitz3d to Unity Wiki
icq: 208084972
skype: pax62rus
Аватара пользователя
PAX
UNIт
 
Сообщения: 134
Зарегистрирован: 03 ноя 2009, 12:53
Откуда: Россия, Рязань
  • Сайт
  • ICQ


Вернуться в Shader Lab

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2