dev.gamez.lv Forum Index dev.gamez.lv
Latvian Game Developers Community
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups 

ssao

 
dev.gamez.lv Forum Index -> Grafikas programmēšana un teorija
View previous topic :: View next topic  
Author Message
martini



Joined: 28 Jan 2008
Posts: 2
Location: riga

PostPosted: Sat Apr 10, 2010 6:28 pm    Post subject: ssao

Neizskatās, ka GLSL grafiskā programēšana te būtu īpaši populāra, bet nu ielikšu sev par prieku. GLSL skillu pašmācības ceļā jau kačāju kādu gadu vai divus.

Tātad uzrakstīju diezgan elementāru, bet ātru un efektīvu Screen Space Ambient Occlusion filtru. Tas kas atšķirās no citiem SSAO: Ierastajā box blur vietā sampļus izkārtoju riņķveidā, iegūstot dabiskākas pārejas un samazinot artefaktus. Sampļu mīkstināšanai ģenerēju random tekstūru pašā kodā, nevis izmantoju bildi. Izmantoju luminances tekstūru lai nomaskētu AO vietās kur gaisma ir aktīvāka, jo ambient occlusion dabā ir manāms tikai ēnās.

te ir topiks ko aizsāku iekš BlenderArtists.org:
http://blenderartists.org/forum/showthread.php?t=184102

rezultāts (animēti gifi):




un YouTube viģiks:
http://www.youtube.com/watch?v=R_L-_oGTbqw

Varbūt kādam noder. Latviski mēģināju nokomentēt, bet aptrūkas teminu..
Atstāju angliski, būs vieglāk saprast.

Code:

uniform sampler2D DepthTexture;
uniform sampler2D RenderedTexture;
uniform sampler2D LuminanceTexture;
uniform float RenderedTextureWidth;
uniform float RenderedTextureHeight;

#define PI    3.14159265

float width = RenderedTextureWidth; //texture width
float height = RenderedTextureHeight; //texture height

float near = 1.0; //Z-near
float far = 1000.0; //Z-far

int samples = 3; //samples on the each ring (3-7)
int rings = 3; //ring count (2-8)

vec2 texCoord = gl_TexCoord[0].st;

vec2 rand(in vec2 coord) //generating random noise
{
   float noiseX = (fract(sin(dot(coord ,vec2(12.9898,78.233))) * 43758.5453));
   float noiseY = (fract(sin(dot(coord ,vec2(12.9898,78.233)*2.0)) * 43758.5453));
   return vec2(noiseX,noiseY)*0.004;
}

float readDepth(in vec2 coord) //getting linear depth
{
   return (2.0 * near) / (far + near - texture2D(DepthTexture, coord ).x * (far-near));    
}

float compareDepths( in float depth1, in float depth2 )
{
   float aoCap = 1.0;
   float aoMultiplier = 100.0;
   float depthTolerance = 0.0000;
   float aorange = 60.0;// units in space the AO effect extends to (this gets divided by the camera far range
   float diff = sqrt(clamp(1.0-(depth1-depth2) / (aorange/(far-near)),0.0,1.0));
   float ao = min(aoCap,max(0.0,depth1-depth2-depthTolerance) * aoMultiplier) * diff;
   return ao;
}

void main(void)
{   
   float depth = readDepth(texCoord);
   float d;
   
   float aspect = width/height;
   vec2 noise = rand(texCoord);
   
   float w = (1.0 / width)/clamp(depth,0.05,1.0)+(noise.x*(1.0-noise.x));
   float h = (1.0 / height)/clamp(depth,0.05,1.0)+(noise.y*(1.0-noise.y));
   
   float pw;
   float ph;

   float ao;   
   float s;
   
   for (int i = -rings ; i < rings; i += 1)
   {
      for (int j = -samples ; j < samples; j += 1)
      {
         float step = PI*2.0 / float(samples*i);
         pw = (cos(float(j)*step)*float(i));
         ph = (sin(float(j)*step)*float(i))*aspect;
         d = readDepth( vec2(texCoord.s+pw*w,texCoord.t+ph*h));
         ao += compareDepths(depth,d);   
         s += 1.0;
      }
   }
   
   ao /= s;
   ao = 1.0-ao;   
   
   vec3 color = texture2D(RenderedTexture,texCoord).rgb;
   vec3 luminance = texture2D(LuminanceTexture,texCoord).rgb;
   vec3 white = vec3(1.0,1.0,1.0);
   vec3 black = vec3(0.0,0.0,0.0);
   vec3 treshold = vec3(0.2,0.2,0.2);
   
   luminance = clamp(max(black,luminance-treshold)+max(black,luminance-treshold)+max(black,luminance-treshold),0.0,1.0); //low pass luminance texture for AO mask
   
   gl_FragColor = vec4(color*mix(vec3(ao,ao,ao),white,luminance),1.0);
}


Last edited by martini on Sun Apr 11, 2010 4:13 pm; edited 1 time in total
Back to top
View user's profile Visit poster's website
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Sat Apr 10, 2010 9:14 pm    Post subject:

Vai tad ierasti SSAO lieto box bluru? Cik es esmu pētījis, tad visi visur iesaka tieši lietot apļveida bluru, piemēram, Poisson disku.

Lai nu kā - sanācis ir smuki.
Vēl - īsti nezinu kā ir ar patreizējiem GL draiveriem, bet gadu/divus atpakaļ performances dēļ sin/cos darības bija stipri vēlams prekalkulēt un izmantot kādas tabulas vai tekstūras veidā.
Back to top
View user's profile Send e-mail
martini



Joined: 28 Jan 2008
Posts: 2
Location: riga

PostPosted: Sun Apr 11, 2010 4:13 pm    Post subject:

poisson disku esmu manījis tikai Depth of Field vai Blur filtriem, nevis SSAO.
Bet būs jāpamēģina tas ar.
Re, salīdzinājums manam un defaultajam samplju kārtojumam:

kā redzi piemērā pa labi - tur sampļi tiek izkārtoti pa 8 katrā "riņķī" un rodās problēmas pie lielāka blur rādiusa.

"sin/cos" darbības vismaz uz mana GPU pilnībā neietekmē ātrdarbību. Zinu, ka vienīgi "atan" nedaudz iebremzē.
_________________
http://martinsh.co.nr/
http://artmartinsh.blogspot.com/
Back to top
View user's profile Visit poster's website
Display posts from previous:   
dev.gamez.lv Forum Index -> Grafikas programmēšana un teorija All times are GMT + 2 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group