#[set(everything)] const constants: { VP: float4x4; invVP: float4x4; mouse: float2; tex_step: float2; radius: float; camera_right: float3; tint: float3; }; #[set(everything)] const sampler_linear: sampler; #[set(everything)] const gbufferD: tex2d; struct vert_in { pos: float4; nor: float2; tex: float2; } struct vert_out { pos: float4; tex: float2; } fun get_pos(uv: float2): float3 { var depth: float = sample_lod(gbufferD, sampler_linear, float2(uv.x, 1.0 - uv.y), 0.0).r; var wpos: float4 = float4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0); wpos = constants.invVP * wpos; return wpos.xyz / wpos.w; } fun get_normal(p0: float3, uv: float2): float3 { var p1: float3 = get_pos(uv + float2(constants.tex_step.x * 4.0, 0.0)); var p2: float3 = get_pos(uv + float2(0.0, constants.tex_step.y * 4.0)); return normalize(cross(p2 - p0, p1 - p0)); } // fun create_basis(normal: float3, out tangent: float3, out binormal: float3) { // tangent = normalize(constants.camera_right - normal * dot(constants.camera_right, normal)); // binormal = cross(tangent, normal); // } fun cursor_vert(input: vert_in): vert_out { var keep: float = input.pos.x + input.nor.x; // hlsl var output: vert_out; output.tex = input.tex; var wpos: float3 = get_pos(constants.mouse); var uv1: float2 = constants.mouse + constants.tex_step * float2(4.0, 4.0); var uv2: float2 = constants.mouse - constants.tex_step * float2(4.0, 4.0); var wpos1: float3 = get_pos(uv1); var wpos2: float3 = get_pos(uv2); var n: float3 = normalize(get_normal(wpos, constants.mouse) + get_normal(wpos1, uv1) + get_normal(wpos2, uv2)); var n_tan: float3; var n_bin: float3; // create_basis(n, n_tan, n_bin); n_tan = normalize(constants.camera_right - n * dot(constants.camera_right, n)); n_bin = cross(n_tan, n); if (vertex_id() == 0) { wpos += normalize(-n_tan - n_bin) * 0.7 * constants.radius; } /*else */if (vertex_id() == 1) { wpos += normalize( n_tan - n_bin) * 0.7 * constants.radius; } /*else */if (vertex_id() == 2) { wpos += normalize( n_tan + n_bin) * 0.7 * constants.radius; } /*else */if (vertex_id() == 3) { wpos += normalize(-n_tan + n_bin) * 0.7 * constants.radius; } output.pos = constants.VP * float4(wpos, 1.0); return output; } fun cursor_frag(input: vert_out): float4 { var radius: float = 0.45; var thickness: float = 0.03; var dist: float = distance(input.tex, float2(0.5, 0.5)); var ring: float = smoothstep(radius - thickness, radius, dist) - smoothstep(radius, radius + thickness, dist); return float4(constants.tint, min(ring, 0.6)); } #[pipe] struct pipe { vertex = cursor_vert; fragment = cursor_frag; }