Search across packages, versions, files, declarations, and comments. Use multiple terms to narrow results (AND), and add @vertex, @fragment, or @compute to filter by shader stage.
1#define_import_path bevy_pbr::view_transformations
3#import bevy_pbr::mesh_view_bindings as view_bindings
4#import bevy_pbr::prepass_bindings
6/// World space:
7/// +y is up
9/// View space:
10/// -z is forward, +x is right, +y is up
11/// Forward is from the camera position into the scene.
12/// (0.0, 0.0, -1.0) is linear distance of 1.0 in front of the camera's view relative to the camera's rotation
13/// (0.0, 1.0, 0.0) is linear distance of 1.0 above the camera's view relative to the camera's rotation
15/// NDC (normalized device coordinate):
16/// https://www.w3.org/TR/webgpu/#coordinate-systems
17/// (-1.0, -1.0) in NDC is located at the bottom-left corner of NDC
18/// (1.0, 1.0) in NDC is located at the top-right corner of NDC
19/// Z is depth where:
20/// 1.0 is near clipping plane
21/// Perspective projection: 0.0 is inf far away
22/// Orthographic projection: 0.0 is far clipping plane
24/// UV space:
25/// 0.0, 0.0 is the top left
26/// 1.0, 1.0 is the bottom right
29// -----------------
30// TO WORLD --------
31// -----------------
33/// Convert a view space position to world space
34fn position_view_to_world(view_pos: vec3<f32>) -> vec3<f32> {
35 let world_pos = view_bindings::view.world_from_view * vec4(view_pos, 1.0);
36 return world_pos.xyz;
39/// Convert a clip space position to world space
40fn position_clip_to_world(clip_pos: vec4<f32>) -> vec3<f32> {
41 let world_pos = view_bindings::view.world_from_clip * clip_pos;
42 return world_pos.xyz;
45/// Convert a ndc space position to world space
46fn position_ndc_to_world(ndc_pos: vec3<f32>) -> vec3<f32> {
47 let world_pos = view_bindings::view.world_from_clip * vec4(ndc_pos, 1.0);
48 return world_pos.xyz / world_pos.w;
51/// Convert a view space direction to world space
52fn direction_view_to_world(view_dir: vec3<f32>) -> vec3<f32> {
53 let world_dir = view_bindings::view.world_from_view * vec4(view_dir, 0.0);
54 return world_dir.xyz;
57/// Convert a clip space direction to world space
58fn direction_clip_to_world(clip_dir: vec4<f32>) -> vec3<f32> {
59 let world_dir = view_bindings::view.world_from_clip * clip_dir;
60 return world_dir.xyz;
63// -----------------
64// TO VIEW ---------
65// -----------------
67/// Convert a world space position to view space
68fn position_world_to_view(world_pos: vec3<f32>) -> vec3<f32> {
69 let view_pos = view_bindings::view.view_from_world * vec4(world_pos, 1.0);
70 return view_pos.xyz;
73/// Convert a clip space position to view space
74fn position_clip_to_view(clip_pos: vec4<f32>) -> vec3<f32> {
75 let view_pos = view_bindings::view.view_from_clip * clip_pos;
76 return view_pos.xyz;
79/// Convert a ndc space position to view space
80fn position_ndc_to_view(ndc_pos: vec3<f32>) -> vec3<f32> {
81 let view_pos = view_bindings::view.view_from_clip * vec4(ndc_pos, 1.0);
82 return view_pos.xyz / view_pos.w;
85/// Convert a world space direction to view space
86fn direction_world_to_view(world_dir: vec3<f32>) -> vec3<f32> {
87 let view_dir = view_bindings::view.view_from_world * vec4(world_dir, 0.0);
88 return view_dir.xyz;
91/// Convert a clip space direction to view space
92fn direction_clip_to_view(clip_dir: vec4<f32>) -> vec3<f32> {
93 let view_dir = view_bindings::view.view_from_clip * clip_dir;
94 return view_dir.xyz;
97// -----------------
98// TO PREV. VIEW ---
99// -----------------
101fn position_world_to_prev_view(world_pos: vec3<f32>) -> vec3<f32> {
102 let view_pos = prepass_bindings::previous_view_uniforms.view_from_world *
103 vec4(world_pos, 1.0);
104 return view_pos.xyz;
107fn position_world_to_prev_ndc(world_pos: vec3<f32>) -> vec3<f32> {
108 let ndc_pos = prepass_bindings::previous_view_uniforms.clip_from_world *
109 vec4(world_pos, 1.0);
110 return ndc_pos.xyz / ndc_pos.w;
113// -----------------
114// TO CLIP ---------
115// -----------------
117/// Convert a world space position to clip space
118fn position_world_to_clip(world_pos: vec3<f32>) -> vec4<f32> {
119 let clip_pos = view_bindings::view.clip_from_world * vec4(world_pos, 1.0);
120 return clip_pos;
123/// Convert a view space position to clip space
124fn position_view_to_clip(view_pos: vec3<f32>) -> vec4<f32> {
125 let clip_pos = view_bindings::view.clip_from_view * vec4(view_pos, 1.0);
126 return clip_pos;
129/// Convert a world space direction to clip space
130fn direction_world_to_clip(world_dir: vec3<f32>) -> vec4<f32> {
131 let clip_dir = view_bindings::view.clip_from_world * vec4(world_dir, 0.0);
132 return clip_dir;
135/// Convert a view space direction to clip space
136fn direction_view_to_clip(view_dir: vec3<f32>) -> vec4<f32> {
137 let clip_dir = view_bindings::view.clip_from_view * vec4(view_dir, 0.0);
138 return clip_dir;
141// -----------------
142// TO NDC ----------
143// -----------------
145/// Convert a world space position to ndc space
146fn position_world_to_ndc(world_pos: vec3<f32>) -> vec3<f32> {
147 let ndc_pos = view_bindings::view.clip_from_world * vec4(world_pos, 1.0);
148 return ndc_pos.xyz / ndc_pos.w;
151/// Convert a view space position to ndc space
152fn position_view_to_ndc(view_pos: vec3<f32>) -> vec3<f32> {
153 let ndc_pos = view_bindings::view.clip_from_view * vec4(view_pos, 1.0);
154 return ndc_pos.xyz / ndc_pos.w;
157// -----------------
158// DEPTH -----------
159// -----------------
161/// Retrieve the perspective camera near clipping plane
162fn perspective_camera_near() -> f32 {
163 return view_bindings::view.clip_from_view[3][2];
166/// Convert ndc depth to linear view z.
167/// Note: Depth values in front of the camera will be negative as -z is forward
168fn depth_ndc_to_view_z(ndc_depth: f32) -> f32 {
169#ifdef VIEW_PROJECTION_PERSPECTIVE
170 return -perspective_camera_near() / ndc_depth;
171#else ifdef VIEW_PROJECTION_ORTHOGRAPHIC
172 return -(view_bindings::view.clip_from_view[3][2] - ndc_depth) / view_bindings::view.clip_from_view[2][2];
173#else
174 let view_pos = view_bindings::view.view_from_clip * vec4(0.0, 0.0, ndc_depth, 1.0);
175 return view_pos.z / view_pos.w;
176#endif
179/// Convert linear view z to ndc depth.
180/// Note: View z input should be negative for values in front of the camera as -z is forward
181fn view_z_to_depth_ndc(view_z: f32) -> f32 {
182#ifdef VIEW_PROJECTION_PERSPECTIVE
183 return -perspective_camera_near() / view_z;
184#else ifdef VIEW_PROJECTION_ORTHOGRAPHIC
185 return view_bindings::view.clip_from_view[3][2] + view_z * view_bindings::view.clip_from_view[2][2];
186#else
187 let ndc_pos = view_bindings::view.clip_from_view * vec4(0.0, 0.0, view_z, 1.0);
188 return ndc_pos.z / ndc_pos.w;
189#endif
192fn prev_view_z_to_depth_ndc(view_z: f32) -> f32 {
193#ifdef VIEW_PROJECTION_PERSPECTIVE
194 return -perspective_camera_near() / view_z;
195#else ifdef VIEW_PROJECTION_ORTHOGRAPHIC
196 return prepass_bindings::previous_view_uniforms.clip_from_view[3][2] +
197 view_z * prepass_bindings::previous_view_uniforms.clip_from_view[2][2];
198#else
199 let ndc_pos = prepass_bindings::previous_view_uniforms.clip_from_view *
200 vec4(0.0, 0.0, view_z, 1.0);
201 return ndc_pos.z / ndc_pos.w;
202#endif
205// -----------------
206// UV --------------
207// -----------------
209/// Convert ndc space xy coordinate [-1.0 .. 1.0] to uv [0.0 .. 1.0]
210fn ndc_to_uv(ndc: vec2<f32>) -> vec2<f32> {
211 return ndc * vec2(0.5, -0.5) + vec2(0.5);
214/// Convert uv [0.0 .. 1.0] coordinate to ndc space xy [-1.0 .. 1.0]
215fn uv_to_ndc(uv: vec2<f32>) -> vec2<f32> {
216 return uv * vec2(2.0, -2.0) + vec2(-1.0, 1.0);
219/// returns the (0.0, 0.0) .. (1.0, 1.0) position within the viewport for the current render target
220/// [0 .. render target viewport size] eg. [(0.0, 0.0) .. (1280.0, 720.0)] to [(0.0, 0.0) .. (1.0, 1.0)]
221fn frag_coord_to_uv(frag_coord: vec2<f32>) -> vec2<f32> {
222 return (frag_coord - view_bindings::view.viewport.xy) / view_bindings::view.viewport.zw;
225/// Convert frag coord to ndc
226fn frag_coord_to_ndc(frag_coord: vec4<f32>) -> vec3<f32> {
227 return vec3(uv_to_ndc(frag_coord_to_uv(frag_coord.xy)), frag_coord.z);
230/// Convert ndc space xy coordinate [-1.0 .. 1.0] to [0 .. render target
231/// viewport size]
232fn ndc_to_frag_coord(ndc: vec2<f32>) -> vec2<f32> {
233 return ndc_to_uv(ndc) * view_bindings::view.viewport.zw;
Contents