Войти
ПрограммированиеФорумГрафика

[OGL+GLSL] SSAO

Страницы: 1 2 3 Следующая »
#0
12:59, 19 июля 2008

Пытаюсь сделать ССАО на примере тех шейдеров, что выкладывал товарищ _arwya. (так что не сочтите за плагиат, если увидите что-то знакомое :) ).
Позиции, нормали, цвет и глубина сохраняются в текстуры GL_RGBA32F через MRT.
Вот код шейдеров:

//
// writeGBuffer Vertex shader
//

varying vec4 p;
varying vec3 n;
varying float z;

void main(void)
{
  vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
  gl_Position = pos;
  z = pos.z / pos.w * 0.5 + 0.5; // правильно ли я сохраняю z ????
  p = gl_ModelViewMatrix * gl_Vertex;
  n = gl_Normal;
}

//
// writeGBuffer Fragment shader
//

varying vec4 p;
varying vec3 n;
varying float z;

void main(void)
{
  vec3 nn = normalize(n);

  gl_FragData[0] = vec4(1.0, 1.0, 1.0, 1.0);
  gl_FragData[1] = p;
  gl_FragData[2] = vec4( nn, z);
}
Сам код ССАО:
//
// Fragment Shader SSAO
//

uniform sampler2DRect albedoMap;
uniform sampler2DRect positionMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect depthMap;
uniform mat4 matModelView;
uniform mat4 matProj;
uniform float width, height;

void main(void)
{  

  vec4 clr = texture2DRect( albedoMap, gl_FragCoord.xy );
  vec4 worldPos = texture2DRect( positionMap, gl_FragCoord.xy );
  vec4 normal = texture2DRect( normalMap, gl_FragCoord.xy );
  float depth = texture2DRect( depthMap, gl_FragCoord.xy ).r;
  float z = texture2DRect( normalMap, gl_FragCoord.xy ).a;
  
  const float num_jitters = 14.0;
  vec3 jitters[14] = { 
  vec3(1.0, 0.0, 0.0), 
  vec3(0.0, 1.0, 0.0), 
  vec3(0.0, 0.0, 1.0), 
  vec3(-1.0, 0.0, 0.0), 
  vec3(0.0, -1.0, 0.0), 
  vec3(0.0, 0.0, -1.0), 

  vec3(0.57735,  0.57735,  0.57735), 
  vec3(0.57735,  0.57735,  -0.57735), 
  vec3(0.57735,  -0.57735,  0.57735), 
  vec3(0.57735,  -0.57735,  -0.57735), 

  vec3(-0.57735,  0.57735,  0.57735), 
  vec3(-0.57735,  0.57735,  -0.57735), 
  vec3(-0.57735,  -0.57735,  0.57735), 
  vec3(-0.57735,  -0.57735,  -0.57735) }; 

  
  float ssao_radius = 0.1;
  float passedRays = 0.0, i;
    
  for(i = 0; i < num_jitters; i++ )
  {
    vec3 p = jitters[i]*ssao_radius;
    vec4 sample3d = worldPos + vec4(p, 1.0);
    
    vec4 sample2d = sample3d * matProj;  // умножаем только на GL_PROJECTION матрицу 
    sample2d /= sample2d.w; // перспективное деление
    sample2d.xy = sample2d.xy * 0.5 + 0.5; // переводим в [0; 1]
    sample2d.xy *= vec2(width, height);
    sample2d.z = sample2d.z * 0.5 + 0.5;
    
    float d1 = sample2d.z;
    float d2 = texture2DRect( normalMap, sample2d.xy).a; // здесь лежит z = pos.z / pos.w * 0.5 + 0.5
  
    if ( d1 > d2 ) passedRays += 1.0;
  }

  float shadeFactor = passedRays / num_jitters;
  gl_FragColor = vec4( vec3(clr.rgb) * shadeFactor, 1.0 );

}

Так вот, результатом работы этих шейдеров является белый экран :). Думаю, что ошибка где-то в проецировании точек или в zbuffer - е
(но не могу найти где). Пробовал также делать линейную глубину, но ситуация не изменилась.
Вообщем, I need help.
Заранее спасибо.


#1
14:02, 20 июля 2008

Тут про SSAO не любят распространяться :)

Я вот сейчас тоже его мучаю. Давай разберемся вместе!
Можешь поподробней рассказать ЧТО и КАК надо делать, я попробую и отпишу, если получиться (или не получиться)??

#2
18:30, 20 июля 2008

Думаю, что ошибка все таки где-то в проецировании точек (если бы ошибка была в zbuffer-е то на картинке было бы хоть ЧТО-ТО).

Проецирую так:

vec4 sample2d = sample3d * matProj;  // умножаем только на GL_PROJECTION матрицу 
sample2d /= sample2d.w; // перспективное деление
sample2d.xy = sample2d.xy * 0.5 + 0.5; // переводим в [0; 1]
sample2d.z = sample2d.z * 0.5 + 0.5;
sample2d.xy *= vec2(width, height); // получаем xy в диапозоне 0..width, 0..height
Кроме этого никаких других вычислений делать не надо?

Sergio666
ОК, давай вместе. Стучи завтра вечером в аську, я сегодня еще подумаю, может что-нибудь придумаю :)

#3
2:21, 21 июля 2008

незнаю ОГЛ, но набрасыватется сразу:

1. Заменить sample2d.xy = sample2d.xy * 0.5 + 0.5; // переводим в [0; 1]  на
sample2d=sample2d*0.5;
sample2d.x=sample2d.x+0.5;
sample2d.y=0.5-sample2d.y; // изза этого картинка может рисоваться выше экрана (ЗЕРКАЛЬНО)

2. Незнаю зачем там координата z оО

3. sample2d.xy *= vec2(width, height); // получаем xy в диапозоне 0..width, 0..height  ------ с точки зрения математики это получение нового вектора, перпендикулярного к sample2d.xy и vec2(width, height). Нужно умножать компоненты отдельно

3,5. А разве в ОГЛ нужно переводить в 0..width, 0..height???

#4
9:10, 21 июля 2008

Che@ter
>2. Незнаю зачем там координата z оО
Там еще кое-что не используется

>3,5. А разве в ОГЛ нужно переводить в 0..width, 0..height???
В шейдере используються текстурные координаты по размеру текстуры (т.е не 0..1, а допустим 0..255)

#5
9:18, 21 июля 2008

Che@ter
Попробовал, как ты написал, но это особо не на что не повлияло ((

>sample2d.y=0.5-sample2d.y
в ОГЛ картинку переворачивать не надо )

> А разве в ОГЛ нужно переводить в 0..width, 0..height???
я перевожу, потому что у меня все текстуры NPOTD

А вообще, чтобы проверить правильно ли работает проекция, я спроецировал все точки, которые были сохранены в uniform sampler2DRect positionMap. Картинка рисуется на полэкрана в центре и при этом ее края вытянуты в стороны о__О.
Если проекция правильная, то может быть я не правильно передаю матрицу в шейдер?? делаю так glUniformMatrix4fv(uni_matProj, 1, false, pr);

#6
10:43, 21 июля 2008

RaZOR
float d2 = texture2DRect( normalMap, sample2d.xy).


sample2d.xy - у тебя тут точно (w.h ) ?

#7
10:58, 21 июля 2008

ну да, глубину сохраняю в альфа-компоненту текстуры normalMap, расчитываю так

  vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
  z = pos.z / pos.w * 0.5 + 0.5;

а в samle2d.xy получаем текст.координаты, по которым берем глубину.

Сейчас пробую писать линейную глубину, но результат тот же ((

#8
11:06, 21 июля 2008

innuendo
или ты имел ввиду правильно ли у меня рассчитываеться sample2d.xy ? если это, то хз. Делаю вроде правильно, но может нужно еще что-то сделать ( например засунуть в clip space ) ?

#9
11:18, 21 июля 2008

RaZOR
sample2d.xy *= vec2(width, height);

не заметил :)

#10
11:26, 21 июля 2008

RaZOR
varying vec4 p;
varying vec3 n;
varying float z;

void main(void)
{
  vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
  gl_Position = pos;
  z = pos.z / pos.w * 0.5 + 0.5; // правильно ли я сохраняю z ????
  p = gl_ModelViewMatrix * gl_Vertex;
  n = gl_Normal;
}


хитро :)
p - в eyeSpace, n - просто так? в objspace


> z = pos.z / pos.w * 0.5 + 0.5; // правильно ли я сохраняю z ????

так ведь в FragCoord.z  уже будет глубина

#11
11:30, 21 июля 2008

innuendo
бывает :)

еще возникла проблемка - не могу вывести на экран глубину(ни обычную, ни линейную).

vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
float z = pos.z / pos.w * 0.5 + 0.5; // нелинейная

float z_linear = (z - znear)/(zfar - znear); // линейная

в чем может быть проблема? к MRT прицеплена текстура gl_depth_component, в нее глубина пишется вроде нормально ( во всяком случае можно разглядеть едва заметные силуэты)

#12
11:33, 21 июля 2008


>хитро :)
p - в eyeSpace, n - просто так? в objspace

издержки производства :)

#13
11:35, 21 июля 2008

RaZOR

>еще возникла проблемка - не могу вывести на экран глубину(ни обычную, ни линейную).

попробуй через pow( )

#14
11:43, 21 июля 2008

> попробуй через pow( )
попробовал, gl_FragCoor.z выводиться выводится нормально, а та глубина, что считаю вручную - нет.

а как тогда посчитать глубину точки в ручную? через distance( cameraPos, sample3d) ??

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.