Advertisement
Guest User

Compute shader

a guest
Jan 15th, 2015
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.06 KB | None | 0 0
  1. #version 430 core
  2. layout (local_size_x = 16, local_size_y = 16) in;
  3.  
  4. // ---- Structs ----
  5. struct vector3 { float x, y, z; };
  6. struct DirectionalLight { vector3 Direction; vector3 Intensity; vector3 Color; };
  7. struct Pointlight { vector3 Position; vector3 Intensity; vector3 Color; float Range; };
  8.  
  9. // ---- INPUTS ----
  10. uniform sampler2D DepthTex;
  11. uniform sampler2DShadow ShadowDepthTex;
  12. layout (rgba32f, binding = 0) uniform readonly image2D NormalTex;
  13. layout (rgba8, binding = 1) uniform readonly image2D ColorTex;
  14. layout (rgba8, binding = 2) uniform readonly image2D RandomTex;
  15. layout (std430, binding = 3) buffer DirectionalLights { DirectionalLight directionalLight; };
  16. layout (std430, binding = 4) buffer PointLights { Pointlight pointlights[]; };
  17.  
  18. // ---- OUTPUT ----
  19. layout (rgba32f, binding = 5) uniform image2D output_image;
  20.  
  21. // ---- Uniforms ----
  22. uniform mat4 ViewMatrix;
  23. uniform mat4 InvProjection;
  24. uniform mat4 BiasMatrix;
  25. uniform mat4 ShadowViewProj;
  26.  
  27. // ---- PER THREAD GLOBALS ----
  28. ivec2 g_threadID; // sample pixel position
  29. vec3 g_viewPos; // position in view space
  30. vec3 g_albedo; // albedo color (ColorTex.xyz)
  31. vec3 g_normal; // normal (NormalTex.xy, haxx)
  32. float g_ks; // spec (NormalTex.z)
  33. float g_shininess; // spec (NormalTex.w)
  34. float g_depthVal; // depthval (DepthTex.x)
  35.  
  36. // ---- FUNCTION DEFINES ----
  37. vec2 getRandom();
  38. vec3 getPosition(ivec2 samplePos);
  39. float doAmbientOcclusion( vec2 offset );
  40. float ComputeSSAO();
  41. float ComputeGlow();
  42.  
  43. void ComputeDirLight(out vec3 ambient, out vec3 diffuse, out vec3 spec);
  44.  
  45. void phongModelDirLight(out vec3 ambient, out vec3 diffuse, out vec3 spec);
  46. void phongModel(int index, out vec3 ambient, out vec3 diffuse, out vec3 spec);
  47. vec3 reconstructPosition(float p_depth);
  48.  
  49. // ---- MAIN ----
  50. void main()
  51. {
  52. vec4 FragColor = vec4(0.0);
  53.  
  54. // Get threadID
  55. g_threadID = ivec2( gl_GlobalInvocationID.x, gl_GlobalInvocationID.y );
  56.  
  57. // Retrieve position, normal and color information from the g-buffer textures
  58. vec4 inputMap0 = texelFetch(DepthTex, g_threadID, 0);
  59. vec4 inputMap1 = imageLoad(NormalTex, g_threadID);
  60. vec4 inputMap2 = imageLoad(ColorTex, g_threadID);
  61.  
  62. // Set globals
  63. g_normal.xy = inputMap1.xy;
  64.  
  65. g_ks = inputMap1.z;
  66. if(inputMap1.w < 0.5)
  67. {
  68. g_normal.z = sqrt( 1 - (g_normal.x*g_normal.x) - (g_normal.y*g_normal.y) );
  69. g_shininess = inputMap1.w * 508.0f + 1.0f;
  70. }
  71. else
  72. {
  73. g_normal.z = sqrt( 1 - (g_normal.x*g_normal.x) - (g_normal.y*g_normal.y) );
  74. g_normal.z *= -1;
  75. g_shininess = (inputMap1.w - 0.5) * 508.0f + 1.0f;
  76. }
  77.  
  78. g_albedo.xyz = inputMap2.xyz;
  79. g_depthVal = inputMap0.x;
  80. g_viewPos = reconstructPosition(g_depthVal);
  81.  
  82.  
  83.  
  84. // Values
  85. vec3 ambient = vec3(0.0);
  86. vec3 diffuse = vec3(0.0);
  87. vec3 spec = vec3(0.0);
  88.  
  89. if((g_depthVal < 1.0))
  90. {
  91. // Calc DirLight
  92. ComputeDirLight(ambient, diffuse, spec);
  93.  
  94. // Calc PointLights
  95. for(int i = 0; i < pointlights.length(); i++)
  96. {
  97. vec3 a,d,s;
  98.  
  99. phongModel(i, a, d, s);
  100. ambient += a;
  101. diffuse += d;
  102. spec += s;
  103. }
  104. }
  105.  
  106. // Do post renderer effect here
  107. float glow = ComputeGlow();
  108. vec4 glowvec = vec4(glow,glow,glow, 1.0);
  109. float SSAO = ComputeSSAO();
  110. vec4 SSAOvec = vec4(SSAO,SSAO,SSAO, 1.0);
  111.  
  112.  
  113. // Do frag calcs here
  114. FragColor = vec4(ambient + diffuse, 1.0) * vec4(g_albedo, 1.0) * SSAOvec + vec4(spec, 0.0f) + glowvec;
  115. //FragColor = glowvec;
  116. //FragColor = SSAOvec;
  117. //FragColor = vec4( g_normal, 1.0);
  118. //FragColor = vec4( g_albedo +g_normal-g_normal , 1.0 )-vec4( g_albedo +g_normal-g_normal , 1.0 ) +SSAOvec +glowvec-glowvec;
  119. //FragColor = vec4( vec3(g_normal + g_viewPos-g_viewPos +g_albedo-g_albedo), 1.0 ) + SSAOvec-SSAOvec +glowvec-glowvec;
  120. //FragColor = vec4( vec3(g_depthVal), 1.0 );
  121.  
  122. imageStore(
  123. output_image,
  124. ivec2(gl_GlobalInvocationID.xy),
  125. FragColor
  126. );
  127. }
  128.  
  129.  
  130.  
  131. //---- FUNCTIONS ----
  132.  
  133. float ComputeGlow()
  134. {
  135. // IMPROVEMENTS CAN BE MADE. RIGHT NOW WE SAMPLE IN A SPIRAL. BETTER SOLUTION WOULD BE TO DO 2 SAMPLES AFTER EACHOTHER. BUT THIS WOULD NEED A NEW TEXTURE MAP AND A BARRIER. AND COST MORE.
  136. /*
  137. - - - - - - 5 - - - - - -
  138. - - - - - - - - - - 6 - -
  139. - - - 4 - - - - - - - - -
  140. - - - - - - - - - - - - -
  141. - - - - - - 1 2 - - - - -
  142. 7 - - 3 - - 0 - - 3 - - 7
  143. - - - - - 2 1 - - - - - -
  144. - - - - - - - - - - - - -
  145. - - - - - - - - - 4 - - -
  146. - - 6 - - - - - - - - - -
  147. - - - - - - 5 - - - - - -
  148. */
  149. float glow = 0;
  150. //glow += imageLoad(ColorTex, g_threadID + ivec2(-6, 0)).w * 0.0044299121055113265;
  151. //glow += imageLoad(ColorTex, g_threadID + ivec2(-4, -4)).w * 0.00895781211794;
  152. //glow += imageLoad(ColorTex, g_threadID + ivec2(0, -5)).w * 0.0215963866053;
  153. //glow += imageLoad(ColorTex, g_threadID + ivec2(3, -3)).w * 0.0443683338718;
  154. //glow += imageLoad(ColorTex, g_threadID + ivec2(-3, 0)).w * 0.0776744219933;
  155. //glow += imageLoad(ColorTex, g_threadID + ivec2(-1, -1)).w * 0.115876621105;
  156. //glow += imageLoad(ColorTex, g_threadID + ivec2(0, -1)).w * 0.147308056121;
  157. //glow += imageLoad(ColorTex, g_threadID).w * 0.159576912161;
  158. //glow += imageLoad(ColorTex, g_threadID + ivec2(0, 1)).w * 0.147308056121;
  159. //glow += imageLoad(ColorTex, g_threadID + ivec2(1, 1)).w * 0.115876621105;
  160. //glow += imageLoad(ColorTex, g_threadID + ivec2(3, 0)).w * 0.0776744219933;
  161. //glow += imageLoad(ColorTex, g_threadID + ivec2(-3, 3)).w * 0.0443683338718;
  162. //glow += imageLoad(ColorTex, g_threadID + ivec2(0, 5)).w * 0.0215963866053;
  163. //glow += imageLoad(ColorTex, g_threadID + ivec2(4, 4)).w * 0.00895781211794;
  164. //glow += imageLoad(ColorTex, g_threadID + ivec2(6, 0)).w * 0.0044299121055113265;
  165.  
  166. return glow;
  167. }
  168.  
  169. vec3 getPosition(ivec2 samplePos)
  170. {
  171. float depthVal = texelFetch(DepthTex, samplePos, 0).x;
  172.  
  173.  
  174. vec2 ndc = vec2(samplePos) / (vec2( gl_WorkGroupSize.xy*gl_NumWorkGroups.xy) ) * 2.0f - 1.0f;
  175.  
  176. vec4 H = vec4(
  177. ndc,
  178. depthVal * 2.0 - 1.0,
  179. 1.0
  180. );
  181.  
  182. vec4 D = InvProjection * H;
  183. return (D.xyz / D.w);
  184. }
  185.  
  186. vec2 getRandom()
  187. {
  188. return normalize( imageLoad(RandomTex, ivec2(gl_LocalInvocationID.xy)).xy * 2.0f - 1.0f );
  189. }
  190.  
  191.  
  192. float doAmbientOcclusion( vec2 offset )
  193. {
  194. float g_scale = 1.6;
  195. float g_intensity = 3;
  196. float g_bias = 0.25;
  197.  
  198. offset = offset * vec2(gl_WorkGroupSize.xy*gl_NumWorkGroups.xy);
  199.  
  200. ivec2 ssaoSamp;
  201. ssaoSamp.x = int(min(max(g_threadID.x + ivec2(offset).x, 0), gl_WorkGroupSize.x*gl_NumWorkGroups.x-1));
  202. ssaoSamp.y = int(min(max(g_threadID.y + ivec2(offset).y, 0), gl_WorkGroupSize.y*gl_NumWorkGroups.y-1));
  203.  
  204. vec3 diff = getPosition(ssaoSamp) - g_viewPos;
  205.  
  206. if(diff.z > 0.25)
  207. return 0.0;
  208.  
  209. vec3 v = normalize(diff);
  210. float d = length(diff)*g_scale;
  211. return max(0.0,dot(g_normal,v)-g_bias)*(1.0/(1.0+d))*g_intensity;
  212. }
  213.  
  214. float ComputeSSAO()
  215. {
  216. float g_sample_rad = 0.18;
  217. vec2 vec[4] = { vec2(1,0), vec2(-1,0), vec2(0,1), vec2(0,-1) };
  218.  
  219. vec2 rand = getRandom();
  220.  
  221. float ao = 0.0f;
  222. float rad = g_sample_rad/g_viewPos.z;
  223.  
  224. //SSAO Calculation
  225. for (int j = 0; j < 4; ++j)
  226. {
  227. vec2 coord1 = vec2(reflect(vec[j],rand)*rad);
  228. vec2 coord2 = vec2(coord1.x*0.707 - coord1.y*0.707, coord1.x*0.707 + coord1.y*0.707);
  229.  
  230. ao += doAmbientOcclusion(coord1*0.25);
  231. ao += doAmbientOcclusion(coord2*0.5);
  232. ao += doAmbientOcclusion(coord1*0.75);
  233. ao += doAmbientOcclusion(coord2);
  234. }
  235.  
  236. ao/= 16;
  237.  
  238. return 1-ao;
  239. }
  240.  
  241. void ComputeDirLight(out vec3 ambient, out vec3 diffuse, out vec3 spec)
  242. {
  243. if(length( vec3(directionalLight.Intensity.x, directionalLight.Intensity.y, directionalLight.Intensity.z) ) > 0.0)
  244. {
  245. vec3 a = vec3(0.0);
  246. vec3 d = vec3(0.0);
  247. vec3 s = vec3(0.0);
  248. phongModelDirLight(a, d, s);
  249. ambient = a;
  250. diffuse = d;
  251. spec = s;
  252. }
  253. }
  254. void phongModelDirLight(out vec3 ambient, out vec3 diffuse, out vec3 spec)
  255. {
  256. ambient = vec3(0.0);
  257. diffuse = vec3(0.0);
  258. spec = vec3(0.0);
  259.  
  260. vec3 thisLightDirection = vec3(directionalLight.Direction.x, directionalLight.Direction.y, directionalLight.Direction.z);
  261. vec3 thisLightColor = vec3(directionalLight.Color.x, directionalLight.Color.y, directionalLight.Color.z);
  262. vec3 thisLightIntensity = vec3(directionalLight.Intensity.x, directionalLight.Intensity.y, directionalLight.Intensity.z);
  263.  
  264. vec3 lightVec = -normalize(( ViewMatrix*vec4(thisLightDirection, 0.0) ).xyz);
  265.  
  266. ambient = thisLightColor * thisLightIntensity.x;
  267.  
  268. vec3 E = normalize(g_viewPos);
  269.  
  270. float diffuseFactor = dot( lightVec, g_normal );
  271.  
  272. if(diffuseFactor > 0)
  273. {
  274. // For shadows
  275. vec4 worldPos = inverse(ViewMatrix) * vec4(g_viewPos, 1.0);
  276. vec4 shadowCoord = BiasMatrix * ShadowViewProj * worldPos;
  277. float shadow = 1.0;// = textureProj(ShadowDepthTex, shadowCoord);
  278. // The sum of the comparisons with nearby texels
  279. float sum = 0;
  280. // Sum contributions from texels around ShadowCoord
  281. sum += textureProjOffset(ShadowDepthTex, shadowCoord, ivec2(-1,-1));
  282. sum += textureProjOffset(ShadowDepthTex, shadowCoord, ivec2(-1,1));
  283. sum += textureProjOffset(ShadowDepthTex, shadowCoord, ivec2(1,1));
  284. sum += textureProjOffset(ShadowDepthTex, shadowCoord, ivec2(1,-1));
  285.  
  286. float shadowResult = sum * 0.25;
  287. float bias = min( pow(shadowCoord.z, 10 - 10*shadowCoord.z), 0.40);
  288.  
  289. if ( shadowResult < (shadowCoord.z - bias)/shadowCoord.w)
  290. {
  291. shadow = shadowResult;
  292. }
  293.  
  294. // diffuse
  295. diffuse = diffuseFactor * thisLightColor * thisLightIntensity.y * shadow;
  296.  
  297. // specular
  298. vec3 v = reflect( lightVec, g_normal );
  299. float specFactor = pow( max( dot(v, E), 0.0 ), g_shininess );
  300. spec = specFactor * thisLightColor * thisLightIntensity.z * g_ks * shadow;
  301. }
  302.  
  303. return;
  304. }
  305.  
  306. void phongModel(int index, out vec3 ambient, out vec3 diffuse, out vec3 spec)
  307. {
  308. ambient = vec3(0.0);
  309. diffuse = vec3(0.0);
  310. spec = vec3(0.0);
  311.  
  312. vec3 thisLightPosition = vec3(pointlights[index].Position.x, pointlights[index].Position.y, pointlights[index].Position.z);
  313. vec3 thisLightColor = vec3(pointlights[index].Color.x, pointlights[index].Color.y, pointlights[index].Color.z);
  314. vec3 thisLightIntensity = vec3(pointlights[index].Intensity.x, pointlights[index].Intensity.y, pointlights[index].Intensity.z);
  315.  
  316. vec3 lightVec = (ViewMatrix * vec4(thisLightPosition, 1.0)).xyz - g_viewPos;
  317.  
  318. float d = length(lightVec);
  319.  
  320. if(d > pointlights[index].Range)
  321. return;
  322. lightVec /= d; //normalizing
  323.  
  324.  
  325. ambient = thisLightColor * thisLightIntensity.x;
  326.  
  327. vec3 E = normalize(g_viewPos);
  328.  
  329. float diffuseFactor = dot( lightVec, g_normal );
  330.  
  331. if(diffuseFactor > 0)
  332. {
  333. // diffuse
  334. diffuse = diffuseFactor * thisLightColor * thisLightIntensity.y;
  335.  
  336. // specular
  337. vec3 v = reflect( lightVec, g_normal );
  338. float specFactor = pow( max( dot(v, E), 0.0 ), g_shininess );
  339. spec = specFactor * thisLightColor * thisLightIntensity.z * g_ks;
  340. }
  341.  
  342. float att = 1 - pow((d/pointlights[index].Range), 1.0f);
  343.  
  344. ambient *= att;
  345. diffuse *= att;
  346. spec *= att;
  347.  
  348. return;
  349. }
  350.  
  351. vec3 reconstructPosition(float p_depth)
  352. {
  353. vec2 ndc = vec2(g_threadID) / vec2( gl_WorkGroupSize.xy*gl_NumWorkGroups.xy ) * 2.0f - 1.0f;
  354.  
  355. vec4 sPos = vec4(ndc, p_depth*2.0f - 1.0f, 1.0);
  356. sPos = InvProjection * sPos;
  357.  
  358. return (sPos.xyz / sPos.w);
  359. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement