# Texture space Raytracing of cylinder primitive in godot shader for Helix interception

I have been trying to do raytracing of an helix in a spatial shader in godot 4.2, but apparently I missed something because the result is bloby and melty at the cylinder level.

The basics is that I trace a 2d circle in the depth plane along U, then try to extrude it as a cylinder by scaling the view vector by the t values given in 2d. But that didn't turn out as expected and I'm a loss of where it got wrong, the normal also don't look correct.

I have already try many permutation, originally I was doing two cylinder packed in sizzling, and removed one for reproduction and removing noise. I used the scratchpixel raytracing's article notation.


uniform sampler2D text;

void fragment()
{
mat3 TBN = mat3(TANGENT, BINORMAL, NORMAL);
vec3 viewDirTangentSpace = TBN * VIEW;

const float mydepth = 1.0;
vec3 raydir = viewDirTangentSpace;///.5; // ray direction/depth

const vec2 centers = vec2(-0.0,.5);//x and depth
const float radius = 0.3;
const float r2 = radius * radius;

const vec2 UVsurfacePos = vec2(UV.x,0);

//vector: 2d origine to circles center in 2d along vertical depth plane
const vec2 L = centers.xy-UVsurfacePos.xy; const vec2 L2 = L*L;

//dot projection: 2d centers to 2d ray line
vec2 raydir2d = normalize(raydir.xz);
float tca = dot(L,raydir2d);

//2d distances to projected
float distances = abs( (L2.x + L2.y) - (tca) );
float d = sqrt( distances );float d2 = d * d;
//float d2 = distances * distances;

//2d intersections points
float thcdiff = r2 - d2; float thc = sqrt (thcdiff);
vec2 t = vec2(tca +thc, tca -thc);

//get extrusion in y
//vec3 p11 = vec3(UV,0) + raydir * t.x; //first impact column 1
//vec3 p12 = vec3(UV,0) + raydir * t.y; //second impact column 1
vec3 p11 = raydir * t.x; //first impact column 1
vec3 p12 = raydir * t.y; //second impact column 1

//get normal
vec3 N11 = normalize( vec3(  (UV+p11.xz - centers),0) );
vec3 N12 = normalize( vec3( -(UV+p12.xz - centers),0) );

//get twist
float twist11 = atan(N11.x, N11.y);
float twist12 = atan(-N12.x, -N12.y);//reverse the N

vec3 result = vec3(0.0); // black color if not intersecting

if( t.x > 0.0 && t.y > 0.0 )
{
result = vec3(1.0, 0.0, 0.0); // red color if intersecting cylinder1
}

float ptmin = min(t.x,t.y);
vec2 UVoffset = UV+raydir.xy * ptmin;

NORMAL = N11.xzy;
ALBEDO = texture(text, UVoffset).xyz;

}


The helix interception is supposed to work in this way:

• we find the hit point angle relative to the cylinder axis (using the normal orientation)
• we find at which height of the cylinder, the similar angle of the spiral land (angle change linearly across height)
• we compute if the hit point land with width of the spiral point at the same angle. else we discard.