Query: How can I mission the fragment place onto the world ground airplane with respect to the cameras present translation, rotation and zoom?
I’m making an attempt to implement an infinite world ground grid shader, much like this query.
My mission is utilizing Metallic Shading Language however the ideas are comparable between GLSL/HLSL.
The web has supplied a number of factors of reference for studying easy methods to implement grid shading. What I’m scuffling with is the ideas required to convert between view areas to realize my objective.
I discover shaders significantly mystical due to the difficulties in debugging visually so I’ve damaged up what I perceive to be the required steps;
-
1.) Within the scene:
- Create a airplane that extends alongside the xy axis within the vary
[-1, -1] -> [1, 1]
- Create a airplane that extends alongside the xy axis within the vary
-
2.) Within the vertex shader:
- Set the fragment place so the airplane fills the view
- Return the untransformed vertex place
-
3.) Within the fragment shader:
- Calculate the digicam place in clip area
- Calculate the airplane place in clip area
- Solid a ray from the digicam to the ground airplane to seek out the purpose of intersection
- Render the world axis grid utilizing the purpose of intersection
Grid Rendering
This methodology determines the ultimate output shade for the world grid for a given level alongside the airplane.
inline float4 grid(float2 uv,
float scale,
float4 gridColor,
float4 backgroundColor) {
uv /= scale;
float2 fractional = abs(fract(uv + 0.5f));
float2 partial = fwidth(uv);
float2 level = smoothstep(-partial, partial, fractional);
float saturation = 1.f - saturate(level.x * level.y);
return combine(backgroundColor, gridColor, saturation);
}
Vertex Shader
The vertex shader passes the vertex place alongside to the fragment shader with none transformations. The vertex positions are within the vary [-1, -1] -> [1, 1]
which fills the viewport in clip area.
struct SurfaceFragment {
float4 place [[position]];
float2 uv;
};
vertex SurfaceFragment surface_vertex(SimpleVertex v [[ stage_in ]],
fixed SceneBuffer& scn_frame [[ buffer(0) ]]) {
return { .place = float4(v.place, 1.f),
.uv = v.place.xy };
}
Fragment Shader
fragment float4 surface_fragment(SurfaceFragment f [[stage_in]],
fixed SceneBuffer& scn_frame [[ buffer(0) ]]) {
//place is in clip area (z = 1.f (far airplane))
float3 place = float3(f.uv, 1.f);
//convert eye from digicam area to clip area
float4 pov = scn_frame.projectionTransform * float4(0.f, 0.f, 0.f, 1.f);
//convert airplane from world area to clip area
float4 origin = scn_frame.viewProjectionTransform * float4(0.f, 0.f, 0.f, 1.f);
//decide course of ray from eye
float3 course = normalize(place - pov.xyz);
//airplane regular
float3 up = float3(0.f, 1.f, 0.f);
float magnitude = dot(up, course);
float size = dot((origin.xyz - pov.xyz), up) / magnitude;
if (size <= epsilon) { return backgroundColor; }
//decide hit location
float3 hit = pov.xyz + (course * size);
//draw grid
return grid(hit.xz,
1.f,
gridColor,
backgroundColor);
}
Points
That is the ultimate output for the scene the place we will observe a couple of issues:
- Rotating the digicam skews the grid strains incorrectly.
- After translating the digicam the bottom airplane not aligns
This appears to be near what I need to obtain however I’m not sure the place to go from right here.
My guess is that the place returned from raycasting is wrong on account of both:
- Incorrect transformations between clip area and world area.
- Incorrect placement of the airplane in world area.
- Incorrectly casting the ray from the unsuitable pov or course.
How can I mission the fragment place onto the world ground airplane in respect to the digicam?