Skip to main content

RT_WGSL

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";