improve shader import model (#5703)
# Objective
operate on naga IR directly to improve handling of shader modules.
- give codespan reporting into imported modules
- allow glsl to be used from wgsl and vice-versa
the ultimate objective is to make it possible to
- provide user hooks for core shader functions (to modify light
behaviour within the standard pbr pipeline, for example)
- make automatic binding slot allocation possible
but ... since this is already big, adds some value and (i think) is at
feature parity with the existing code, i wanted to push this now.
## Solution
i made a crate called naga_oil (https://github.com/robtfm/naga_oil -
unpublished for now, could be part of bevy) which manages modules by
- building each module independantly to naga IR
- creating "header" files for each supported language, which are used to
build dependent modules/shaders
- make final shaders by combining the shader IR with the IR for imported
modules
then integrated this into bevy, replacing some of the existing shader
processing stuff. also reworked examples to reflect this.
## Migration Guide
shaders that don't use `#import` directives should work without changes.
the most notable user-facing difference is that imported
functions/variables/etc need to be qualified at point of use, and
there's no "leakage" of visible stuff into your shader scope from the
imports of your imports, so if you used things imported by your imports,
you now need to import them directly and qualify them.
the current strategy of including/'spreading' `mesh_vertex_output`
directly into a struct doesn't work any more, so these need to be
modified as per the examples (e.g. color_material.wgsl, or many others).
mesh data is assumed to be in bindgroup 2 by default, if mesh data is
bound into bindgroup 1 instead then the shader def `MESH_BINDGROUP_1`
needs to be added to the pipeline shader_defs.
2023-06-27 00:29:22 +00:00
|
|
|
// TODO use common view binding
|
2023-10-21 11:51:58 +00:00
|
|
|
#import bevy_render::view::View
|
improve shader import model (#5703)
# Objective
operate on naga IR directly to improve handling of shader modules.
- give codespan reporting into imported modules
- allow glsl to be used from wgsl and vice-versa
the ultimate objective is to make it possible to
- provide user hooks for core shader functions (to modify light
behaviour within the standard pbr pipeline, for example)
- make automatic binding slot allocation possible
but ... since this is already big, adds some value and (i think) is at
feature parity with the existing code, i wanted to push this now.
## Solution
i made a crate called naga_oil (https://github.com/robtfm/naga_oil -
unpublished for now, could be part of bevy) which manages modules by
- building each module independantly to naga IR
- creating "header" files for each supported language, which are used to
build dependent modules/shaders
- make final shaders by combining the shader IR with the IR for imported
modules
then integrated this into bevy, replacing some of the existing shader
processing stuff. also reworked examples to reflect this.
## Migration Guide
shaders that don't use `#import` directives should work without changes.
the most notable user-facing difference is that imported
functions/variables/etc need to be qualified at point of use, and
there's no "leakage" of visible stuff into your shader scope from the
imports of your imports, so if you used things imported by your imports,
you now need to import them directly and qualify them.
the current strategy of including/'spreading' `mesh_vertex_output`
directly into a struct doesn't work any more, so these need to be
modified as per the examples (e.g. color_material.wgsl, or many others).
mesh data is assumed to be in bindgroup 2 by default, if mesh data is
bound into bindgroup 1 instead then the shader def `MESH_BINDGROUP_1`
needs to be added to the pipeline shader_defs.
2023-06-27 00:29:22 +00:00
|
|
|
|
2023-09-19 22:17:44 +00:00
|
|
|
@group(0) @binding(0) var<uniform> view: View;
|
improve shader import model (#5703)
# Objective
operate on naga IR directly to improve handling of shader modules.
- give codespan reporting into imported modules
- allow glsl to be used from wgsl and vice-versa
the ultimate objective is to make it possible to
- provide user hooks for core shader functions (to modify light
behaviour within the standard pbr pipeline, for example)
- make automatic binding slot allocation possible
but ... since this is already big, adds some value and (i think) is at
feature parity with the existing code, i wanted to push this now.
## Solution
i made a crate called naga_oil (https://github.com/robtfm/naga_oil -
unpublished for now, could be part of bevy) which manages modules by
- building each module independantly to naga IR
- creating "header" files for each supported language, which are used to
build dependent modules/shaders
- make final shaders by combining the shader IR with the IR for imported
modules
then integrated this into bevy, replacing some of the existing shader
processing stuff. also reworked examples to reflect this.
## Migration Guide
shaders that don't use `#import` directives should work without changes.
the most notable user-facing difference is that imported
functions/variables/etc need to be qualified at point of use, and
there's no "leakage" of visible stuff into your shader scope from the
imports of your imports, so if you used things imported by your imports,
you now need to import them directly and qualify them.
the current strategy of including/'spreading' `mesh_vertex_output`
directly into a struct doesn't work any more, so these need to be
modified as per the examples (e.g. color_material.wgsl, or many others).
mesh data is assumed to be in bindgroup 2 by default, if mesh data is
bound into bindgroup 1 instead then the shader def `MESH_BINDGROUP_1`
needs to be added to the pipeline shader_defs.
2023-06-27 00:29:22 +00:00
|
|
|
|
2023-03-20 20:57:54 +00:00
|
|
|
|
2023-06-13 06:49:47 +00:00
|
|
|
struct LineGizmoUniform {
|
|
|
|
line_width: f32,
|
|
|
|
depth_bias: f32,
|
|
|
|
#ifdef SIXTEEN_BYTE_ALIGNMENT
|
|
|
|
// WebGL2 structs must be 16 byte aligned.
|
|
|
|
_padding: vec2<f32>,
|
|
|
|
#endif
|
2023-03-20 20:57:54 +00:00
|
|
|
}
|
|
|
|
|
2023-09-19 22:17:44 +00:00
|
|
|
@group(1) @binding(0) var<uniform> line_gizmo: LineGizmoUniform;
|
2023-06-13 06:49:47 +00:00
|
|
|
|
|
|
|
struct VertexInput {
|
|
|
|
@location(0) position_a: vec3<f32>,
|
|
|
|
@location(1) position_b: vec3<f32>,
|
|
|
|
@location(2) color_a: vec4<f32>,
|
|
|
|
@location(3) color_b: vec4<f32>,
|
|
|
|
@builtin(vertex_index) index: u32,
|
|
|
|
};
|
|
|
|
|
2023-03-20 20:57:54 +00:00
|
|
|
struct VertexOutput {
|
2023-06-13 06:49:47 +00:00
|
|
|
@builtin(position) clip_position: vec4<f32>,
|
2023-03-20 20:57:54 +00:00
|
|
|
@location(0) color: vec4<f32>,
|
2024-03-25 19:10:45 +00:00
|
|
|
@location(1) uv: f32,
|
2023-06-13 06:49:47 +00:00
|
|
|
};
|
2023-03-20 20:57:54 +00:00
|
|
|
|
2023-11-14 22:36:02 +00:00
|
|
|
const EPSILON: f32 = 4.88e-04;
|
|
|
|
|
2023-06-13 06:49:47 +00:00
|
|
|
@vertex
|
|
|
|
fn vertex(vertex: VertexInput) -> VertexOutput {
|
2024-03-25 19:10:45 +00:00
|
|
|
var positions = array<vec2<f32>, 6>(
|
|
|
|
vec2(-0.5, 0.),
|
|
|
|
vec2(-0.5, 1.),
|
|
|
|
vec2(0.5, 1.),
|
|
|
|
vec2(-0.5, 0.),
|
|
|
|
vec2(0.5, 1.),
|
|
|
|
vec2(0.5, 0.)
|
2023-06-13 06:49:47 +00:00
|
|
|
);
|
|
|
|
let position = positions[vertex.index];
|
|
|
|
|
|
|
|
// algorithm based on https://wwwtyro.net/2019/11/18/instanced-lines.html
|
Normalise matrix naming (#13489)
# Objective
- Fixes #10909
- Fixes #8492
## Solution
- Name all matrices `x_from_y`, for example `world_from_view`.
## Testing
- I've tested most of the 3D examples. The `lighting` example
particularly should hit a lot of the changes and appears to run fine.
---
## Changelog
- Renamed matrices across the engine to follow a `y_from_x` naming,
making the space conversion more obvious.
## Migration Guide
- `Frustum`'s `from_view_projection`, `from_view_projection_custom_far`
and `from_view_projection_no_far` were renamed to
`from_clip_from_world`, `from_clip_from_world_custom_far` and
`from_clip_from_world_no_far`.
- `ComputedCameraValues::projection_matrix` was renamed to
`clip_from_view`.
- `CameraProjection::get_projection_matrix` was renamed to
`get_clip_from_view` (this affects implementations on `Projection`,
`PerspectiveProjection` and `OrthographicProjection`).
- `ViewRangefinder3d::from_view_matrix` was renamed to
`from_world_from_view`.
- `PreviousViewData`'s members were renamed to `view_from_world` and
`clip_from_world`.
- `ExtractedView`'s `projection`, `transform` and `view_projection` were
renamed to `clip_from_view`, `world_from_view` and `clip_from_world`.
- `ViewUniform`'s `view_proj`, `unjittered_view_proj`,
`inverse_view_proj`, `view`, `inverse_view`, `projection` and
`inverse_projection` were renamed to `clip_from_world`,
`unjittered_clip_from_world`, `world_from_clip`, `world_from_view`,
`view_from_world`, `clip_from_view` and `view_from_clip`.
- `GpuDirectionalCascade::view_projection` was renamed to
`clip_from_world`.
- `MeshTransforms`' `transform` and `previous_transform` were renamed to
`world_from_local` and `previous_world_from_local`.
- `MeshUniform`'s `transform`, `previous_transform`,
`inverse_transpose_model_a` and `inverse_transpose_model_b` were renamed
to `world_from_local`, `previous_world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh` type in WGSL mirrors this, however `transform` and
`previous_transform` were named `model` and `previous_model`).
- `Mesh2dTransforms::transform` was renamed to `world_from_local`.
- `Mesh2dUniform`'s `transform`, `inverse_transpose_model_a` and
`inverse_transpose_model_b` were renamed to `world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh2d` type in WGSL mirrors this).
- In WGSL, in `bevy_pbr::mesh_functions`, `get_model_matrix` and
`get_previous_model_matrix` were renamed to `get_world_from_local` and
`get_previous_world_from_local`.
- In WGSL, `bevy_sprite::mesh2d_functions::get_model_matrix` was renamed
to `get_world_from_local`.
2024-06-03 16:56:53 +00:00
|
|
|
var clip_a = view.clip_from_world * vec4(vertex.position_a, 1.);
|
|
|
|
var clip_b = view.clip_from_world * vec4(vertex.position_b, 1.);
|
2023-08-17 20:09:19 +00:00
|
|
|
|
|
|
|
// Manual near plane clipping to avoid errors when doing the perspective divide inside this shader.
|
|
|
|
clip_a = clip_near_plane(clip_a, clip_b);
|
|
|
|
clip_b = clip_near_plane(clip_b, clip_a);
|
2024-03-25 19:10:45 +00:00
|
|
|
let clip = mix(clip_a, clip_b, position.y);
|
2023-06-13 06:49:47 +00:00
|
|
|
|
|
|
|
let resolution = view.viewport.zw;
|
|
|
|
let screen_a = resolution * (0.5 * clip_a.xy / clip_a.w + 0.5);
|
|
|
|
let screen_b = resolution * (0.5 * clip_b.xy / clip_b.w + 0.5);
|
|
|
|
|
2024-03-25 19:10:45 +00:00
|
|
|
let y_basis = normalize(screen_b - screen_a);
|
|
|
|
let x_basis = vec2(-y_basis.y, y_basis.x);
|
2023-06-13 06:49:47 +00:00
|
|
|
|
2024-03-25 19:10:45 +00:00
|
|
|
var color = mix(vertex.color_a, vertex.color_b, position.y);
|
2023-06-13 06:49:47 +00:00
|
|
|
|
|
|
|
var line_width = line_gizmo.line_width;
|
|
|
|
var alpha = 1.;
|
|
|
|
|
2024-03-25 19:10:45 +00:00
|
|
|
var uv: f32;
|
2023-06-13 06:49:47 +00:00
|
|
|
#ifdef PERSPECTIVE
|
|
|
|
line_width /= clip.w;
|
2024-03-25 19:10:45 +00:00
|
|
|
|
|
|
|
// get height of near clipping plane in world space
|
Normalise matrix naming (#13489)
# Objective
- Fixes #10909
- Fixes #8492
## Solution
- Name all matrices `x_from_y`, for example `world_from_view`.
## Testing
- I've tested most of the 3D examples. The `lighting` example
particularly should hit a lot of the changes and appears to run fine.
---
## Changelog
- Renamed matrices across the engine to follow a `y_from_x` naming,
making the space conversion more obvious.
## Migration Guide
- `Frustum`'s `from_view_projection`, `from_view_projection_custom_far`
and `from_view_projection_no_far` were renamed to
`from_clip_from_world`, `from_clip_from_world_custom_far` and
`from_clip_from_world_no_far`.
- `ComputedCameraValues::projection_matrix` was renamed to
`clip_from_view`.
- `CameraProjection::get_projection_matrix` was renamed to
`get_clip_from_view` (this affects implementations on `Projection`,
`PerspectiveProjection` and `OrthographicProjection`).
- `ViewRangefinder3d::from_view_matrix` was renamed to
`from_world_from_view`.
- `PreviousViewData`'s members were renamed to `view_from_world` and
`clip_from_world`.
- `ExtractedView`'s `projection`, `transform` and `view_projection` were
renamed to `clip_from_view`, `world_from_view` and `clip_from_world`.
- `ViewUniform`'s `view_proj`, `unjittered_view_proj`,
`inverse_view_proj`, `view`, `inverse_view`, `projection` and
`inverse_projection` were renamed to `clip_from_world`,
`unjittered_clip_from_world`, `world_from_clip`, `world_from_view`,
`view_from_world`, `clip_from_view` and `view_from_clip`.
- `GpuDirectionalCascade::view_projection` was renamed to
`clip_from_world`.
- `MeshTransforms`' `transform` and `previous_transform` were renamed to
`world_from_local` and `previous_world_from_local`.
- `MeshUniform`'s `transform`, `previous_transform`,
`inverse_transpose_model_a` and `inverse_transpose_model_b` were renamed
to `world_from_local`, `previous_world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh` type in WGSL mirrors this, however `transform` and
`previous_transform` were named `model` and `previous_model`).
- `Mesh2dTransforms::transform` was renamed to `world_from_local`.
- `Mesh2dUniform`'s `transform`, `inverse_transpose_model_a` and
`inverse_transpose_model_b` were renamed to `world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh2d` type in WGSL mirrors this).
- In WGSL, in `bevy_pbr::mesh_functions`, `get_model_matrix` and
`get_previous_model_matrix` were renamed to `get_world_from_local` and
`get_previous_world_from_local`.
- In WGSL, `bevy_sprite::mesh2d_functions::get_model_matrix` was renamed
to `get_world_from_local`.
2024-06-03 16:56:53 +00:00
|
|
|
let pos0 = view.view_from_clip * vec4(0, -1, 0, 1); // Bottom of the screen
|
|
|
|
let pos1 = view.view_from_clip * vec4(0, 1, 0, 1); // Top of the screen
|
2024-03-25 19:10:45 +00:00
|
|
|
let near_clipping_plane_height = length(pos0.xyz - pos1.xyz);
|
|
|
|
|
|
|
|
// We can't use vertex.position_X because we may have changed the clip positions with clip_near_plane
|
Normalise matrix naming (#13489)
# Objective
- Fixes #10909
- Fixes #8492
## Solution
- Name all matrices `x_from_y`, for example `world_from_view`.
## Testing
- I've tested most of the 3D examples. The `lighting` example
particularly should hit a lot of the changes and appears to run fine.
---
## Changelog
- Renamed matrices across the engine to follow a `y_from_x` naming,
making the space conversion more obvious.
## Migration Guide
- `Frustum`'s `from_view_projection`, `from_view_projection_custom_far`
and `from_view_projection_no_far` were renamed to
`from_clip_from_world`, `from_clip_from_world_custom_far` and
`from_clip_from_world_no_far`.
- `ComputedCameraValues::projection_matrix` was renamed to
`clip_from_view`.
- `CameraProjection::get_projection_matrix` was renamed to
`get_clip_from_view` (this affects implementations on `Projection`,
`PerspectiveProjection` and `OrthographicProjection`).
- `ViewRangefinder3d::from_view_matrix` was renamed to
`from_world_from_view`.
- `PreviousViewData`'s members were renamed to `view_from_world` and
`clip_from_world`.
- `ExtractedView`'s `projection`, `transform` and `view_projection` were
renamed to `clip_from_view`, `world_from_view` and `clip_from_world`.
- `ViewUniform`'s `view_proj`, `unjittered_view_proj`,
`inverse_view_proj`, `view`, `inverse_view`, `projection` and
`inverse_projection` were renamed to `clip_from_world`,
`unjittered_clip_from_world`, `world_from_clip`, `world_from_view`,
`view_from_world`, `clip_from_view` and `view_from_clip`.
- `GpuDirectionalCascade::view_projection` was renamed to
`clip_from_world`.
- `MeshTransforms`' `transform` and `previous_transform` were renamed to
`world_from_local` and `previous_world_from_local`.
- `MeshUniform`'s `transform`, `previous_transform`,
`inverse_transpose_model_a` and `inverse_transpose_model_b` were renamed
to `world_from_local`, `previous_world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh` type in WGSL mirrors this, however `transform` and
`previous_transform` were named `model` and `previous_model`).
- `Mesh2dTransforms::transform` was renamed to `world_from_local`.
- `Mesh2dUniform`'s `transform`, `inverse_transpose_model_a` and
`inverse_transpose_model_b` were renamed to `world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh2d` type in WGSL mirrors this).
- In WGSL, in `bevy_pbr::mesh_functions`, `get_model_matrix` and
`get_previous_model_matrix` were renamed to `get_world_from_local` and
`get_previous_world_from_local`.
- In WGSL, `bevy_sprite::mesh2d_functions::get_model_matrix` was renamed
to `get_world_from_local`.
2024-06-03 16:56:53 +00:00
|
|
|
let position_a = view.inverse_clip_from_world * clip_a;
|
|
|
|
let position_b = view.inverse_clip_from_world * clip_b;
|
2024-03-25 19:10:45 +00:00
|
|
|
let world_distance = length(position_a.xyz - position_b.xyz);
|
|
|
|
|
|
|
|
// Offset to compensate for moved clip positions. If removed dots on lines will slide when position a is ofscreen.
|
|
|
|
let clipped_offset = length(position_a.xyz - vertex.position_a);
|
|
|
|
|
|
|
|
uv = (clipped_offset + position.y * world_distance) * resolution.y / near_clipping_plane_height / line_gizmo.line_width;
|
|
|
|
#else
|
|
|
|
// Get the distance of b to the camera along camera axes
|
Normalise matrix naming (#13489)
# Objective
- Fixes #10909
- Fixes #8492
## Solution
- Name all matrices `x_from_y`, for example `world_from_view`.
## Testing
- I've tested most of the 3D examples. The `lighting` example
particularly should hit a lot of the changes and appears to run fine.
---
## Changelog
- Renamed matrices across the engine to follow a `y_from_x` naming,
making the space conversion more obvious.
## Migration Guide
- `Frustum`'s `from_view_projection`, `from_view_projection_custom_far`
and `from_view_projection_no_far` were renamed to
`from_clip_from_world`, `from_clip_from_world_custom_far` and
`from_clip_from_world_no_far`.
- `ComputedCameraValues::projection_matrix` was renamed to
`clip_from_view`.
- `CameraProjection::get_projection_matrix` was renamed to
`get_clip_from_view` (this affects implementations on `Projection`,
`PerspectiveProjection` and `OrthographicProjection`).
- `ViewRangefinder3d::from_view_matrix` was renamed to
`from_world_from_view`.
- `PreviousViewData`'s members were renamed to `view_from_world` and
`clip_from_world`.
- `ExtractedView`'s `projection`, `transform` and `view_projection` were
renamed to `clip_from_view`, `world_from_view` and `clip_from_world`.
- `ViewUniform`'s `view_proj`, `unjittered_view_proj`,
`inverse_view_proj`, `view`, `inverse_view`, `projection` and
`inverse_projection` were renamed to `clip_from_world`,
`unjittered_clip_from_world`, `world_from_clip`, `world_from_view`,
`view_from_world`, `clip_from_view` and `view_from_clip`.
- `GpuDirectionalCascade::view_projection` was renamed to
`clip_from_world`.
- `MeshTransforms`' `transform` and `previous_transform` were renamed to
`world_from_local` and `previous_world_from_local`.
- `MeshUniform`'s `transform`, `previous_transform`,
`inverse_transpose_model_a` and `inverse_transpose_model_b` were renamed
to `world_from_local`, `previous_world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh` type in WGSL mirrors this, however `transform` and
`previous_transform` were named `model` and `previous_model`).
- `Mesh2dTransforms::transform` was renamed to `world_from_local`.
- `Mesh2dUniform`'s `transform`, `inverse_transpose_model_a` and
`inverse_transpose_model_b` were renamed to `world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh2d` type in WGSL mirrors this).
- In WGSL, in `bevy_pbr::mesh_functions`, `get_model_matrix` and
`get_previous_model_matrix` were renamed to `get_world_from_local` and
`get_previous_world_from_local`.
- In WGSL, `bevy_sprite::mesh2d_functions::get_model_matrix` was renamed
to `get_world_from_local`.
2024-06-03 16:56:53 +00:00
|
|
|
let camera_b = view.view_from_clip * clip_b;
|
2024-03-25 19:10:45 +00:00
|
|
|
|
|
|
|
// This differentiates between orthographic and perspective cameras.
|
|
|
|
// For orthographic cameras no depth adaptment (depth_adaptment = 1) is needed.
|
|
|
|
var depth_adaptment: f32;
|
|
|
|
if (clip_b.w == 1.0) {
|
|
|
|
depth_adaptment = 1.0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
depth_adaptment = -camera_b.z;
|
|
|
|
}
|
|
|
|
uv = position.y * depth_adaptment * length(screen_b - screen_a) / line_gizmo.line_width;
|
2023-03-29 18:05:03 +00:00
|
|
|
#endif
|
2023-03-20 20:57:54 +00:00
|
|
|
|
2023-06-13 06:49:47 +00:00
|
|
|
// Line thinness fade from https://acegikmo.com/shapes/docs/#anti-aliasing
|
2023-07-31 18:57:59 +00:00
|
|
|
if line_width > 0.0 && line_width < 1. {
|
2023-06-13 06:49:47 +00:00
|
|
|
color.a *= line_width;
|
|
|
|
line_width = 1.;
|
|
|
|
}
|
|
|
|
|
2024-03-25 19:10:45 +00:00
|
|
|
let x_offset = line_width * position.x * x_basis;
|
|
|
|
let screen = mix(screen_a, screen_b, position.y) + x_offset;
|
2023-03-20 20:57:54 +00:00
|
|
|
|
2023-06-13 06:49:47 +00:00
|
|
|
var depth: f32;
|
|
|
|
if line_gizmo.depth_bias >= 0. {
|
|
|
|
depth = clip.z * (1. - line_gizmo.depth_bias);
|
|
|
|
} else {
|
|
|
|
// depth * (clip.w / depth)^-depth_bias. So that when -depth_bias is 1.0, this is equal to clip.w
|
|
|
|
// and when equal to 0.0, it is exactly equal to depth.
|
2023-07-31 18:57:59 +00:00
|
|
|
// the epsilon is here to prevent the depth from exceeding clip.w when -depth_bias = 1.0
|
2023-07-10 00:11:51 +00:00
|
|
|
// clip.w represents the near plane in homogeneous clip space in bevy, having a depth
|
2023-06-13 06:49:47 +00:00
|
|
|
// of this value means nothing can be in front of this
|
2023-07-31 18:57:59 +00:00
|
|
|
// The reason this uses an exponential function is that it makes it much easier for the
|
2023-07-10 00:11:51 +00:00
|
|
|
// user to chose a value that is convenient for them
|
2023-11-14 22:36:02 +00:00
|
|
|
depth = clip.z * exp2(-line_gizmo.depth_bias * log2(clip.w / clip.z - EPSILON));
|
2023-06-13 06:49:47 +00:00
|
|
|
}
|
2023-03-20 20:57:54 +00:00
|
|
|
|
2023-06-13 06:49:47 +00:00
|
|
|
var clip_position = vec4(clip.w * ((2. * screen) / resolution - 1.), depth, clip.w);
|
|
|
|
|
2024-03-25 19:10:45 +00:00
|
|
|
return VertexOutput(clip_position, color, uv);
|
2023-03-20 20:57:54 +00:00
|
|
|
}
|
|
|
|
|
2023-08-17 20:09:19 +00:00
|
|
|
fn clip_near_plane(a: vec4<f32>, b: vec4<f32>) -> vec4<f32> {
|
|
|
|
// Move a if a is behind the near plane and b is in front.
|
|
|
|
if a.z > a.w && b.z <= b.w {
|
|
|
|
// Interpolate a towards b until it's at the near plane.
|
|
|
|
let distance_a = a.z - a.w;
|
|
|
|
let distance_b = b.z - b.w;
|
2023-11-14 22:36:02 +00:00
|
|
|
// Add an epsilon to the interpolator to ensure that the point is
|
|
|
|
// not just behind the clip plane due to floating-point imprecision.
|
|
|
|
let t = distance_a / (distance_a - distance_b) + EPSILON;
|
|
|
|
return mix(a, b, t);
|
2023-08-17 20:09:19 +00:00
|
|
|
}
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2023-06-13 06:49:47 +00:00
|
|
|
struct FragmentInput {
|
2024-03-25 19:10:45 +00:00
|
|
|
@builtin(position) position: vec4<f32>,
|
2023-06-13 06:49:47 +00:00
|
|
|
@location(0) color: vec4<f32>,
|
2024-03-25 19:10:45 +00:00
|
|
|
@location(1) uv: f32,
|
2023-06-13 06:49:47 +00:00
|
|
|
};
|
2023-03-20 20:57:54 +00:00
|
|
|
|
2023-06-13 06:49:47 +00:00
|
|
|
struct FragmentOutput {
|
|
|
|
@location(0) color: vec4<f32>,
|
|
|
|
};
|
2023-03-20 20:57:54 +00:00
|
|
|
|
2023-06-13 06:49:47 +00:00
|
|
|
@fragment
|
2024-03-25 19:10:45 +00:00
|
|
|
fn fragment_solid(in: FragmentInput) -> FragmentOutput {
|
2023-06-13 06:49:47 +00:00
|
|
|
return FragmentOutput(in.color);
|
2023-03-20 20:57:54 +00:00
|
|
|
}
|
2024-03-25 19:10:45 +00:00
|
|
|
@fragment
|
|
|
|
fn fragment_dotted(in: FragmentInput) -> FragmentOutput {
|
|
|
|
var alpha: f32;
|
|
|
|
#ifdef PERSPECTIVE
|
|
|
|
alpha = 1 - floor(in.uv % 2.0);
|
|
|
|
#else
|
|
|
|
alpha = 1 - floor((in.uv * in.position.w) % 2.0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return FragmentOutput(vec4(in.color.xyz, in.color.w * alpha));
|
|
|
|
}
|