From 1139c150555a2da1e6234663d69f57143315176d Mon Sep 17 00:00:00 2001 From: ansgar <ansgar@5a81b35b-ba03-0410-adc8-b2c5c5119f08> Date: Sat, 8 May 2010 20:34:01 +0000 Subject: [PATCH] tweaks to ambient occlusion git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/branches/new_gfx@2206 5a81b35b-ba03-0410-adc8-b2c5c5119f08 --- modules/gfx/pymod/export_scene.cc | 5 ++- modules/gfx/src/impl/scene_fx.cc | 16 ++++--- modules/gfx/src/impl/scene_fx.hh | 1 + modules/gfx/src/scene.cc | 14 ++++++- modules/gfx/src/scene.hh | 5 ++- modules/gfx/src/shader/amboccl_fs.glsl | 58 ++++++++++++++++++-------- 6 files changed, 69 insertions(+), 30 deletions(-) diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc index e5e93d5b5..47bd793c0 100644 --- a/modules/gfx/pymod/export_scene.cc +++ b/modules/gfx/pymod/export_scene.cc @@ -120,9 +120,10 @@ void export_Scene() .def("SetShadow",&Scene::SetShadow) .def("SetShadowQuality",&Scene::SetShadowQuality) .def("SetDepthDarkening",&Scene::SetDepthDarkening) - .def("SetDepthDarkeningFactor",&Scene::SetDepthDarkeningFactor) + .def("SetDepthDarkeningWeight",&Scene::SetDepthDarkeningWeight) .def("SetAmbientOcclusion",&Scene::SetAmbientOcclusion) - .def("SetAmbientOcclusionFactor",&Scene::SetAmbientOcclusionFactor) + .def("SetAmbientOcclusionWeight",&Scene::SetAmbientOcclusionWeight) + .def("SetAmbientOcclusionMode",&Scene::SetAmbientOcclusionMode) .def("AttachObserver",&Scene::AttachObserver) .def("StartOffscreenMode",&Scene::StartOffscreenMode) .def("StopOffscreenMode",&Scene::StopOffscreenMode) diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc index 9e32dc329..5b200f274 100644 --- a/modules/gfx/src/impl/scene_fx.cc +++ b/modules/gfx/src/impl/scene_fx.cc @@ -28,6 +28,7 @@ SceneFX::SceneFX(): depth_dark_factor(1.0), amb_occl_flag(false), amb_occl_factor(1.0), + amb_occl_mode(1), scene_tex_id_(), depth_tex_id_(), shadow_tex_id_(), @@ -263,8 +264,7 @@ void SceneFX::Postprocess() glBindTexture(GL_TEXTURE_2D,shadow_tex_id_); glMatrixMode(GL_TEXTURE); glPushMatrix(); - // make explicit object instead of temporary to avoid potential crash with Data() - geom::Mat4 ttmp=Transpose(shadow_tex_mat_); + geom::Mat4 ttmp=geom::Transpose(shadow_tex_mat_); glLoadMatrix(ttmp.Data()); glMatrixMode(GL_MODELVIEW); glActiveTexture(GL_TEXTURE0); @@ -379,7 +379,7 @@ void SceneFX::prep_shadow_map() //glFrustum(tmin[0],tmax[0],tmin[1],tmax[1],-tmax[2],-tmin[2]); float glpmat[16]; glGetv(GL_PROJECTION_MATRIX, glpmat); - geom::Mat4 pmat(Transpose(geom::Mat4(glpmat))); + geom::Mat4 pmat(geom::Transpose(geom::Mat4(glpmat))); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -416,7 +416,7 @@ void SceneFX::prep_shadow_map() //shadow_tex_mat_ = bias*pmat*ltrans.GetMatrix(); Scene::Instance().ResetProjection(); glGetv(GL_PROJECTION_MATRIX, glpmat); - geom::Mat4 pmat2(Transpose(geom::Mat4(glpmat))); + geom::Mat4 pmat2(geom::Transpose(geom::Mat4(glpmat))); /* given the normalized coordinates in scenefx, the camera projection and modelview transformation are first reverted, and then the light modelview and projection are applied, resulting (with the @@ -435,7 +435,6 @@ void SceneFX::prep_amb_occlusion() Shader::Instance().PushProgram(); Shader::Instance().Activate("amboccl"); GLuint cpr=Shader::Instance().GetCurrentProgram(); - // assign tex units glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,depth_tex_id_); glActiveTexture(GL_TEXTURE1); @@ -448,10 +447,15 @@ void SceneFX::prep_amb_occlusion() glUniform1i(glGetUniformLocation(cpr,"kernel"),2); glUniform1f(glGetUniformLocation(cpr,"step"),1.0/static_cast<float>(kernel_size_)); glUniform2f(glGetUniformLocation(cpr,"i_vp"),1.0/static_cast<float>(width),1.0/static_cast<float>(height)); + glUniform1i(glGetUniformLocation(cpr,"mode"),amb_occl_mode); double pm[16]; glGetDoublev(GL_PROJECTION_MATRIX,pm); glUniform4f(glGetUniformLocation(cpr,"abcd"),pm[0],pm[5],pm[10],pm[14]); - + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + geom::Mat4 ipm(geom::Transpose(geom::Invert(geom::Transpose(geom::Mat4(pm))))); + glLoadMatrix(ipm.Data()); + glMatrixMode(GL_MODELVIEW); // set up viewport filling quad to run the fragment shader draw_screen_quad(width,height); diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh index 3048e1d52..f24e4596e 100644 --- a/modules/gfx/src/impl/scene_fx.hh +++ b/modules/gfx/src/impl/scene_fx.hh @@ -56,6 +56,7 @@ public: float depth_dark_factor; bool amb_occl_flag; float amb_occl_factor; + uint amb_occl_mode; private: SceneFX(); diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index c11457597..cad6fc603 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -195,7 +195,7 @@ void Scene::SetDepthDarkening(bool f) #endif } -void Scene::SetDepthDarkeningFactor(float f) +void Scene::SetDepthDarkeningWeight(float f) { #if OST_SHADER_SUPPORT_ENABLED impl::SceneFX::Instance().depth_dark_factor=f; @@ -213,7 +213,7 @@ void Scene::SetAmbientOcclusion(bool f) #endif } -void Scene::SetAmbientOcclusionFactor(float f) +void Scene::SetAmbientOcclusionWeight(float f) { #if OST_SHADER_SUPPORT_ENABLED impl::SceneFX::Instance().amb_occl_factor=f; @@ -222,6 +222,15 @@ void Scene::SetAmbientOcclusionFactor(float f) #endif } +void Scene::SetAmbientOcclusionMode(uint m) +{ +#if OST_SHADER_SUPPORT_ENABLED + impl::SceneFX::Instance().amb_occl_mode=m; + // the redraw routine will deal with the Shader + RequestRedraw(); +#endif +} + void Scene::SetShadingMode(const std::string& smode) { #if OST_SHADER_SUPPORT_ENABLED @@ -241,6 +250,7 @@ void Scene::SetShadingMode(const std::string& smode) } else { Shader::Instance().Activate("fraglight"); } + RequestRedraw(); #endif } diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index 397d2dbb3..1b798d24b 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -112,10 +112,11 @@ class DLLEXPORT_OST_GFX Scene { void SetShadowQuality(int q); void SetDepthDarkening(bool f); - void SetDepthDarkeningFactor(float f); + void SetDepthDarkeningWeight(float f); void SetAmbientOcclusion(bool f); - void SetAmbientOcclusionFactor(float f); + void SetAmbientOcclusionWeight(float f); + void SetAmbientOcclusionMode(uint m); /// \brief select shading mode /// one of fallback, basic, default, hf, toon1, toon2 diff --git a/modules/gfx/src/shader/amboccl_fs.glsl b/modules/gfx/src/shader/amboccl_fs.glsl index 01f7a7217..894290241 100644 --- a/modules/gfx/src/shader/amboccl_fs.glsl +++ b/modules/gfx/src/shader/amboccl_fs.glsl @@ -4,28 +4,51 @@ uniform sampler1D kernel; uniform float step; uniform vec2 i_vp; uniform vec4 abcd; +uniform int mode; -vec3 unproject(in vec3 scr) +vec3 unproject(in vec3 rpos) { - vec3 tmp=vec3(scr.x*i_vp.x*2.0-1.0,scr.y*i_vp.y*2.0-1.0,scr.z); - //float iw = 1.0/(tmp.z/abcd.w+abcd.z/abcd.w); - //return iw*vec3(tmp.x/abcd.x,tmp.y/abcd.y,-1.0); - vec4 tmp2 = gl_ProjectionMatrixInverse*vec4(tmp,1.0); - return tmp2.xyz/tmp2.w; + vec4 coord = gl_TextureMatrix[0]*vec4(rpos.xy*2.0-1.0,rpos.z*2.0-1.0,1.0); + return coord.xyz/coord.w; } -float ao(in vec2 tab, in vec3 pos_p, in vec3 norm_p, in vec3 t_pos_p) +float ao(in vec2 tab, in float depth_p, in vec3 norm_p, in vec3 t_pos_p) { - float depth_q = texture2D(depth_map,gl_TexCoord[0].xy+tab.xy*i_vp).r; - if(depth_q>=1.0) { - return 0.0; - } - vec3 pos_q = vec3(gl_FragCoord.xy+tab.xy,depth_q); - vec3 t_pos_q = unproject(pos_q); + vec2 rpos = gl_TexCoord[0].xy+tab.xy*i_vp; + float depth_q = texture2D(depth_map,rpos).r; + if(mode==0) { + if(depth_q>=depth_p) { + return 0.0; + } else { + return 1.0; + } + } + vec3 t_pos_q = unproject(vec3(rpos.xy,depth_q)); vec3 diff=t_pos_q-t_pos_p; - float fac=1.0+dot(diff,diff)/5.0; - return max(0.0,dot(normalize(norm_p),normalize(diff)))/fac; + float nd = dot(normalize(norm_p),normalize(diff)); + + if(mode==1) { + return 1.6*max(0.0,nd); + } + + if(mode==2) { + float fac=1.0+dot(diff,diff)/100.0; + return 1.6*max(0.0,nd)/fac; + } + + if(mode==3) { + // radius of imposter at distance depth_q to cover a single pixel + vec4 tmpv=gl_TextureMatrix[0]*vec4(-1.0,0.0,depth_q,1.0); + float tmpd=tmpv.x/tmpv.w; + tmpv=gl_TextureMatrix[0]*vec4(1.0,0.0,depth_q,1.0); + // 10.0 is a fudge factor + float rad=10.0*i_vp[0]*abs(tmpv.x/tmpv.w-tmpd); + float s = 6.283*(1.0-sqrt(1.0-min(1.0,rad*rad/dot(diff,diff)))); + return s*max(0.0,nd); + } + + return 0.0; } void main() @@ -36,14 +59,13 @@ void main() return; } vec3 norm_p = (texture2D(norm_map,gl_TexCoord[0].xy).xyz-0.5)*2.0; - vec3 pos_p = vec3(gl_FragCoord.xy,depth_p); - vec3 t_pos_p = unproject(pos_p); + vec3 t_pos_p = unproject(vec3(gl_TexCoord[0].xy,depth_p)); float i; float sum=0.0; for(i=0.0;i<1.0;i+=step) { vec2 nn=texture1D(kernel,i).xy*40.0-20.0; - sum+=ao(nn,pos_p,norm_p,t_pos_p); + sum+=ao(nn,depth_p,norm_p,t_pos_p); } sum*=step; -- GitLab