|
dev.gamez.lv Latvian Game Developers Community
|
View previous topic :: View next topic |
Author |
Message |
martini
Joined: 28 Jan 2008 Posts: 2 Location: riga
|
Posted: 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 |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: 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 |
|
|
martini
Joined: 28 Jan 2008 Posts: 2 Location: riga
|
Posted: 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 |
|
|
|
|
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
|