Files
2026-07-13 12:24:51 +08:00

205 lines
7.4 KiB
GLSL

(
name: "GridShader",
resources: [
(
name: "properties",
kind: PropertyGroup([
(
name: "diffuseColor",
kind: Color(r: 40, g: 40, b: 40, a: 255),
),
(
name: "xAxisColor",
kind: Color(r: 255, g: 0, b: 0, a: 255),
),
(
name: "yAxisColor",
kind: Color(r: 0, g: 255, b: 0, a: 255),
),
(
name: "zAxisColor",
kind: Color(r: 0, g: 0, b: 255, a: 255),
),
(
name: "orientation",
kind: Int(value: 0),
),
(
name: "isPerspective",
kind: Bool(value: false)
),
(
name: "scale",
kind: Vector2(value: (1.0, 1.0))
)
]),
binding: 0
),
(
name: "fyrox_cameraData",
kind: PropertyGroup([
// Autogenerated
]),
binding: 1
),
],
disabled_passes: ["GBuffer", "DirectionalShadow", "PointShadow", "SpotShadow"],
passes: [
(
name: "Forward",
draw_parameters: DrawParameters(
cull_face: None,
color_write: ColorMask(
red: true,
green: true,
blue: true,
alpha: true,
),
depth_write: true,
stencil_test: None,
depth_test: Some(Less),
blend: Some(BlendParameters(
func: BlendFunc(
sfactor: SrcAlpha,
dfactor: OneMinusSrcAlpha,
alpha_sfactor: SrcAlpha,
alpha_dfactor: OneMinusSrcAlpha,
),
equation: BlendEquation(
rgb: Add,
alpha: Add
)
)),
stencil_op: StencilOp(
fail: Keep,
zfail: Keep,
zpass: Keep,
write_mask: 0xFFFF_FFFF,
),
scissor_box: None
),
vertex_shader:
r#"
layout(location = 0) in vec3 vertexPosition;
out vec3 nearPoint;
out vec3 farPoint;
vec3 Unproject(float x, float y, float z, mat4 matrix)
{
vec4 position = matrix * vec4(x, y, z, 1.0);
return position.xyz / position.w;
}
void main()
{
mat4 invViewProj = inverse(fyrox_cameraData.viewProjectionMatrix);
nearPoint = Unproject(vertexPosition.x, vertexPosition.y, 0.0, invViewProj);
farPoint = Unproject(vertexPosition.x, vertexPosition.y, 1.0, invViewProj);
gl_Position = vec4(vertexPosition, 1.0);
}
"#,
fragment_shader:
r#"
// Original code: https://asliceofrendering.com/scene%20helper/2020/01/05/InfiniteGrid/
// Fixed and adapted for Fyrox.
out vec4 FragColor;
in vec3 nearPoint;
in vec3 farPoint;
vec4 grid(vec3 fragPos3D) {
vec2 projection;
vec3 planeNormal;
vec4 xColor;
vec4 yColor;
if (properties.orientation == 0) {
projection = fragPos3D.xz;
planeNormal = vec3(0.0, 1.0, 0.0);
xColor = properties.xAxisColor;
yColor = properties.zAxisColor;
} else if (properties.orientation == 1) {
projection = fragPos3D.xy;
planeNormal = vec3(0.0, 0.0, 1.0);
xColor = properties.yAxisColor;
yColor = properties.xAxisColor;
} else if (properties.orientation == 2) {
projection = fragPos3D.zy;
planeNormal = vec3(1.0, 0.0, 0.0);
xColor = properties.zAxisColor;
yColor = properties.yAxisColor;
}
vec2 coord = projection * properties.scale;
vec2 derivative = fwidth(coord);
vec2 grid = abs(fract(coord - 0.5) - 0.5) / derivative;
float line = min(grid.x, grid.y);
float minX = 0.5 * min(derivative.x, 1.0);
float minY = 0.5 * min(derivative.y, 1.0);
vec4 color = properties.diffuseColor;
float alpha = 1.0 - min(line, 1.0);
// Sharpen lines a bit.
color.a = alpha >= 0.5 ? 1.0 : 0.0;
if (projection.x > -minX && projection.x < minX) {
color.xyz = xColor.xyz;
} else if (projection.y > -minY && projection.y < minY) {
color.xyz = yColor.xyz;
} else {
vec3 viewDir = fragPos3D - fyrox_cameraData.position;
// This helps to negate moire pattern at large distances.
float cosAngle = abs(dot(planeNormal, normalize(viewDir)));
color.a *= cosAngle;
}
return color;
}
float computeDepth(vec3 pos) {
vec4 clip_space_pos = fyrox_cameraData.viewProjectionMatrix * vec4(pos.xyz, 1.0);
return (clip_space_pos.z / clip_space_pos.w);
}
void main()
{
float nearCoord;
float farCoord;
if (properties.orientation == 0) {
nearCoord = nearPoint.y;
farCoord = farPoint.y;
} else if (properties.orientation == 1) {
nearCoord = nearPoint.z;
farCoord = farPoint.z;
} else if (properties.orientation == 2) {
nearCoord = nearPoint.x;
farCoord = farPoint.x;
}
float denominator = farCoord - nearCoord;
float t = denominator != 0.0 ? -nearCoord / denominator : 0.0;
vec3 fragPos3D = nearPoint + t * (farPoint - nearPoint);
float depth = computeDepth(fragPos3D);
gl_FragDepth = ((gl_DepthRange.diff * depth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
FragColor = grid(fragPos3D);
if (properties.isPerspective) {
FragColor.a *= float(t > 0.0);
}
// Alpha test to prevent blending issues.
if (FragColor.a < 0.01) {
discard;
}
}
"#,
),
],
)