Constant RT_WGSL
Source pub const RT_WGSL: &str = "@group(0) @binding(17) var rt_world: acceleration_structure;\n@group(0) @binding(18) var<storage, read> rt_map: array<u32>;\nfn rt_triangle(c: RayIntersection) -> u32 {\n return rt_map[2u+select(0u,rt_map[0],c.geometry_index==1u)+c.primitive_index];\n}\nfn rt_shape(c: RayIntersection) -> u32 {\n return rt_map[2u+rt_map[1]+c.primitive_index];\n}\nfn rt_finite(v: f32) -> bool {\n return (bitcast<u32>(v)&0x7fffffffu)<0x7f800000u;\n}\nfn rt_valid(o: vec3f, d: vec3f, limit: f32) -> bool {\n return rt_finite(o.x) && rt_finite(o.y) && rt_finite(o.z) && rt_finite(d.x) && rt_finite(d.y) && rt_finite(d.z) && (bitcast<u32>(limit)&0x7fffffffu)<=0x7f800000u;\n}\nfn rt_shape_t(i: u32, o: vec3f, d: vec3f, limit: f32) -> f32 {\n if (u32(shapes[i].a.w)==5u) { return union_hit(i,o,d,limit); }\n return primitive_hit(i,o,d,limit);\n}\nfn rt_fill(i: u32, o: vec3f, d: vec3f, t: f32, u: f32, v: f32, hit: ptr<function,Hit>) {\n let tri = triangles[i];\n let e1 = tri.b.xyz-tri.a.xyz;\n let e2 = tri.c.xyz-tri.a.xyz;\n (*hit).t=t;\n (*hit).surface=i;\n (*hit).shape=0u;\n let geometric=normalize(cross(e1,e2));\n (*hit).geometric=geometric;\n let shaded=tri.na.xyz*(1.0-u-v)+tri.nb.xyz*u+tri.nc.xyz*v;\n (*hit).n=select(geometric,normalize(shaded),dot(shaded,shaded)>1e-12);\n (*hit).material=u32(tri.a.w);\n let uv_v=triangle_uv_v[i];\n (*hit).uv=vec2f(tri.na.w*(1.0-u-v)+tri.nb.w*u+tri.nc.w*v,\n uv_v.x*(1.0-u-v)+uv_v.y*u+uv_v.z*v);\n let du1=tri.nb.w-tri.na.w;\n let du2=tri.nc.w-tri.na.w;\n let dv1=uv_v.y-uv_v.x;\n let dv2=uv_v.z-uv_v.x;\n let uv_det=du1*dv2-du2*dv1;\n var tangent=normalize(e1);\n if (abs(uv_det)>1e-10) { tangent=normalize((e1*dv2-e2*dv1)/uv_det); }\n (*hit).tangent=tangent;\n (*hit).bitangent=normalize(cross(geometric,tangent))*select(-1.0,1.0,uv_det>=0.0);\n}\nfn rt_shape_hit(i: u32, o: vec3f, d: vec3f, t: f32) -> Hit {\n let p=o+d*t;\n let e=0.0002;\n let n=normalize(vec3f(\n shape_distance(i,p+vec3f(e,0.0,0.0))-shape_distance(i,p-vec3f(e,0.0,0.0)),\n shape_distance(i,p+vec3f(0.0,e,0.0))-shape_distance(i,p-vec3f(0.0,e,0.0)),\n shape_distance(i,p+vec3f(0.0,0.0,e))-shape_distance(i,p-vec3f(0.0,0.0,e))));\n return Hit(t,n,n,u32(shapes[i].c.w),vec2f(0.0),vec3f(1.0,0.0,0.0),vec3f(0.0,1.0,0.0),0u,i+1u);\n}\nfn scene(o: vec3f, d: vec3f, limit: f32, shadow_ray: bool) -> Hit {\n var hit=Hit(limit,vec3f(0.0),vec3f(0.0),0u,vec2f(0.0),vec3f(1.0,0.0,0.0),vec3f(0.0,1.0,0.0),0u,0u);\n if (!rt_valid(o,d,limit)) { return hit; }\n var rq: ray_query;\n rayQueryInitialize(&rq,rt_world,RayDesc(RAY_FLAG_NONE,0xffu,0.0001,limit,o,d));\n var best=limit;\n var shape=0u;\n while (rayQueryProceed(&rq)) {\n let c=rayQueryGetCandidateIntersection(&rq);\n if (c.kind==RAY_QUERY_INTERSECTION_TRIANGLE) {\n var probe=hit;\n probe.t=best;\n tri_hit(rt_triangle(c),o,d,shadow_ray,&probe);\n if (probe.t<best) {\n rayQueryConfirmIntersection(&rq);\n best=probe.t;\n shape=0u;\n }\n } else {\n let i=rt_shape(c);\n let t=rt_shape_t(i,o,d,best);\n if (t<best && t>0.0001) {\n best=t;\n shape=i+1u;\n }\n }\n }\n let committed=rayQueryGetCommittedIntersection(&rq);\n let triangle=committed.kind==RAY_QUERY_INTERSECTION_TRIANGLE;\n if (shape>0u && !(triangle && committed.t<best)) {\n hit=rt_shape_hit(shape-1u,o,d,best);\n } else if (triangle) {\n rt_fill(rt_triangle(committed),o,d,committed.t,committed.barycentrics.x,committed.barycentrics.y,&hit);\n }\n if (!RT_BOXES) {\n for (var i=0u;i<frame.counts.y;i++) {\n if (shapes[i].d.x > 0.5) { continue; }\n let t=rt_shape_t(i,o,d,hit.t);\n if (t<hit.t && t>0.0001) { hit=rt_shape_hit(i,o,d,t); }\n }\n }\n return hit;\n}\nfn occluded(o: vec3f, d: vec3f, limit: f32) -> bool {\n if (!rt_valid(o,d,limit)) { return true; }\n var rq: ray_query;\n rayQueryInitialize(&rq,rt_world,RayDesc(RAY_FLAG_TERMINATE_ON_FIRST_HIT,0xffu,0.0001,limit,o,d));\n var blocked=false;\n while (rayQueryProceed(&rq)) {\n let c=rayQueryGetCandidateIntersection(&rq);\n if (c.kind==RAY_QUERY_INTERSECTION_TRIANGLE) {\n if (tri_blocks(rt_triangle(c),o,d,limit)) { rayQueryConfirmIntersection(&rq); }\n } else {\n let t=rt_shape_t(rt_shape(c),o,d,limit);\n if (t<limit && t>0.0001) {\n blocked=true;\n rayQueryTerminate(&rq);\n }\n }\n }\n if (blocked || rayQueryGetCommittedIntersection(&rq).kind!=RAY_QUERY_INTERSECTION_NONE) { return true; }\n if (!RT_BOXES) {\n for (var i=0u;i<frame.counts.y;i++) {\n if (shapes[i].d.x > 0.5) { continue; }\n let t=rt_shape_t(i,o,d,limit);\n if (t<limit && t>0.0001) { return true; }\n }\n }\n return false;\n}\nfn shadow_passed(o: vec3f, d: vec3f, limit: f32) -> vec3f {\n if (!rt_valid(o,d,limit)) { return vec3f(0.0); }\n var passed=vec3f(1.0);\n var rq: ray_query;\n rayQueryInitialize(&rq,rt_world,RayDesc(RAY_FLAG_TERMINATE_ON_FIRST_HIT,0xffu,0.0001,limit,o,d));\n while (rayQueryProceed(&rq)) {\n let c=rayQueryGetCandidateIntersection(&rq);\n if (c.kind==RAY_QUERY_INTERSECTION_TRIANGLE) {\n passed*=tri_passes(rt_triangle(c),o,d,limit);\n } else {\n let i=rt_shape(c);\n let t=rt_shape_t(i,o,d,limit);\n if (t<limit && t>0.0001) { passed*=cast_tint(u32(shapes[i].c.w)); }\n }\n if (all(passed<=vec3f(0.0))) { rayQueryTerminate(&rq); }\n }\n if (rayQueryGetCommittedIntersection(&rq).kind!=RAY_QUERY_INTERSECTION_NONE) { return vec3f(0.0); }\n if (!RT_BOXES) {\n for (var i=0u;i<frame.counts.y;i++) {\n if (shapes[i].d.x > 0.5) { continue; }\n let t=rt_shape_t(i,o,d,limit);\n if (t<limit && t>0.0001) { passed*=cast_tint(u32(shapes[i].c.w)); }\n }\n }\n return passed;\n}\n";