Advanced Effects

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Advanced Effects

Post by Vectrotek »

Shaders & Shader-Comms, Deferred Rendering, Multi-Pass Effects, Screen-Quads, Physically Based Methods,
Modelling for Irrlicht, Useful Software Titles, Future Plans, and Cool Ideas go here..
(excluding matters that clearly belong in the "Open Discussion and Dev Announcements" forum)
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

SSAO works well for some models..
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

I'll post the project some time but here is the Screen Space Ambient Occlusion Fragment Shader:
(I changed it so that AO Diff Radius decreases as depth increases, it worked, surprisingly)

By the way, If you know "Blender" see this: http://devlog-martinsh.blogspot.co.za/2 ... h-v23.html
and work from there..

Code: Select all

 
 #version 120
 
 uniform sampler2D Image01;       // DEPTH.. RGB ENCODED FOR EXTRA DOMAIN..
 uniform sampler2D Image02;       // RAW DIFFUSE..
 uniform float     BufferWidth;
 uniform float     BufferHeight;
 uniform float     SSAOTweakerNear;
 uniform float     SSAOTweakerFar;
 uniform float     SSAOTweakerRadius;
 uniform float     SSAOTweakerDiffArea;
 uniform float     SSAOTweakerGauseBell;
 
 uniform int       OpSwitch;  // Used to controll general operation for testing and tweaking..
 
 
 #define PI    3.14159265
 float width  = BufferWidth;  //texture width
 float height = BufferHeight; //texture height
 
 //--------------------------------------------------------
 // A list of user parameters
 // These are tweaked from the app by multiplying them with given values..
 // (see the code) 
 float   near         = 0.6;   //Z-near
 float   far          = 150.0; //Z-far
 int     samples      = 5;     //samples on the first ring (3 - 5)
 int     rings        = 5;     //ring count (3 - 5)
 float   radius       = 1.0;   //ao radius
 float   diffarea     = 0.4;   //self-shadowing reduction
 float   gdisplace    = 0.4;   //gauss bell center
 float   lumInfluence = 0.0;   //how much luminance affects occlusion
 bool    noise        = false; //use noise instead of pattern for sample dithering?
 bool    onlyAO       = true;  //use only ambient occlusion pass?
 
 
 //--------------------------------------------------------
 vec2 texCoord = gl_TexCoord[0].st;
 float UnpackedDepth;
 // Unpack what was Packed in the Shader Responsible for rendering the Scene Depth,
 // i.e. "GL_0007_FRAG_GEOMETRY_DEPTH_CLIPPED.glsl"
 float UnPackDepth_002(vec3 RGBDepth) 
  {// return RGBDepth.x + (RGBDepth.y / 255.0);
   return RGBDepth.x + (RGBDepth.y / 255.0) + (RGBDepth.z / 65535.0); // IM NOT SURE THIS IS THE RIGHT WAY TO UNPACK!!!
  }
 
 // If you blur right you could skip noise..
 vec2 rand(in vec2 coord) //generating noise/pattern texture for dithering
  {float noiseX = ((fract(1.0-coord.s*(width/2.0))*0.25)+(fract(coord.t*(height/2.0))*0.75))*2.0-1.0;
   float noiseY = ((fract(1.0-coord.s*(width/2.0))*0.75)+(fract(coord.t*(height/2.0))*0.25))*2.0-1.0;
   if (noise)
    {noiseX = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0;
     noiseY = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0;
    }
   return vec2(noiseX,noiseY) * 0.001;
  }
 //--------------------------------------------------------
 float readDepth(in vec2 coord) 
  {// return (2.0 * near) / (far + near - texture2D(Image01, coord ).x * (far-near));   // ORIGINAL (only R)
   // AHA!!..
   return (2.0 * near) / (far + near - UnPackDepth_002 (texture2D (Image01,coord).rgb) * (far - near)); 
  }
 //--------------------------------------------------------
 float compareDepths(in float depth1, in float depth2,inout int far)
  {float garea = 2.0; // gauss bell width    
   float diff = (depth1 - depth2) * 50.0 ; // depth difference (0-100)
   //reduce left bell width to avoid self-shadowing 
   if (diff < gdisplace) {garea = diffarea;} 
   else {far = 1;}
   float gauss = pow(2.7182,-2.0*(diff-gdisplace)*(diff-gdisplace)/(garea*garea));
   return gauss;
  }  
 //--------------------------------------------------------
 float calAO(float depth,float dw, float dh)
  {// float dd      = (1.0 - depth) * radius; // ORIGINAL (keep around)..
   // I added this because I thought that haveing the AO darkness
   // distance scaled by inverse depth would add a bit of realism..
    float dd      = (1.0 - depth) * radius  * (1.0 - UnpackedDepth );
   // Another version..
   // float dd      = radius  * (1.0 - (UnpackedDepth) );
   // float dd      = (1.0 - UnpackedDepth)*radius ;
   float temp    = 0.0;
   float temp2   = 0.0;
   float coordw  = gl_TexCoord[0].x + dw * dd;
   float coordh  = gl_TexCoord[0].y + dh * dd;
   float coordw2 = gl_TexCoord[0].x - dw * dd;
   float coordh2 = gl_TexCoord[0].y - dh * dd;
   vec2  coord   = vec2(coordw , coordh);
   vec2  coord2  = vec2(coordw2, coordh2);
   int   far     = 0;
   temp = compareDepths(depth, readDepth(coord),far);
   // DEPTH EXTRAPOLATION:
   if (far > 0)
    {temp2 = compareDepths(readDepth(coord2),depth,far);
     temp += (1.0-temp)*temp2;
    }
   return temp;
  } 
 //--------------------------------------------------------
 void main(void)
  {// Packing and Un-Packing from an RGB Encoded Image increases Domain and Quality greatly..
   UnpackedDepth = UnPackDepth_002 (texture2D (Image01,gl_TexCoord[0].xy).rgb);
   // Keeping in mind that our "Ranged" Depth is now from 0 to 1..
   if (UnpackedDepth > 1.0) {UnpackedDepth = 1.0;} // FIX..
 
   // TWEAKING FROM APP..  
   near      *= SSAOTweakerNear;       // Z-near
   far       *= SSAOTweakerFar;        // Z-far
   radius    *= SSAOTweakerRadius;     // ao radius
   diffarea  *= SSAOTweakerDiffArea;   // self-shadowing reduction
   gdisplace *= SSAOTweakerGauseBell;  // gauss bell center
  
   vec2 noise = rand(texCoord); 
   float depth = readDepth(texCoord);
   
   // if (depth > far  ) {gl_FragColor.xyz = vec3 (1.0, 0.0, 0.0) ; return;}
   
   float d;
   float w = (1.0 / width) / clamp(depth,0.25,1.0) + (noise.x * (1.0-noise.x));
   float h = (1.0 / height) / clamp(depth,0.25,1.0) + (noise.y * (1.0-noise.y));
   float pw;
   float ph;
   float ao;
   float s;
   int ringsamples;
   // Version 001 "NO HALO REMOVAL"..
   for (int i = 1; i <= rings; i += 1)
    {ringsamples = i * samples;
     for (int j = 0 ; j < ringsamples ; j += 1)
      {float step = PI * 2.0 / float(ringsamples);
       pw = (cos(float(j) * step) * float(i));
       ph = (sin(float(j) * step) * float(i));
       ao += calAO(depth, pw * w, ph * h);
       s  += 1.0;
      }
    }
    
    
   ao /= s;
   ao = 1.0 - ao;   
   // TRY YOUR PRE-BLUR DIFFUSION HERE!!!!!
   vec3 color = texture2D(Image02,texCoord).rgb;
   // vec3 color = vec3 (1.0, 1.0, 1.0);
   vec3 lumcoeff = vec3(0.299,0.587,0.114);
   float lum = dot(color.rgb, lumcoeff);
   vec3 luminance = vec3(lum, lum, lum);
   if(onlyAO)
    {gl_FragColor = vec4(vec3(mix(vec3(ao),vec3(1.0),luminance*lumInfluence)),1.0); //ambient occlusion only
    }
   else
    {gl_FragColor = vec4(vec3(color*mix(vec3(ao),vec3(1.0),luminance*lumInfluence)),1.0); //mix(color*ao, white, luminance)
    }
 
   // Operational switch the user can set to tweak and experiment..    
   if (OpSwitch == 0) {gl_FragColor = vec4(vec3(ao) , 1.0);}
   if (OpSwitch == 1) {gl_FragColor = vec4(vec3(ao) * vec3(color) , 1.0);}
   if (OpSwitch == 2) {gl_FragColor.xyz = vec3 (texture2D (Image01, gl_TexCoord[0].xy).xyz);}     
   if (OpSwitch == 3) {gl_FragColor.xyz = vec3 (texture2D (Image02, gl_TexCoord[0].xy).xyz);}     
   if (OpSwitch == 4) {gl_FragColor.xyz = vec3 (1.0 - (UnpackedDepth) );}     
  }
 
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

For my Irrlicht projects I like referring to how some things were done in Blender..

Here is the "Bokeh" Shader (with Autofocus Function) changed for Irrlicht:

Code: Select all

 
 
 #version 120
 
 
 #define PI  3.14159265  // Used?
 
 uniform sampler2D Image01;      // Image..
 uniform sampler2D Image02;      // Depth..
 uniform float     BufferWidth;
 uniform float     BufferHeight;
 
 // From App when tweaks done..
 // uniform float focalDepth;  //focal distance value in meters, but you may use autofocus option below
 // uniform float focalLength; //focal length in mm
 // uniform float aperture; //pupil diameter in mm
 // uniform int       showFocus; //show debug focus point and focal range (red = focal point, green = focal range)
 
 float  focalDepth  = 40.0;   // RED focal distance value in meters, but you may use autofocus option below
 float  focalLength = 0.35;  // GREEN (bigger is tighter) focal length in mm
 float  aperture    = 1.5;  //pupil diameter in mm
 
 int    showFocus   = 0;     // Not sure if Irrlicht sends these as BOOLS so I use INT..
 
 float  width       = BufferWidth; //texture width
 float  height      = BufferHeight; //texture height
 vec2   texel       = vec2(1.0 / width, 1.0 / height);
 // Make sure that these two values are the same for your camera, otherwise distances will be wrong.
 float  znear       = 0.05;   //camera clipping start
 float  zfar        = 200.0;  //camera clipping end
 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 //user variables
 
 int    samples     = 3;             // samples on the first ring
 int    rings       = 4;             // Was 4.. ring count
 bool   autofocus   = true;         // use autofocus in shader? disable if you use external focalDepth value
 vec2   focus       = vec2(0.5,0.5); // autofocus point on screen (0.0,0.0 - left lower corner, 1.0,1.0 - upper right)
 float  maxblur     = 1.0;           // clamp value of max blur (0.0 = no blur,1.0 default)
 float  threshold   = 0.5;           // highlight threshold;
 float  gain        = 2.0;           // highlight gain;
 float  bias        = 0.5;           // bokeh edge bias
 float  fringe      = 0.7;           // bokeh chromatic aberration/fringing
 bool   noise       = false;         // use noise instead of pattern for sample dithering
 float  namount     = 0.0001;        // dither amount
 bool   depthblur   = false;         // blur the depth buffer?
 float  dbsize      = 1.25;          // depthblursize
 
 
 // next part is experimental
 // not looking good with small sample and ring count
 // looks okay starting from samples = 4, rings = 4
 
 bool pentagon = false; //use pentagon as bokeh shape?
 float feather = 0.4; //pentagon shape feather
 
 //------------------------------------------
 
 float penta(vec2 coords) //pentagonal shape
  {float scale = float(rings) - 1.3;
    vec4  HS0 = vec4( 1.0,         0.0,         0.0,  1.0);
    vec4  HS1 = vec4( 0.309016994, 0.951056516, 0.0,  1.0);
    vec4  HS2 = vec4(-0.809016994, 0.587785252, 0.0,  1.0);
    vec4  HS3 = vec4(-0.809016994,-0.587785252, 0.0,  1.0);
    vec4  HS4 = vec4( 0.309016994,-0.951056516, 0.0,  1.0);
    vec4  HS5 = vec4( 0.0        ,0.0         , 1.0,  1.0);
    vec4  one = vec4( 1.0 );
    vec4 P = vec4((coords),vec2(scale, scale)); 
    vec4 dist = vec4(0.0);
    float inorout = -4.0;
    dist.x = dot( P, HS0 );
    dist.y = dot( P, HS1 );
    dist.z = dot( P, HS2 );
    dist.w = dot( P, HS3 );
    dist = smoothstep( -feather, feather, dist );
    inorout += dot( dist, one );
    dist.x = dot( P, HS4 );
    dist.y = HS5.w - abs( P.z );
    dist   = smoothstep( -feather, feather, dist );
    inorout += dist.x;
    return clamp( inorout, 0.0, 1.0 );
   }
 float bdepth(vec2 coords) //blurring depth
  {float d = 0.0;
   float kernel[9];
   vec2 offset[9];
   vec2 wh = vec2(texel.x, texel.y) * dbsize;
   offset[0] = vec2(-wh.x,-wh.y);
   offset[1] = vec2( 0.0, -wh.y);
   offset[2] = vec2( wh.x -wh.y);
   offset[3] = vec2(-wh.x,  0.0);
   offset[4] = vec2( 0.0,   0.0);
   offset[5] = vec2( wh.x,  0.0);
   offset[6] = vec2(-wh.x, wh.y);
   offset[7] = vec2( 0.0,  wh.y);
   offset[8] = vec2( wh.x, wh.y);
   kernel[0] = 1.0/16.0;   kernel[1] = 2.0/16.0;   kernel[2] = 1.0/16.0;
   kernel[3] = 2.0/16.0;   kernel[4] = 4.0/16.0;   kernel[5] = 2.0/16.0;
   kernel[6] = 1.0/16.0;   kernel[7] = 2.0/16.0;   kernel[8] = 1.0/16.0;
   for(int i = 0; i < 9; i++ )
    {float tmp = texture2D(Image02, coords + offset[i]).r;
     d += tmp * kernel[i];
    }
   return d;
  }
 
 vec3 color(vec2 coords,float blur) //processing the sample
  {vec3 col = vec3(0.0);
   col.r = texture2D(Image01,coords + vec2(0.0,1.0)*texel*fringe*blur).r;
   col.g = texture2D(Image01,coords + vec2(-0.866,-0.5)*texel*fringe*blur).g;
   col.b = texture2D(Image01,coords + vec2(0.866,-0.5)*texel*fringe*blur).b;
   vec3 lumcoeff = vec3(0.299,0.587,0.114);
   float lum = dot(col.rgb, lumcoeff);
   float thresh = max((lum-threshold)*gain, 0.0);
   return col+mix(vec3(0.0),col,thresh*blur);
  }
 
 vec2 rand(vec2 coord) //generating noise/pattern texture for dithering
  {float noiseX = ((fract(1.0-coord.s*(width/2.0))*0.25)+(fract(coord.t*(height/2.0))*0.75))*2.0-1.0;
   float noiseY = ((fract(1.0-coord.s*(width/2.0))*0.75)+(fract(coord.t*(height/2.0))*0.25))*2.0-1.0;
   if (noise)
    {noiseX = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0;
     noiseY = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0;
    }
   return vec2(noiseX,noiseY);
  }
 
 vec3 debugFocus(vec3 col, float blur)
  {float m = smoothstep(0.0,0.01,blur);
   float e = smoothstep(0.99,1.0,blur);
   float ee = smoothstep(0.97,1.0,blur)-e;
   col = mix(vec3(1.0,0.0,0.0),col,m);
   col = mix(vec3(0.0,1.0,0.0),col,(1.0-ee)-(1.0-e)*0.1);
   return col;
  }
 
 float linearize(float depth)
  {return -zfar * znear / (depth * (zfar - znear) - zfar);
  }
 
 void main() 
  {float blur = 0.0;
   float depth = linearize(texture2D(Image02,gl_TexCoord[0].xy).w);  // IF YOU USE ALPHA MAKE SURE THIS KNOWS IT..
   if (depthblur)
    {depth = linearize(bdepth(gl_TexCoord[0].xy));
    }
   blur = abs(aperture * (focalLength * (depth - focalDepth)) /(depth * (focalDepth - focalLength)));
   if (autofocus)
    {float fDepth = linearize(texture2D(Image02,focus).w); // IF YOU USE ALPHA MAKE SURE THIS KNOWS IT..
     blur = abs(aperture * (focalLength * (depth - fDepth)) /
     (depth * (fDepth - focalLength)));
    }
   blur = clamp(blur,0.0,1.0);
   vec2 noise = rand(gl_TexCoord[0].xy)*namount*blur;
   float w = (1.0/width)*blur*maxblur+noise.x;
   float h = (1.0/height)*blur*maxblur+noise.y;
   vec3 col = texture2D(Image01, gl_TexCoord[0].xy).rgb;
   float s = 1.0;
   int ringsamples;
   for (int i = 1; i <= rings; i += 1)
    {ringsamples = i * samples;
     for (int j = 0 ; j < ringsamples ; j += 1)   
      {float step = PI*2.0 / float(ringsamples);
       float pw = (cos(float(j)*step)*float(i));
       float ph = (sin(float(j)*step)*float(i));
       float p = 1.0;
       if (pentagon)
        {p = penta(vec2(pw,ph));
        }
       col += color(gl_TexCoord[0].xy + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;  
       s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;   
      }
    }
   col /= s;   
   if (showFocus == 1)
    {col = debugFocus(col, blur);
     // col = vec4(1.0, 0.0 ,1.0, 1.0); // just checking..
    }
   // OVERRIDE FOCAL DEBUG VISUALISATION..
   // col = debugFocus(col, blur);
   gl_FragColor.rgb = col;
   // gl_FragColor.rgb = vec3 (depth,depth,depth);
   gl_FragColor.a = 1.0;
  }
  
 // END..
 
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Hammering on SSAO a bit here but this LEGO model rendered quite fast in Irrlicht considering
that all tens of thousands of the polygons for all the pieces are present (even if you cant see them)!
There must be a plugin for blender somewhere to get rid of unseen polygons!
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Really having fun.
Image
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Advanced Effects

Post by thanhle »

Why is it white at the edge but dark on the surface?
Can you invert so that it is slightly dark at the edge by white on the surface? I want to see what different it makes.

Nice work,
cheers
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Its just the SSAO settings..
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Discovered LDRAW etc etc, Lego Modelling system, which is very cool but there is a problem..
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Just get this lovely model into Blender convert to *.obj and render?
Image
!! What happened to the frame-rate?
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

This happened..
Image
Each end every polygon (even those not seen) gets
exported! So what now?
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Just select the the "Invisible" polygons and delete them..
Image
No problem, but at about Polygon 753534 it gets a bit tedious..
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

I won't be watching the next Lego movie with the same pair of eyes again..

So if anyone gets hardware occlusion to disable polygons in a plugin for Blender please let me know..

Perhaps just make a convex cage of some sort and then bake the normals onto it?

Anyhow, I did one and I wont be doing more..
Image
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Re: Advanced Effects

Post by Virion »

Looks good. Should post it in screenshot competition thread haha
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Advanced Effects

Post by Vectrotek »

Thanks! :)
Post Reply