Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование в широком смысле слова > Алгоритмика

Алгоритмика Об алгоритмах вообще; методы, обсуждения способов решения

Ответ
 
Опции темы
Старый 12.12.2011, 12:51   #1
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Карта высот из картинки

Подскажите, есть ли какие-то специальные алгоритмы построения карты высот по картинке?

Нужно для дальнейшего преобразования в карту нормалей.
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 13:50   #2
dsd
Мастер
 
Аватар для dsd
 
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений
(для 1,836 пользователей)
Ответ: Карта высот из картинки

Насчет специальных алгоритмов я не знаю, по моему карта высот она и в Африке карта высот и вся подготовка может быть выполнена в графическом редакторе. А вот по нормалям чутка есть.

        for(int i=0;i<uppersize;i++){
            for(int j=0;j<uppersize;j++){
            int x0=i-1,x1=i+1,y0=j-1,y1=j+1;
            //check of indexes size
            if(i==0){x0=uppersize-1;}
            if(i==uppersize-1){x1=0;}
            if(j==0){y0=uppersize-1;}
            if(j==uppersize-1){y1=0;}
            //normals
            float3  a00(-1,first->seed[x0][y0]-first->seed[i][j],-1); a00.normalize();
            float3  a10(0,first->seed[i][y0]-first->seed[i][j],-1); a10.normalize();
            float3  a20(1,first->seed[x1][y0]-first->seed[i][j],-1); a20.normalize();

            float3  a01(-1,first->seed[x0][j]-first->seed[i][j],0); a01.normalize();
            float3  a11(0,first->seed[i][j]-first->seed[i][j],0); a11.normalize();
            float3  a21(1,first->seed[x1][j]-first->seed[i][j],0); a21.normalize();

            float3  a02(-1,first->seed[x0][y1]-first->seed[i][j],1); a02.normalize();
            float3  a12(0,first->seed[i][y1]-first->seed[i][j],1); a12.normalize();
            float3  a22(1,first->seed[x1][y1]-first->seed[i][j],1); a22.normalize();

            //result normal
            float3 result=a00*a10+a10*a20+a20*a21+a21*a22+a22*a12+a12*a02+a02*a01+a01*a00;result.normalize();
            norm[i][j]=-1*result;
            }}
first->seed[x0][y1] - это моя карта высот там
Плюс даже из гладкой карты высот получится наждачная бумага вместо приличной карты нормалей, но она довольно легко сглаживается gausian blur'ом

            int radius=32;
            gauss_mask=new float*[radius];
            for(int i=0;i<radius;i++){gauss_mask[i]=new float[radius];}
            for(int i=0;i<radius;i++){
                for(int j=0;j<radius;j++){

                    gauss_mask[i][j]=gaussian_blur(i,j, 12.4);

                }}

float gaussian_blur(int x,int y, float sigma)
{

    float koff=(1/sqrt(2*M_PI*pow(sigma,2)))*pow(M_E,-(x*x+y*y)/(2*sigma*sigma));
    return koff;

}

и после построения маски и применения её к изначальной карте нормалей получался более приличный результат.

        for(int i=0;i<uppersize;i++){
        for(int j=0;j<uppersize;j++){
            for(int x=0;x<radius;x++){
            for(int y=0;y<radius;y++){
              //now will sum all here
              if(x==0 && y==0){normb[i][j]=gauss_mask[x][y]*norm[i][j];}
              else if((x==0 && y!=0) ||(x!=0 && y==0)){
              int x0=i-x,x1=i+x,y0=j-y,y1=j+y;
              if(x0<0){x0=uppersize+x0;}
              if(x1>=uppersize){x1=x1-uppersize;}
              if(y0<0){y0=uppersize+y0;}
              if(y1>=uppersize){y1=y1-uppersize;}
              normb[i][j]=normb[i][j]+ 0.5*gauss_mask[x][y]*(norm[x0][y0]+norm[x1][y0]+norm[x0][y1]+norm[x1][y1]);
              }
              else{
              int x0=i-x,x1=i+x,y0=j-y,y1=j+y;
              if(x0<0){x0=uppersize+x0;}
              if(x1>=uppersize){x1=x1-uppersize;}
              if(y0<0){y0=uppersize+y0;}
              if(y1>=uppersize){y1=y1-uppersize;}
              normb[i][j]=normb[i][j]+gauss_mask[x][y]*(norm[x0][y0]+norm[x1][y0]+norm[x0][y1]+norm[x1][y1]);
              }
            }}
          normb[i][j].normalize();
        }}
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 13:55   #3
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Карта высот из картинки

Нормали я считать умею, а вот карту высот по цветному изображению построить тяжело.
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 13:57   #4
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Карта высот из картинки

Попробую использовать формулу grayscale
Lum := Red 0.299 Green 0.587 Blue 0.114
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 14:06   #5
dsd
Мастер
 
Аватар для dsd
 
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений
(для 1,836 пользователей)
Ответ: Карта высот из картинки

В смысле фотку со спутника к карте высот образовывающей похожий ландшафт привести?
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 14:18   #6
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Карта высот из картинки

Ну похожий явно не получится, но ты понял задачу)
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 14:30   #7
dsd
Мастер
 
Аватар для dsd
 
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений
(для 1,836 пользователей)
Ответ: Карта высот из картинки

А почему нельзя топологическую карту очищенную от мусора использовать? Зря что ли геодезисты с теодолитами ноги по горам ломали? Тем паче, что там есть явная зависимость высоты от цвета, плюс линиями одинаковая высота показана.
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 14:52   #8
Mr_F_
Терабайт исходников
 
Аватар для Mr_F_
 
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений
(для 6,051 пользователей)
Ответ: Карта высот из картинки

если необязательно свой код, то CrazyBump умеет что-то подобное
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 15:02   #9
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Карта высот из картинки

Сообщение от dsd Посмотреть сообщение
А почему нельзя топологическую карту очищенную от мусора использовать? Зря что ли геодезисты с теодолитами ноги по горам ломали? Тем паче, что там есть явная зависимость высоты от цвета, плюс линиями одинаковая высота показана.
не не, у меня не связано с ландшафтом)

Вопрос в экономии ресурсов в проекте. Если например можно не скачивать нормалмэпы с сервера а генерировать.
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
dsd (12.12.2011)
Старый 12.12.2011, 16:27   #10
radiobutton
Бывалый
 
Регистрация: 16.09.2011
Сообщений: 863
Написано 257 полезных сообщений
(для 546 пользователей)
Ответ: Карта высот из картинки

(red+green+blue) /(255*3)
ne?
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 16:36   #11
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Карта высот из картинки

не, grayscale дает лучший эффект в таком случае.
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 12.12.2011, 17:17   #12
dsd
Мастер
 
Аватар для dsd
 
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений
(для 1,836 пользователей)
Ответ: Карта высот из картинки

А если пытаться выделить на текстуре те участки, где цвет меняет оттенок по трем каналам одинаково. То получается, что текущий цвет в пятне/ максимальный цвет в пятне => cos(угол между нормаль текущей точки и нормаль само светлой в пятне(0,1,0)). Потом исходя из расстояния и угла вектора от точки до точки на изображении получать еще один вектор. Потом неведомым образом после разглядывания результата, бааац и нормалмапа?
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо dsd за это полезное сообщение:
LLI.T.A.L.K.E.R. (24.01.2012), pax (12.12.2011)
Старый 12.12.2011, 17:19   #13
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений
(для 5,323 пользователей)
Ответ: Карта высот из картинки

Если получится, то дай знать)))
Я пока остановился на grayscale.
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 20.12.2011, 23:46   #14
dsd
Мастер
 
Аватар для dsd
 
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений
(для 1,836 пользователей)
Ответ: Карта высот из картинки

В рендерманке есть один шейдер, который из

делает:
вершинный
struct VS_OUTPUT {
   float4 Pos: POSITION;
   float2 texCoord: TEXCOORD;
};

VS_OUTPUT main(float4 Pos: POSITION){
   VS_OUTPUT Out;

   // Clean up inaccuracies
   Pos.xy = sign(Pos.xy);

   Out.Pos = float4(Pos.xy, 0, 1);
   // Image-space
   Out.texCoord.x = 0.5 * (1 + Pos.x);
   Out.texCoord.y = 0.5 * (1 - Pos.y);

   return Out;
}

пиксельный
float TextureSize: register(c1);
float4 lightness: register(c0);
sampler BaseMap: register(s0);
// The Sobel filter extracts the first order derivates of the image,
// that is, the slope. The slope in X and Y directon allows us to
// given a heightmap evaluate the normal for each pixel. This is
// the same this as ATI's NormalMapGenerator application does,
// except this is in hardware.
//
// These are the filter kernels:
//
//  SobelX       SobelY
//  1  0 -1      1  2  1
//  2  0 -2      0  0  0
//  1  0 -1     -1 -2 -1

float4 main(float2 texCoord: TEXCOORD) : COLOR {
   float off = 1.0 / TextureSize;

   // Take all neighbor samples
   float4 s00 = tex2D(BaseMap, texCoord + float2(-off, -off));
   float4 s01 = tex2D(BaseMap, texCoord + float2( 0,   -off));
   float4 s02 = tex2D(BaseMap, texCoord + float2( off, -off));

   float4 s10 = tex2D(BaseMap, texCoord + float2(-off,  0));
   float4 s12 = tex2D(BaseMap, texCoord + float2( off,  0));

   float4 s20 = tex2D(BaseMap, texCoord + float2(-off,  off));
   float4 s21 = tex2D(BaseMap, texCoord + float2( 0,    off));
   float4 s22 = tex2D(BaseMap, texCoord + float2( off,  off));

   // Slope in X direction
   float4 sobelX = s00 + 2 * s10 + s20 - s02 - 2 * s12 - s22;
   // Slope in Y direction
   float4 sobelY = s00 + 2 * s01 + s02 - s20 - 2 * s21 - s22;

   // Weight the slope in all channels, we use grayscale as height
   float sx = dot(sobelX, lightness);
   float sy = dot(sobelY, lightness);

   // Compose the normal
   float3 normal = normalize(float3(sx, sy, 1));

   // Pack [-1, 1] into [0, 1]
   return float4(normal * 0.5 + 0.5, 1);
}
NormalMapFilter называется
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
pax (21.12.2011)
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 13:03.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com