gpuray_glsl

annotate sdr/rt.glsl @ 3:297dbc5080c4

cone intersection
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 09 Nov 2014 20:13:33 +0200
parents
children 2ed3da7dc0bc
rev   line source
nuclear@0 1 /* vi:set filetype=glsl ts=4 sw=4: */
nuclear@0 2 #version 120
nuclear@0 3 #extension GL_ARB_gpu_shader5 : enable
nuclear@0 4
nuclear@0 5 #define M_PI 3.1415926
nuclear@0 6
nuclear@0 7 #define INIT_EVERYTHING
nuclear@0 8 #define USE_XFORM
nuclear@0 9 #define OBJ_LINE_WIDTH 16.0
nuclear@0 10
nuclear@0 11 struct Ray {
nuclear@0 12 vec3 origin, dir;
nuclear@0 13 };
nuclear@0 14
nuclear@0 15 struct Material {
nuclear@0 16 vec3 diffuse, specular;
nuclear@0 17 float shininess;
nuclear@0 18 vec4 megatex_rect;
nuclear@0 19 float reflectivity;
nuclear@0 20 };
nuclear@0 21
nuclear@0 22 struct HitPoint {
nuclear@0 23 float dist;
nuclear@0 24 vec3 pos, normal;
nuclear@0 25 vec2 texcoord;
nuclear@0 26 struct Material mat;
nuclear@0 27 };
nuclear@0 28
nuclear@0 29 struct Sphere {
nuclear@0 30 float index;
nuclear@0 31 vec3 pos;
nuclear@0 32 float radius;
nuclear@0 33 struct Material mat;
nuclear@0 34 };
nuclear@0 35
nuclear@0 36 struct Plane {
nuclear@0 37 float index;
nuclear@0 38 vec3 normal;
nuclear@0 39 float dist;
nuclear@0 40 struct Material mat;
nuclear@0 41 };
nuclear@0 42
nuclear@0 43 struct Box {
nuclear@0 44 float index;
nuclear@0 45 vec3 min, max;
nuclear@0 46 struct Material mat;
nuclear@0 47 };
nuclear@0 48
nuclear@0 49 struct Light {
nuclear@0 50 vec3 pos, color;
nuclear@0 51 };
nuclear@0 52
nuclear@0 53 vec3 shade(in Ray ray, in HitPoint hit);
nuclear@0 54 bool find_intersection(in Ray ray, out HitPoint hit);
nuclear@0 55 bool sphere_intersect(in Sphere sph, in Ray ray, out HitPoint pt);
nuclear@0 56 bool plane_intersect(in Plane plane, in Ray ray, out HitPoint pt);
nuclear@0 57 bool box_intersect(in Box box, in Ray ray, out HitPoint pt);
nuclear@0 58 vec3 transform(in vec3 v, in mat4 inv_xform);
nuclear@0 59 Ray transform(in Ray ray, in mat4 xform, in mat4 inv_xform);
nuclear@0 60 Ray get_primary_ray();
nuclear@0 61
nuclear@0 62 Sphere read_sphere(in float idx);
nuclear@0 63 Plane read_plane(in float idx);
nuclear@0 64 Box read_box(in float idx);
nuclear@0 65 Material read_material(in sampler2D tex, in float ty);
nuclear@0 66 void read_xform(in float idx, out mat4 xform, out mat4 inv_xform);
nuclear@0 67
nuclear@0 68 uniform sampler2D tex_raydir;
nuclear@0 69 uniform sampler2D tex_spheres, tex_planes, tex_boxes;
nuclear@0 70 uniform sampler2D tex_megatex;
nuclear@0 71 uniform sampler2D tex_xforms;
nuclear@0 72 uniform samplerCube tex_env;
nuclear@0 73 uniform vec2 fog;
nuclear@0 74
nuclear@0 75 uniform Light lights[8];
nuclear@0 76 uniform int num_lights;
nuclear@0 77
nuclear@0 78 int num_spheres, num_planes, num_boxes;
nuclear@0 79 float sph_tex_sz, plane_tex_sz, box_tex_sz, xform_tex_sz;
nuclear@0 80
nuclear@0 81 #ifdef INIT_EVERYTHING
nuclear@0 82 Material default_material;
nuclear@0 83 #endif
nuclear@0 84
nuclear@0 85 void main()
nuclear@0 86 {
nuclear@0 87 #ifdef INIT_EVERYTHING
nuclear@0 88 default_material.diffuse = default_material.specular = vec3(0.0, 0.0, 0.0);
nuclear@0 89 default_material.shininess = 1.0;
nuclear@0 90 default_material.reflectivity = 0.0;
nuclear@0 91 default_material.megatex_rect = vec4(0.0, 0.0, 0.0, 0.0);
nuclear@0 92 #endif
nuclear@0 93
nuclear@0 94 Ray ray = get_primary_ray();
nuclear@0 95
nuclear@0 96 /* read the various descriptors specifying dimensions and counts for
nuclear@0 97 * all the relevant data textures
nuclear@0 98 */
nuclear@0 99 vec4 desc = texture2D(tex_spheres, vec2(0.0, 0.0));
nuclear@0 100 num_spheres = int(desc.x);
nuclear@0 101 sph_tex_sz = desc.y;
nuclear@0 102
nuclear@0 103 desc = texture2D(tex_planes, vec2(0.0, 0.0));
nuclear@0 104 num_planes = int(desc.x);
nuclear@0 105 plane_tex_sz = desc.y;
nuclear@0 106
nuclear@0 107 desc = texture2D(tex_boxes, vec2(0.0, 0.0));
nuclear@0 108 num_boxes = int(desc.x);
nuclear@0 109 box_tex_sz = desc.y;
nuclear@0 110
nuclear@0 111 xform_tex_sz = texture2D(tex_xforms, vec2(0.0, 0.0)).x;
nuclear@0 112
nuclear@0 113
nuclear@0 114 HitPoint hit;
nuclear@0 115 #ifdef INIT_EVERYTHING
nuclear@0 116 hit.dist = 0.0;
nuclear@0 117 hit.pos = hit.normal = vec3(0.0, 0.0, 0.0);
nuclear@0 118 #endif
nuclear@0 119
nuclear@0 120 vec3 color = vec3(0.0, 0.0, 0.0);
nuclear@0 121 float energy = 1.0;
nuclear@0 122
nuclear@0 123 int iter = 0;
nuclear@0 124 while(energy > 0.01 && iter++ < 4) {
nuclear@0 125 vec3 envcol = textureCube(tex_env, ray.dir).xyz;
nuclear@0 126
nuclear@0 127 if(find_intersection(ray, hit)) {
nuclear@0 128 float fog_t = clamp((hit.dist - fog.x) / (fog.y - fog.x), 0.0, 1.0);
nuclear@0 129 color += mix(shade(ray, hit), envcol, fog_t) * energy;
nuclear@0 130 energy *= hit.mat.reflectivity * (1.0 - fog_t);
nuclear@0 131 ray.origin = hit.pos;
nuclear@0 132 ray.dir = reflect(ray.dir, hit.normal);
nuclear@0 133 } else {
nuclear@0 134 color += envcol * energy;
nuclear@0 135 energy = 0.0;
nuclear@0 136 iter = 100;
nuclear@0 137 }
nuclear@0 138 }
nuclear@0 139
nuclear@0 140 gl_FragColor.xyz = color;
nuclear@0 141 gl_FragColor.w = 1.0;
nuclear@0 142 }
nuclear@0 143
nuclear@0 144 vec3 shade(in Ray ray, in HitPoint hit)
nuclear@0 145 {
nuclear@0 146 vec3 normal = faceforward(hit.normal, ray.dir, hit.normal);
nuclear@0 147
nuclear@0 148 vec3 vdir = normalize(ray.dir);
nuclear@0 149 vec3 vref = reflect(vdir, normal);
nuclear@0 150
nuclear@0 151 /* if there's no texture rect.zw will be (0, 0, 0, 0) so this will map onto
nuclear@0 152 * the top-left 1x1 null texture which is all white (having no effect)
nuclear@0 153 */
nuclear@0 154 vec2 tc = mod(hit.texcoord, vec2(1.0, 1.0)) * hit.mat.megatex_rect.zw + hit.mat.megatex_rect.xy;
nuclear@0 155
nuclear@0 156 vec3 diffuse_color = hit.mat.diffuse * texture2D(tex_megatex, tc).xyz;
nuclear@0 157
nuclear@0 158 vec3 color = vec3(0.0, 0.0, 0.0);
nuclear@0 159 for(int i=0; i<num_lights; i++) {
nuclear@0 160 Ray shadow_ray;
nuclear@0 161 shadow_ray.origin = hit.pos;
nuclear@0 162 shadow_ray.dir = lights[i].pos - hit.pos;
nuclear@0 163
nuclear@0 164 HitPoint shadow_hit;
nuclear@0 165 if(!find_intersection(shadow_ray, shadow_hit) || shadow_hit.dist > 1.0) {
nuclear@0 166 vec3 ldir = normalize(shadow_ray.dir);
nuclear@0 167
nuclear@0 168 float diffuse = max(dot(ldir, normal), 0.0);
nuclear@0 169 float specular = pow(max(dot(ldir, vref), 0.0), hit.mat.shininess);
nuclear@0 170
nuclear@0 171 color += (diffuse_color * diffuse + hit.mat.specular * specular) * lights[i].color;
nuclear@0 172 }
nuclear@0 173 }
nuclear@0 174
nuclear@0 175 return color;
nuclear@0 176 }
nuclear@0 177
nuclear@0 178 bool find_intersection(in Ray ray, out HitPoint hit)
nuclear@0 179 {
nuclear@0 180 hit.dist = 100000.0;
nuclear@0 181 #ifdef INIT_EVERYTHING
nuclear@0 182 hit.pos = hit.normal = vec3(0.0, 0.0, 0.0);
nuclear@0 183 hit.mat = default_material;
nuclear@0 184 hit.texcoord = vec2(0.0, 0.0);
nuclear@0 185 #endif
nuclear@0 186 bool found = false;
nuclear@0 187
nuclear@0 188 for(int i=0; i<num_spheres; i++) {
nuclear@0 189 Sphere sph = read_sphere(i);
nuclear@0 190
nuclear@0 191 HitPoint tmphit;
nuclear@0 192 if(sphere_intersect(sph, ray, tmphit) && tmphit.dist < hit.dist) {
nuclear@0 193 hit = tmphit;
nuclear@0 194 found = true;
nuclear@0 195 }
nuclear@0 196 }
nuclear@0 197
nuclear@0 198 for(int i=0; i<num_planes; i++) {
nuclear@0 199 Plane plane = read_plane(i);
nuclear@0 200
nuclear@0 201 HitPoint tmphit;
nuclear@0 202 if(plane_intersect(plane, ray, tmphit) && tmphit.dist < hit.dist) {
nuclear@0 203 hit = tmphit;
nuclear@0 204 found = true;
nuclear@0 205 }
nuclear@0 206 }
nuclear@0 207
nuclear@0 208 for(int i=0; i<num_boxes; i++) {
nuclear@0 209 Box box = read_box(i);
nuclear@0 210
nuclear@0 211 HitPoint tmphit;
nuclear@0 212 if(box_intersect(box, ray, tmphit) && tmphit.dist < hit.dist) {
nuclear@0 213 hit = tmphit;
nuclear@0 214 found = true;
nuclear@0 215 }
nuclear@0 216 }
nuclear@0 217
nuclear@0 218 return found;
nuclear@0 219 }
nuclear@0 220
nuclear@0 221 #define EPSILON 1e-4
nuclear@0 222 #define SQ(x) ((x) * (x))
nuclear@0 223
nuclear@0 224 bool sphere_intersect(in Sphere sph, in Ray inray, out HitPoint pt)
nuclear@0 225 {
nuclear@0 226 #ifdef USE_XFORM
nuclear@0 227 mat4 xform, inv_xform;
nuclear@0 228 read_xform(sph.index, xform, inv_xform);
nuclear@0 229
nuclear@0 230 Ray ray = transform(inray, inv_xform, xform);
nuclear@0 231 #else
nuclear@0 232 Ray ray = inray;
nuclear@0 233 #endif
nuclear@0 234
nuclear@0 235 #ifdef INIT_EVERYTHING
nuclear@0 236 pt.dist = 0.0;
nuclear@0 237 pt.pos = pt.normal = vec3(0.0, 0.0, 0.0);
nuclear@0 238 pt.mat = default_material;
nuclear@0 239 pt.texcoord = vec2(0.0, 0.0);
nuclear@0 240 #endif
nuclear@0 241
nuclear@0 242 float a = dot(ray.dir, ray.dir);
nuclear@0 243 float b = dot(ray.dir, ray.origin - sph.pos) * 2.0;
nuclear@0 244 float c = dot(ray.origin, ray.origin) + dot(sph.pos, sph.pos) -
nuclear@0 245 2.0 * dot(ray.origin, sph.pos) - sph.radius * sph.radius;
nuclear@0 246
nuclear@0 247 float discr = b * b - 4.0 * a * c;
nuclear@0 248 if(discr < EPSILON)
nuclear@0 249 return false;
nuclear@0 250
nuclear@0 251 float sqrt_discr = sqrt(discr);
nuclear@0 252 float t0 = (-b + sqrt_discr) / (2.0 * a);
nuclear@0 253 float t1 = (-b - sqrt_discr) / (2.0 * a);
nuclear@0 254
nuclear@0 255 if(t0 < EPSILON)
nuclear@0 256 t0 = t1;
nuclear@0 257 if(t1 < EPSILON)
nuclear@0 258 t1 = t0;
nuclear@0 259
nuclear@0 260 float t = min(t0, t1);
nuclear@0 261 if(t < EPSILON)
nuclear@0 262 return false;
nuclear@0 263
nuclear@0 264 // fill the HitPoint structure
nuclear@0 265 pt.dist = t;
nuclear@0 266 pt.pos = ray.origin + ray.dir * t;
nuclear@0 267 pt.normal = (pt.pos - sph.pos) / sph.radius;
nuclear@0 268 pt.mat = sph.mat;
nuclear@0 269
nuclear@0 270 pt.texcoord.x = 0.5 * atan(pt.normal.z, pt.normal.x) / M_PI + 0.5;
nuclear@0 271 pt.texcoord.y = acos(pt.normal.y) / M_PI;
nuclear@0 272
nuclear@0 273 #ifdef USE_XFORM
nuclear@0 274 pt.pos = (xform * vec4(pt.pos, 1.0)).xyz;
nuclear@0 275 pt.normal = normalize(transform(pt.normal, xform));
nuclear@0 276 #endif
nuclear@0 277 return true;
nuclear@0 278 }
nuclear@0 279
nuclear@0 280 bool plane_intersect(in Plane plane, in Ray inray, out HitPoint pt)
nuclear@0 281 {
nuclear@0 282 #ifdef USE_XFORM
nuclear@0 283 mat4 xform, inv_xform;
nuclear@0 284 read_xform(plane.index, xform, inv_xform);
nuclear@0 285
nuclear@0 286 Ray ray = transform(inray, inv_xform, xform);
nuclear@0 287 #else
nuclear@0 288 Ray ray = inray;
nuclear@0 289 #endif
nuclear@0 290
nuclear@0 291 #ifdef INIT_EVERYTHING
nuclear@0 292 pt.dist = 0.0;
nuclear@0 293 pt.pos = pt.normal = vec3(0.0, 0.0, 0.0);
nuclear@0 294 pt.mat = default_material;
nuclear@0 295 pt.texcoord = vec2(0.0, 0.0);
nuclear@0 296 #endif
nuclear@0 297
nuclear@0 298 float ndotdir = dot(plane.normal, ray.dir);
nuclear@0 299 if(abs(ndotdir) < EPSILON) {
nuclear@0 300 return false;
nuclear@0 301 }
nuclear@0 302
nuclear@0 303 vec3 planept = plane.normal * plane.dist;
nuclear@0 304 vec3 pptdir = planept - ray.origin;
nuclear@0 305
nuclear@0 306 float t = dot(plane.normal, pptdir) / ndotdir;
nuclear@0 307 if(t < EPSILON) {
nuclear@0 308 return false;
nuclear@0 309 }
nuclear@0 310
nuclear@0 311 pt.dist = t;
nuclear@0 312 pt.pos = ray.origin + ray.dir * t;
nuclear@0 313 pt.normal = plane.normal;
nuclear@0 314 pt.mat = plane.mat;
nuclear@0 315 pt.texcoord.x = pt.pos.x;
nuclear@0 316 pt.texcoord.y = pt.pos.z;
nuclear@0 317
nuclear@0 318 #ifdef USE_XFORM
nuclear@0 319 pt.pos = (xform * vec4(pt.pos, 1.0)).xyz;
nuclear@0 320 pt.normal = normalize(transform(pt.normal, xform));
nuclear@0 321 #endif
nuclear@0 322 return true;
nuclear@0 323 }
nuclear@0 324
nuclear@0 325 bool box_intersect(in Box box, in Ray inray, out HitPoint pt)
nuclear@0 326 {
nuclear@0 327 #ifdef USE_XFORM
nuclear@0 328 mat4 xform, inv_xform;
nuclear@0 329 read_xform(box.index, xform, inv_xform);
nuclear@0 330
nuclear@0 331 Ray ray = transform(inray, inv_xform, xform);
nuclear@0 332 #else
nuclear@0 333 Ray ray = inray;
nuclear@0 334 #endif
nuclear@0 335
nuclear@0 336 #ifdef INIT_EVERYTHING
nuclear@0 337 pt.dist = 0.0;
nuclear@0 338 pt.pos = pt.normal = vec3(0.0, 0.0, 0.0);
nuclear@0 339 pt.mat = default_material;
nuclear@0 340 pt.texcoord = vec2(0.0, 0.0);
nuclear@0 341 #endif
nuclear@0 342
nuclear@0 343 vec3 param[2];
nuclear@0 344 param[0] = box.min;
nuclear@0 345 param[1] = box.max;
nuclear@0 346
nuclear@0 347 vec3 inv_dir = 1.0 / ray.dir;
nuclear@0 348 int sgn[3];
nuclear@0 349 sgn[0] = inv_dir.x < 0.0 ? 1 : 0;
nuclear@0 350 sgn[1] = inv_dir.y < 0.0 ? 1 : 0;
nuclear@0 351 sgn[2] = inv_dir.z < 0.0 ? 1 : 0;
nuclear@0 352
nuclear@0 353 float tmin = (param[sgn[0]].x - ray.origin.x) * inv_dir.x;
nuclear@0 354 float tmax = (param[1 - sgn[0]].x - ray.origin.x) * inv_dir.x;
nuclear@0 355 float tymin = (param[sgn[1]].y - ray.origin.y) * inv_dir.y;
nuclear@0 356 float tymax = (param[1 - sgn[1]].y - ray.origin.y) * inv_dir.y;
nuclear@0 357
nuclear@0 358 pt.normal = vec3(ray.origin.x > 0.0 ? 1.0 : -1.0, 0.0, 0.0);
nuclear@0 359
nuclear@0 360 if(tmin > tymax || tymin > tmax) {
nuclear@0 361 return false;
nuclear@0 362 }
nuclear@0 363 if(tymin > tmin) {
nuclear@0 364 pt.normal = vec3(0.0, ray.origin.y > 0.0 ? 1.0 : -1.0, 0.0);
nuclear@0 365 tmin = tymin;
nuclear@0 366 }
nuclear@0 367 if(tymax < tmax) {
nuclear@0 368 tmax = tymax;
nuclear@0 369 }
nuclear@0 370
nuclear@0 371 float tzmin = (param[sgn[2]].z - ray.origin.z) * inv_dir.z;
nuclear@0 372 float tzmax = (param[1 - sgn[2]].z - ray.origin.z) * inv_dir.z;
nuclear@0 373
nuclear@0 374 if(tmin > tzmax || tzmin > tmax) {
nuclear@0 375 return false;
nuclear@0 376 }
nuclear@0 377 if(tzmin > tmin) {
nuclear@0 378 pt.normal = vec3(0.0, 0.0, ray.origin.z > 0.0 ? 1.0 : -1.0);
nuclear@0 379 tmin = tzmin;
nuclear@0 380 }
nuclear@0 381 if(tzmax < tmax) {
nuclear@0 382 tmax = tzmax;
nuclear@0 383 }
nuclear@0 384
nuclear@0 385 float t = tmin < EPSILON ? tmax : tmin;
nuclear@0 386 if(t >= 1e-4) {
nuclear@0 387 pt.dist = t;
nuclear@0 388 pt.pos = ray.origin + ray.dir * t;
nuclear@0 389 pt.mat = box.mat;
nuclear@0 390
nuclear@0 391 float min_dist = 10000.0;
nuclear@0 392
nuclear@0 393 vec3 offs = box.min + (box.max - box.min) / 2.0;
nuclear@0 394 vec3 local_pt = pt.pos - offs;
nuclear@0 395
nuclear@0 396 vec3 dist = abs((box.max - offs) - abs(local_pt));
nuclear@0 397 if(dist.x < min_dist) {
nuclear@0 398 min_dist = dist.x;
nuclear@0 399 pt.normal = sign(local_pt.x) * vec3(1.0, 0.0, 0.0);
nuclear@0 400 pt.texcoord = pt.pos.zy;
nuclear@0 401 }
nuclear@0 402 if(dist.y < min_dist) {
nuclear@0 403 min_dist = dist.y;
nuclear@0 404 pt.normal = sign(local_pt.y) * vec3(0.0, 1.0, 0.0);
nuclear@0 405 pt.texcoord = pt.pos.xz;
nuclear@0 406 }
nuclear@0 407 if(dist.z < min_dist) {
nuclear@0 408 pt.normal = sign(local_pt.y) * vec3(0.0, 0.0, 1.0);
nuclear@0 409 pt.texcoord = pt.pos.xy;
nuclear@0 410 }
nuclear@0 411
nuclear@0 412
nuclear@0 413 #ifdef USE_XFORM
nuclear@0 414 pt.pos = (xform * vec4(pt.pos, 1.0)).xyz;
nuclear@0 415 pt.normal = normalize(transform(pt.normal, xform));
nuclear@0 416 #endif
nuclear@0 417 return true;
nuclear@0 418 }
nuclear@0 419 return false;
nuclear@0 420 }
nuclear@0 421
nuclear@0 422 vec3 transform(in vec3 v, in mat4 xform)
nuclear@0 423 {
nuclear@0 424 return mat3(xform) * v;
nuclear@0 425 }
nuclear@0 426
nuclear@0 427 Ray transform(in Ray ray, in mat4 xform, in mat4 inv_xform)
nuclear@0 428 {
nuclear@0 429 Ray res;
nuclear@0 430 res.origin = (xform * vec4(ray.origin, 1.0)).xyz;
nuclear@0 431 res.dir = transform(ray.dir, xform);
nuclear@0 432 return res;
nuclear@0 433 }
nuclear@0 434
nuclear@0 435 Ray get_primary_ray()
nuclear@0 436 {
nuclear@0 437 Ray ray;
nuclear@0 438 ray.origin = (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
nuclear@0 439 vec3 dir = texture2D(tex_raydir, gl_TexCoord[0].st).xyz;
nuclear@0 440 ray.dir = normalize(gl_NormalMatrix * dir);
nuclear@0 441 return ray;
nuclear@0 442 }
nuclear@0 443
nuclear@0 444 #define ITEM(x) ((float(x) + 0.5) / OBJ_LINE_WIDTH)
nuclear@0 445
nuclear@0 446 Sphere read_sphere(in float idx)
nuclear@0 447 {
nuclear@0 448 Sphere sph;
nuclear@0 449 // +1 because the first scanline is the descriptor
nuclear@0 450 float ty = (idx + 1.0) / sph_tex_sz;
nuclear@0 451
nuclear@0 452 sph.index = texture2D(tex_spheres, vec2(ITEM(0), ty)).x;
nuclear@0 453
nuclear@0 454 vec4 texel = texture2D(tex_spheres, vec2(ITEM(1), ty));
nuclear@0 455 sph.pos = texel.xyz;
nuclear@0 456 sph.radius = texel.w;
nuclear@0 457
nuclear@0 458 sph.mat = read_material(tex_spheres, ty);
nuclear@0 459 return sph;
nuclear@0 460 }
nuclear@0 461
nuclear@0 462 Plane read_plane(in float idx)
nuclear@0 463 {
nuclear@0 464 Plane plane;
nuclear@0 465 // +1 (see above)
nuclear@0 466 float ty = (idx + 1.0) / plane_tex_sz;
nuclear@0 467
nuclear@0 468 plane.index = texture2D(tex_planes, vec2(ITEM(0), ty)).x;
nuclear@0 469
nuclear@0 470 vec4 texel = texture2D(tex_planes, vec2(ITEM(1), ty));
nuclear@0 471 plane.normal = texel.xyz;
nuclear@0 472 plane.dist = texel.w;
nuclear@0 473
nuclear@0 474 plane.mat = read_material(tex_planes, ty);
nuclear@0 475 return plane;
nuclear@0 476 }
nuclear@0 477
nuclear@0 478 Box read_box(in float idx)
nuclear@0 479 {
nuclear@0 480 Box box;
nuclear@0 481 float ty = (idx + 1.0) / box_tex_sz;
nuclear@0 482
nuclear@0 483 box.index = texture2D(tex_boxes, vec2(ITEM(0), ty)).x;
nuclear@0 484
nuclear@0 485 box.min = texture2D(tex_boxes, vec2(ITEM(1), ty)).xyz;
nuclear@0 486 box.max = texture2D(tex_boxes, vec2(ITEM(2), ty)).xyz;
nuclear@0 487
nuclear@0 488 box.mat = read_material(tex_boxes, ty);
nuclear@0 489 return box;
nuclear@0 490 }
nuclear@0 491
nuclear@0 492 void read_xform(in float idx, out mat4 xform, out mat4 inv_xform)
nuclear@0 493 {
nuclear@0 494 float ty = (idx + 1.0) / xform_tex_sz;
nuclear@0 495
nuclear@0 496 for(int i=0; i<4; i++) {
nuclear@0 497 xform[i] = texture2D(tex_xforms, vec2(ITEM(i), ty));
nuclear@0 498 }
nuclear@0 499 inv_xform = inverse(xform);
nuclear@0 500 /*for(int i=0; i<4; i++) {
nuclear@0 501 inv_xform[i] = texture2D(tex_xforms, vec2(ITEM(float(i) + 4.0), ty));
nuclear@0 502 }*/
nuclear@0 503 }
nuclear@0 504
nuclear@0 505 #define MAT_START 4
nuclear@0 506 Material read_material(in sampler2D tex, in float ty)
nuclear@0 507 {
nuclear@0 508 Material mat;
nuclear@0 509
nuclear@0 510 vec4 texel = texture2D(tex, vec2(ITEM(MAT_START), ty));
nuclear@0 511 mat.diffuse = texel.xyz;
nuclear@0 512
nuclear@0 513 texel = texture2D(tex, vec2(ITEM(MAT_START + 1), ty));
nuclear@0 514 mat.specular = texel.xyz;
nuclear@0 515 mat.shininess = texel.w;
nuclear@0 516
nuclear@0 517 texel = texture2D(tex, vec2(ITEM(MAT_START + 2), ty));
nuclear@0 518 mat.reflectivity = texel.x;
nuclear@0 519
nuclear@0 520 mat.megatex_rect = texture2D(tex, vec2(ITEM(MAT_START + 3), ty));
nuclear@0 521
nuclear@0 522 return mat;
nuclear@0 523 }