Advertisement
Guest User

Untitled

a guest
Nov 20th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.11 KB | None | 0 0
  1. #version 430 core
  2. #extension GL_ARB_compute_shader : enable
  3. #extension GL_ARB_shader_image_load_store : enable
  4.  
  5. // output of compute shader is a TEXTURE
  6. layout(rgba32f, binding = 0) uniform image2D outTexture;
  7.  
  8.  
  9. // receive as inputs, rays from the centre of the camera to the frustum corners
  10. layout( location = 0 ) uniform vec4 ray00; // top left in world space
  11. layout( location = 1 ) uniform vec4 ray01; // top right in world space
  12. layout( location = 2 ) uniform vec4 ray10; // bottom left in world space
  13. layout( location = 3 ) uniform vec4 ray11; // bottom right in world space
  14.  
  15. // receive the camera position
  16. layout( location = 4 ) uniform vec3 camPos; // camera position
  17.  
  18. // receive how many primitives of each type
  19. // geomCount.x = number of spheres
  20. // geomCount.y = number of triangles
  21. // geomCount.z = number of planes
  22. // geomCount.w = number of obbs
  23. layout( location = 5 ) uniform ivec4 geomCount; // sphere, triangle, planes, obbs
  24.  
  25. // how many lights to process (how many elements in the array "light")
  26. layout( location = 6 ) uniform int lightCount;
  27.  
  28. // receive an ARRAY of light_type,
  29. struct light_type {
  30. vec4 position;
  31. vec4 colour;
  32. };
  33. layout(std430, binding = 2) buffer light
  34. {
  35. light_type lights_data[];
  36. };
  37.  
  38. struct sphere_type {
  39. vec4 centre_radius;
  40. vec4 colour;
  41. };
  42. // 8 floats per sphere: c cy cz rad r g b a
  43. layout(std430, binding = 3) buffer sphere
  44. {
  45. sphere_type spheres_data[];
  46. };
  47.  
  48. struct plane_type {
  49. vec4 normal_d;
  50. vec4 colour;
  51. };
  52. // 8 floats per plane: nx ny nz d r g b a
  53. layout(std430, binding = 4) buffer plane
  54. {
  55. plane_type planes_data[];
  56. };
  57.  
  58. struct triangle_type {
  59. vec4 vtx0, vtx1, vtx2;
  60. vec4 colour;
  61. };
  62. layout(std430, binding = 5) buffer triangle
  63. {
  64. triangle_type triangles_data[];
  65. };
  66.  
  67. // 20 floats per obb: centre4, u3, hu, v3, hv, w3, hw, rgba4
  68. struct obb_type {
  69. vec4 centre, u_hu, v_hv, w_hw, colour;
  70. };
  71. layout(std430, binding = 6) buffer obb
  72. {
  73. obb_type obb_data[];
  74. };
  75.  
  76. layout (local_size_x = 20, local_size_y = 20) in;
  77.  
  78. #define SPHERE_TYPE 0
  79. #define LIGHT_TYPE 1
  80. #define PLANE_TYPE 2
  81. #define TRIANGLE_TYPE 3
  82. #define OBB_TYPE 4
  83.  
  84. // primitives tests forward declarations
  85. float sphereTest(vec3 rayDir, vec3 rayOrigin, vec4 centre_radius);
  86. float planeTest(vec3 rayDir, vec3 rayOrigin, vec4 plane_info);
  87. float triangleTest(vec3 rayDir, vec3 rayOrigin, triangle_type tri);
  88. float obbTest(vec3 rayDir, vec3 rayOrigin, obb_type obb);
  89.  
  90. // entire scene test forward declaration
  91. void sceneTest(in vec4 ray_dir, inout float lastT, inout int objIndex, inout int objType);
  92.  
  93. // shade a point of a surface (for any primitive) forward declaration
  94. vec4 shade(in vec3 pointOnSurface, in vec3 normal, in vec3 colour);
  95.  
  96. vec4 castRay(ivec2 pos)
  97. {
  98. // normalise values from [ 0,width; 0,height ] to [ 0,1; 0,1]
  99. vec2 interp = vec2(pos) / imageSize(outTexture);
  100.  
  101. // compute ray as interpolation of input rays (corners)
  102. vec4 ray_dir = normalize(
  103. mix(
  104. mix(ray00,ray01,interp.y), // left corners together
  105. mix(ray10,ray11,interp.y), // right corners together
  106. interp.x // join new interpolated rays into a final ray
  107. )
  108. );
  109.  
  110. // lastT is the last intersection found (will keep the closest value)
  111. float lastT=-1;
  112. // will remember which object index was hit if any.
  113. int objIndex = -1;
  114. // will remember which object type was hit if any.
  115. int objType = -1;
  116.  
  117. // do ray versus scene test
  118. sceneTest(ray_dir, lastT, objIndex, objType);
  119.  
  120. vec3 pointOnSurface = ray_dir.xyz * lastT;
  121. // set pixel to BACKGROUND colour
  122. vec4 finalPixelOut = vec4(0.2,0.2,0.2, 1.0);
  123.  
  124. if (objIndex >= 0) {
  125.  
  126. // did we hit something?
  127.  
  128. // IMPLEMENT HERE.
  129. // FIND POINT IN SPACE WHERE THE INTERSECTION HAPPENED.
  130. vec3 pointOnSurface;
  131. if (objType==SPHERE_TYPE)
  132. {
  133. // IMPLEMENT HERE
  134. // COMPUTE FINAL PIXEL COLOUR USING SHADE() FUNCTION
  135. finalPixelOut = shade(pointOnSurface, spheres_data[objIndex].centre_radius.xyz,finalPixelOut.xyz);
  136. }
  137. else if (objType==LIGHT_TYPE)
  138. {
  139. // IMPLEMENT HERE.
  140. // LIGHTS ARE DRAWN AS SPHERES, JUST GIVE A CONSTANT COLOUR TO IT.
  141. // DO NOT SHADE WITH SHADE() FUNCTION.
  142. finalPixelOut = vec4(1.0,1.0,1.0,1.0);
  143. }
  144. else if (objType == PLANE_TYPE)
  145. {
  146. // IMPLEMENT HERE
  147. // COMPUTE FINAL PIXEL COLOUR USING SHADE() FUNCTION
  148. finalPixelOut = shade(pointOnSurface, planes_data[objIndex].normal_d.xyz,finalPixelOut.xyz);
  149. }
  150. else if (objType == TRIANGLE_TYPE)
  151. {
  152.  
  153. // IMPLEMENT HERE
  154. // COMPUTE FINAL PIXEL COLOUR USING SHADE() FUNCTION
  155. vec3 normal = cross(triangles_data[objIndex].vtx1.xyz - triangles_data[objIndex].vtx0.xyz, triangles_data[objIndex].vtx2.xyz - triangles_data[objIndex].vtx0.xyz);
  156. finalPixelOut = shade(pointOnSurface, normal,finalPixelOut.xyz);
  157. }
  158. else if (objType == OBB_TYPE)
  159. {
  160. // IMPLEMENT HERE
  161. // COMPUTE FINAL PIXEL COLOUR USING SHADE() FUNCTION
  162. float epsilon = 0.0001;
  163. obb_type obb = obb_data[objIndex];
  164. vec3 normal;
  165. bool normalFound = false;
  166.  
  167. vec4 vecArr[3];
  168. vecArr[0] = obb.u_hu;
  169. vecArr[1] = obb.v_hv;
  170. vecArr[2] = obb.w_hw;
  171.  
  172. for(int i = 0; i < 3 && normalFound == false; i++)
  173. {
  174. vec3 n = normalize(vecArr[i].xyz);
  175. vec3 centreToFace = n * vecArr[i].w;
  176. vec3 pointOnFace = obb.centre.xyz + centreToFace;
  177.  
  178. if(abs(dot(pointOnSurface - pointOnFace, n)) < epsilon)
  179. {
  180. normalFound = true;
  181. normal = n;
  182. }
  183. }
  184.  
  185. finalPixelOut = shade(pointOnSurface, normal, finalPixelOut.xyz);
  186. }
  187. }
  188. return finalPixelOut;
  189. }
  190.  
  191. layout (local_size_x = 20, local_size_y = 20) in;
  192. void main()
  193. {
  194. // pixel coordinate, x in [0,width-1], y in [0,height-1]
  195. ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
  196. vec4 finalPixel = castRay(pos);
  197. imageStore(outTexture, pos, finalPixel);
  198. return;
  199. };
  200.  
  201. void sceneTest(in vec4 ray_dir,inout float lastT, inout int objIndex, inout int objType)
  202. {
  203.  
  204. // use camPos to know where is the ray origin.
  205. // example:
  206. float testT;
  207. // test all spheres (in geomCount.x)
  208. for (int i=0;i< geomCount.x;i++)
  209. {
  210. sphere_type sphere = spheres_data[i];
  211. testT = sphereTest(ray_dir.xyz, camPos, sphere.centre_radius);
  212. if(testT != -1){
  213. if(testT < lastT || lastT == -1){
  214. lastT = testT;
  215. objType = SPHERE_TYPE;
  216. objIndex = i;
  217. }
  218. }
  219. // IMPLEMENT HERE.
  220. // TEST SPHERE, UPDATE lastT, objIndex and objType if necessary.
  221. }
  222. // lights (we render lights as spheres)
  223. for (int i=0;i<lightCount;i++)
  224. {
  225. light_type light = lights_data[i];
  226.  
  227. testT = sphereTest(ray_dir.xyz, camPos, light.position);
  228. if(testT != -1){
  229. if(testT < lastT || lastT == -1){
  230. lastT = testT;
  231. objType = SPHERE_TYPE;
  232. objIndex = i;
  233. }
  234. }
  235. // IMPLEMENT HERE.
  236. // TEST SPHERE (LIGHT), UPDATE lastT, objIndex and objType if necessary.
  237. }
  238. // planes
  239. for (int i = 0; i<geomCount.y; i++)
  240. {
  241. plane_type plane = planes_data[i];
  242. testT = planeTest(ray_dir.xyz, camPos, plane.normal_d);
  243. if(testT != -1){
  244. if(testT < lastT || lastT == -1){
  245. lastT = testT;
  246. objType = PLANE_TYPE;
  247. objIndex = i;
  248. }
  249. }
  250. // IMPLEMENT HERE.
  251. // TEST PLANE, UPDATE lastT, objIndex and objType if necessary.
  252. }
  253. // triangles
  254. for (int i = 0; i<geomCount.z; i++)
  255. {
  256. triangle_type triangle = triangles_data[i];
  257. // IMPLEMENT HERE.
  258. testT = triangleTest(ray_dir.xyz, camPos, triangle);
  259. if(testT != -1){
  260. if(testT < lastT || lastT == -1){
  261. lastT = testT;
  262. objType = TRIANGLE_TYPE;
  263. objIndex = i;
  264. }
  265. }
  266.  
  267. // TEST TRIANGLE, UPDATE lastT, objIndex and objType if necessary.
  268. }
  269. // OBBs
  270. for (int i = 0; i < geomCount.w; i++)
  271. {
  272. obb_type obb = obb_data[i];
  273.  
  274. testT = obbTest(ray_dir.xyz, camPos, obb);
  275. if(testT != -1){
  276. if(testT < lastT || lastT == -1){
  277. lastT = testT;
  278. objType = OBB_TYPE;
  279. objIndex = i;
  280. }
  281. }
  282. // IMPLEMENT HERE.
  283. // TEST OBB, UPDATE lastT, objIndex and objType if necessary.
  284. }
  285. }
  286.  
  287. float sphereTest(in vec3 rayDir, in vec3 rayOrigin, in vec4 centre_radius)
  288. {
  289. vec3 oc = rayOrigin - centre_radius.xyz;
  290. float p = dot(rayDir, oc);
  291. float q = dot(oc,oc) - (centre_radius.w * centre_radius.w);
  292. if(p*p - q < 0){
  293. return -1.0f;
  294. }else
  295. return min(-p+sqrt(p*p - q), -p - sqrt(p*p -q));
  296. }
  297.  
  298. float planeTest(vec3 rayDir, vec3 rayOrigin, vec4 plane_info)
  299. {
  300. // IMPLEMENT HERE
  301. vec3 oc = rayOrigin - plane_info.xyz;
  302. if(dot(plane_info.xyz,rayDir) == 0)
  303. {
  304. return -1;
  305. }
  306. else
  307. {
  308. float t = (-plane_info.w- dot(plane_info.xyz,rayOrigin)) / dot(plane_info.xyz,rayDir);
  309. if( t >= 0)
  310. {
  311. return t;
  312. }
  313. }
  314.  
  315. return -1;
  316.  
  317. }
  318.  
  319. float triangleTest(vec3 rayDir, vec3 rayOrigin, triangle_type tri)
  320. {
  321. vec3 v1,v2, s, tuv, temp;
  322. float epsilon = 0.0001;
  323. v1 = tri.vtx1.xyz - tri.vtx0.xyz;
  324. v2 = tri.vtx2.xyz - tri.vtx0.xyz;
  325. s = rayOrigin - tri.vtx0.xyz;
  326. vec3 q = cross(rayDir, v2);
  327. float a = dot(v1, q);
  328. float tReturn = -1;
  329. temp.x = determinant(mat3(s,v1,v2));
  330. temp.y = determinant(mat3(-rayDir,s,v2));
  331. temp.z = determinant(mat3(-rayDir,v1,s));
  332.  
  333. if(determinant(mat3(-rayDir,v1,v2)) > 0.0f){
  334. tuv = (1 / determinant(mat3(-rayDir,v1,v2)))*temp;
  335.  
  336. if(tuv.x >= 0.0){
  337. tReturn = tuv.x;
  338. }
  339.  
  340. if((a > -epsilon && a < epsilon) || (tuv.y < 0.0)|| ((tuv.z < 0.0) || (tuv.y + tuv.z > 1.0)))
  341. {
  342. tReturn = -1;
  343. }
  344. }
  345. return tReturn;
  346. }
  347.  
  348. float obbTest(vec3 rayDir, vec3 rayOrigin, obb_type o)
  349. {
  350. // FIXAAAAAAAAAAAAAAAAAAA
  351. float epsilon = 0.0001;
  352. float tReturn = -1;
  353. float tMin = -1000000;
  354. float tMax = 1000000;
  355. float t1;
  356. float t2;
  357. float e;
  358. float f;
  359. vec3 p = o.centre.xyz - rayOrigin;
  360. bool behindCamera = false;
  361. bool miss = false;
  362. vec4 obbDataArr[3];
  363. obbDataArr[0] = o.u_hu;
  364. obbDataArr[1] = o.v_hv;
  365. obbDataArr[2] = o.w_hw;
  366.  
  367. for(int i = 0; i < 3 && miss == false
  368. && behindCamera == false; i++)
  369. {
  370. e = dot(obbDataArr[i].xyz, p);
  371. f = dot(obbDataArr[i].xyz, rayDir);
  372.  
  373. if(abs(f) > epsilon)
  374. {
  375. float t1 = (e + obbDataArr[i].w)/f;
  376. float t2 = (e - obbDataArr[i].w)/f;
  377. if(t1 > t2)
  378. {
  379. float temp = t1;
  380. t1 = t2;
  381. t2 = temp;
  382. }
  383. if(t1 > tMin)
  384. tMin = t1;
  385. if(t2 < tMax)
  386. tMax = t2;
  387. if(tMin > tMax)
  388. {
  389. tReturn = -1;
  390. miss = true;
  391. }
  392. if(tMax < 0)
  393. {
  394. tReturn = -1; //behind camera
  395. behindCamera = true;
  396. }
  397. }
  398. else if(((-e) - obbDataArr[i].w) > 0.0 || ((-e) + obbDataArr[i].w) < 0.0)
  399. {
  400. tReturn = -1;
  401. miss = true;
  402. }
  403. }
  404.  
  405. if(miss == false && behindCamera == false)
  406. {
  407. if(tMin > 0.0)
  408. tReturn = tMin;
  409. else
  410. tReturn = tMax;
  411. }
  412.  
  413.  
  414. return tReturn;
  415. };
  416.  
  417. // everythin in World Space
  418. vec4 shade(in vec3 pointOnSurface, in vec3 normal, in vec3 colour)
  419. {
  420. // ambient (combine with material color!)
  421. // 0.2 is arbitrary, that is the value used in the model solution.
  422. vec4 final_colour = vec4(0.2,0.2,0.2,1);
  423. // diffuse, no attenuation.
  424. for (int i = 0; i < lightCount; i++)
  425. {
  426. vec4 light_pos = lights_data[i].position;
  427. vec4 light_colour = lights_data[i].colour;
  428. vec3 lightVector = normalize(light_pos.xyz - pointOnSurface);
  429. vec3 diffuseFactor = colour * dot(normal,lightVector);
  430. vec3 colorObject = lights_data[i].colour.xyz * colour * diffuseFactor * 1/abs(light_pos.xyz - pointOnSurface);
  431. final_colour += vec4(colorObject,1);
  432. // IMPLEMENT HERE DIFFUSE SHADING
  433.  
  434. }
  435. if(final_colour.x > 1)
  436. final_colour.x = 1;
  437. if(final_colour.y > 1)
  438. final_colour.y = 1;
  439. if(final_colour.z > 1)
  440. final_colour.z = 1;
  441. if(final_colour.w > 1)
  442. final_colour.w = 1;
  443. // UPDATE THIS LINE TO ACCOUNT FOR SATURATION (PIXEL COLOUR CANNOT GO OVER 1.0)
  444. return final_colour;
  445. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement