Query: How can I undertaking 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 undertaking is utilizing Steel Shading Language however the ideas are related between GLSL/HLSL.
The web has offered a number of factors of reference for studying find out how to implement grid shading. What I’m fighting is the ideas required to convert between view areas to attain 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 digital camera place in clip area
- Calculate the airplane place in clip area
- Forged a ray from the digital camera to the ground airplane to seek out the purpose of intersection
- Render the world axis grid utilizing the purpose of intersection
Grid Rendering
This technique determines the ultimate output colour 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 ((place));
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 digital camera 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 route of ray from eye
float3 route = normalize(place - pov.xyz);
//airplane regular
float3 up = float3(0.f, 1.f, 0.f);
float magnitude = dot(up, route);
float size = dot((origin.xyz - pov.xyz), up) / magnitude;
if (size <= epsilon) { return backgroundColor; }
//decide hit location
float3 hit = pov.xyz + (route * 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 digital camera skews the grid traces incorrectly.
- After translating the digital camera the bottom airplane not aligns
This seems to be near what I wish to obtain however I’m uncertain the place to go from right here.
My guess is that the place returned from raycasting is wrong as a consequence 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 route.
How can I undertaking the fragment place onto the world ground airplane in respect to the digital camera?