Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / [OGL+GLSL] SSAO

[OGL+GLSL] SSAO

Страницы: 1 2 3 Следующая »
RaZORПостоялецwww19 июля 200812:59#0
Пытаюсь сделать ССАО на примере тех шейдеров, что выкладывал товарищ _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.
Заранее спасибо.

SergioУдалёнwww20 июля 200814:02#1
Тут про SSAO не любят распространяться :)

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

RaZORПостоялецwww20 июля 200818:30#2
Думаю, что ошибка все таки где-то в проецировании точек (если бы ошибка была в 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
ОК, давай вместе. Стучи завтра вечером в аську, я сегодня еще подумаю, может что-нибудь придумаю :)

Che@terПостоялецwww21 июля 20082:21#3
незнаю ОГЛ, но набрасыватется сразу:

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???

SergioУдалёнwww21 июля 20089:10#4
Che@ter
>2. Незнаю зачем там координата z оО
Там еще кое-что не используется

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

RaZORПостоялецwww21 июля 20089:18#5
Che@ter
Попробовал, как ты написал, но это особо не на что не повлияло ((

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

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

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

innuendoПостоялецwww21 июля 200810:43#6
RaZOR
float d2 = texture2DRect( normalMap, sample2d.xy).


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

RaZORПостоялецwww21 июля 200810:58#7
ну да, глубину сохраняю в альфа-компоненту текстуры normalMap, расчитываю так
  vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;
  z = pos.z / pos.w * 0.5 + 0.5;

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

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

RaZORПостоялецwww21 июля 200811:06#8
innuendo
или ты имел ввиду правильно ли у меня рассчитываеться sample2d.xy ? если это, то хз. Делаю вроде правильно, но может нужно еще что-то сделать ( например засунуть в clip space ) ?
innuendoПостоялецwww21 июля 200811:18#9
RaZOR
sample2d.xy *= vec2(width, height);

не заметил :)

innuendoПостоялецwww21 июля 200811:26#10
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  уже будет глубина

RaZORПостоялецwww21 июля 200811:30#11
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, в нее глубина пишется вроде нормально ( во всяком случае можно разглядеть едва заметные силуэты)

RaZORПостоялецwww21 июля 200811:33#12

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

издержки производства :)
innuendoПостоялецwww21 июля 200811:35#13
RaZOR

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

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

RaZORПостоялецwww21 июля 200811:43#14
> попробуй через pow( )
попробовал, gl_FragCoor.z выводиться выводится нормально, а та глубина, что считаю вручную - нет.

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

Страницы: 1 2 3 Следующая »

/ Форум / Программирование игр / Графика

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

2001—2018 © GameDev.ru — Разработка игр