reflection.glsl 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. TODO
  2. //@renderpasses 0
  3. //based on code by 'cireneikual' found at www.opengl.org - thanks!
  4. //current accum buffer
  5. uniform sampler2D r_SourceBuffer;
  6. uniform vec2 r_SourceBufferSize;
  7. uniform vec2 r_SourceBufferScale;
  8. //deferred buffers
  9. uniform sampler2D r_ColorBuffer;
  10. uniform sampler2D r_NormalBuffer;
  11. uniform sampler2D r_DepthBuffer;
  12. uniform vec2 r_BufferCoordScale;
  13. varying vec2 v_SourceCoords;
  14. varying vec2 v_BufferCoords;
  15. //@vertex
  16. attribute vec2 a_Position;
  17. void main(){
  18. v_SourceCoords=a_Position * r_SourceBufferScale;
  19. v_BufferCoords=a_Position * r_BufferCoordScale;
  20. gl_Position=vec4( a_Position * 2.0 - 1.0,-1.0,1.0 );
  21. }
  22. //@fragment
  23. // Consts should help improve performance
  24. const float rayStep = 0.25;
  25. const float minRayStep = 0.1;
  26. const float searchDist = 5.0;
  27. const float searchDistInv = 0.2;
  28. const float maxDDepth = 1.0;
  29. const float maxDDepthInv = 1.0;
  30. const float reflectionSpecularFalloffExponent = 3.0;
  31. const int maxSteps = 20;
  32. const int numBinarySearchSteps = 5;
  33. float fragmentDepth( vec2 projCoord ){
  34. float dbdepth=texture2D( r_DepthBuffer,projCoord * r_BufferCoordScale ).r;
  35. return viewDepth( dbdepth );
  36. }
  37. vec2 projectedCoord( vec3 hitCoord ){
  38. vec4 projCoord = r_ProjectonMatrix * vec4( hitCoord,1.0 );
  39. projCoord.xy = projCoord.xy / projCoord.w * 0.5 + 0.5;
  40. return projCoord.xy;
  41. }
  42. vec3 binarySearch( vec3 dir,inout vec3 hitCoord,out float dDepth ){
  43. float depth;
  44. for( int i=0;i<numBinarySearchSteps; ++i ){
  45. vec2 projCoord=projectedCoord( hitCoord );
  46. depth=fragmentDepth( projCoord );
  47. dDepth=hitCoord.z-depth;
  48. if( dDepth>0.0 ) hitCoord+=dir;
  49. dir*=0.5;
  50. hitCoord-=dir;
  51. }
  52. vec2 projCoord=projectedCoord( hitCoord );
  53. return vec3( projCoord.xy,depth );
  54. }
  55. vec4 rayCast( vec3 dir,inout vec3 hitCoord,out float dDepth ){
  56. dir*=rayStep;
  57. for( int i=0;i<maxSteps;++i ){
  58. hitCoord+=dir;
  59. vec2 projCoord=projectedCoord( hitCoord );
  60. float depth=fragmentDepth( projCoord );
  61. dDepth=hitCoord.z-depth;
  62. if( dDepth<0.0 ) return vec4( binarySearch( dir,hitCoord,dDepth ),1.0 );
  63. }
  64. return vec4( 0.0 );
  65. }
  66. void main(){
  67. vec4 normal_r=texture2D( r_NormalBuffer,v_BufferCoords );
  68. if( normal_r.a==1.0 ){
  69. gl_FragColor=vec4( 0.0 );
  70. return;
  71. }
  72. vec3 position=fragmentPosition();
  73. vec3 reflected=normalize( reflect( normalize( position ),normalize( normal_r.rgb ) ) );
  74. // Ray cast
  75. vec3 hitPos=viewPos;
  76. float dDepth;
  77. vec4 coords=rayCast( reflected * max(minRayStep, -viewPos.z), hitPos, dDepth );
  78. vec2 dCoords = abs( vec2(0.5, 0.5)-coords.xy );
  79. float screenEdgefactor = clamp( 1.0-( dCoords.x + dCoords.y ),0.0,1.0 );
  80. vec3 color=texture2D( r_ColorBuffer,coords.xy * r_BufferCoordScale ).rgb;
  81. float alpha=
  82. pow( specular, reflectionSpecularFalloffExponent ) *
  83. screenEdgefactor *
  84. clamp( -reflected.z, 0.0, 1.0 ) *
  85. clamp( ( searchDist-length( viewPos-hitPos )) * searchDistInv,0.0,1.0) *
  86. coords.w );
  87. gl_FragColor=vec4( color*alpha,alpha );
  88. }