Здравствуйте. Собственно вопрос в следующем.
Давно парился с восстановлением глубины и не мог понять как его сделать корректно. Постоянно некорректно считалась позиция, а как следствие и свет. Но проблема оказалась крайне банальная. А именно время жизни временной переменной (Значение в WorldPos/WorldPos2 всегда будет неверным). Собственно вопрос - почему такое происходит? Аналогичная ситуация если я буду писать в GBuffer.worldPos
Излишние оптимизации компилятора, или же моя невнимательность? Такое странное поведение обнаружил минут 30 назад.
Recons возвращает vec4
void main() { vec2 uv = VERTEXDATA.v_tex_coord; /*GBuffer*/ GBufferInfo GBuffer; DecodeGBufferData( gRT0, gRT1, gRT2, gRT3, gRT4, uv, GBuffer); vec3 lighting = vec3( 0.0); bool bGetNormalizedNormal = true; // INVALID value vec4 worldPos = Recons( LinearizeDepth( GBuffer.LinearDepth), VERTEXDATA.v_tex_coord); for ( int i = 0; i < lights.length( ); ++i) { vec3 normals = unpack_normal( GBuffer.WorldNormal); normals = DecodeNormal( normals); if ( bGetNormalizedNormal) { normals = normalize( normals); } lighting += ComputeLighting ( i, uv, normals, Recons( GBuffer.LinearDepth, VERTEXDATA.v_tex_coord).xyz, // CORRECT, but if send worldPos will incorrect GBuffer ); } // INVALID value vec4 worldPos2 = Recons( LinearizeDepth( GBuffer.LinearDepth), VERTEXDATA.v_tex_coord); ... if ( draw_mode == 3) { // valid //my_FragColor0 = vec4(Recons(GBuffer.LinearDepth, VERTEXDATA.v_tex_coord).xyz, 1.0); vec4 tmp = Recons( GBuffer.LinearDepth, VERTEXDATA.v_tex_coord); // Valid my_FragColor0 = worldPos; // Incorrect } .... else if ( draw_mode == 7) { float d = LinearizeDepth( GBuffer.LinearDepth) / 100.0;; my_FragColor0 = vec4( d, d, d, 1.0); } else my_FragColor0 = vec4( lighting, 1.0); ... }
Видеокарта: Geforce GTX970
Версия видеодрайвера: 398.36
Контекст: 4.6 (#version 460)
NickGastovski
Ошибка либо внутри этой функции:
DecodeGBufferData(gRT0, gRT1, gRT2, gRT3, gRT4, uv, GBuffer);
Либо внутри этой:
LinearizeDepth(GBuffer.LinearDepth)
Либо внутри Recons.
p.s. Либо сразу в нескольких функциях
MrShoor, в том то и дело, что нет. В DecodeGBufferData даже была убрана запись в это поле.
Recons и LinearizeDepth так же валидная. Секунду, возможно я не обратил внимания и сделал лишний вызов по невнимательности
MrShoor, да все оказалось проще - я по невнимательности, пытался использовать линейную глубину там где она была не нужна. Хотя готов поспорить, что пробовал и без нее
Я со вчерашнего дня воюю с другим - изменение позиции, когда на сцене есть двигающиеся объекты. А как следствие проявилось влияние на освещение.
Корректно(физическая симуляция на паузе)
Некорректно:
![]()
Реконструирую так:
vec4 ReconstructWorldPosFromDepth(in float depth, in vec2 uv, in mat4 _inverseMVP) { depth = depth * 2.0 - 1.0; vec4 spos = vec4( _uv * 2.0 - vec2( 1.0), _depth, 1.0); vec4 wpos = _inverseMVP * spos; wpos /= wpos.w; return wpos; }
Где _inverseMVP - inverse(MVP), Depth обычная глубина(gl_FragCoord.z, либо же значение из хардварной карты глубины).
uv и gl_Position - приходит из модельки
layout(location = 0) in vec3 my_Position; layout( location = 5) in vec2 my_Texcoord0; void main( ) { VERTEXDATA.v_tex_coord = my_Texcoord0; gl_Position = vec4( my_Position + instancing_offset, 1.0); }
Как я понимаю, данные в gbuffer'e устаревают и это надо учитывать. Вызов реконструкции осуществляется с обычной глубиной(не линейной)
в шейдерах надо внимательно следить чтобы NaN нигде не вылез, его же даже не проверить толком.
g-cont
> в шейдерах надо внимательно следить чтобы NaN нигде не вылез, его же даже не
> проверить толком.
кхм...
https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/isnan.xhtml
barnes
ну вот на 1.2 этого нет.
barnes
Лет 5 назад прикручивал на gpu алгоритм, активно использующий nan и inf на промежуточных этапах вычислений. Все люто тормозило, и вышло медленнее, чем на CPU, хотя задача отлично параллелилась. Потом я просто заменил inf и nan на магические константы, и все стало летать. Короче gpu и nan плохо дружили лет 5 назад. Сомневаюсь, что сегодня ситуация изменилась.
MrShoor
> Сомневаюсь, что сегодня ситуация изменилась.
Вроде вендоры (nVidia точно, и по AMD тоже что-то было) хвастались, что у них теперь полная поддержка IEEE (nan, inf, денормалы) на полной скорости.
}:+()___ [Smile]
Не прошло и 18 лет
MrShoor
> Короче gpu и nan плохо дружили лет 5 назад. Сомневаюсь, что сегодня ситуация
> изменилась.
может они в софт вываливались? У меня было такое с textureGrad, хотя компилятор упорно молчал.
barnes
> может они в софт вываливались?
В драйверах насколько я знаю обычно болт забивают на вываливание в софт. Это раньше давно была такая практика, когда еще FFP существовал. Да и как оно в софт вывалится в рантайме то?
> У меня было такое с textureGrad, хотя компилятор упорно молчал.
Тут на этапе компилирования textureGrad видно, что можно свалится в софт (и то скорее всего не в софт валилось, а просто эмулировало grad кучей выборок). У меня же были inf-ы и nan-ы - это входные данные, которые приходили с текстурами.
MrShoor
> и то скорее всего не в софт валилось, а просто эмулировало grad кучей выборок
Да, так более верно я думаю. Из похожего было, когда я пытался на старой видяхе в шейдере узнать размер текстуры (для вычисления лодов). Вышло в разы медленнее, чем передача униформа))))
g-count,уточню : позиция меняется, при движении объектов(похоже на наркоманию).
Разве это похоже на NaN?Помнится,что NV крашила драйвер при его выпадении
MrShoor
> а просто эмулировало grad кучей выборок
это как так ?
Тема в архиве.