[rs] Add conversion matrix from OpenGL to wgpu

The matrices in the examples are given in an OpenGL-like coordinate system,
while a Vulkan-like coordinate system is used by wgpu. This was previously
partially corrected in the shader and by flipping the up axis of the camera,
but left the x-axis mirrored in the final result.

This change adds a conversion matrix to framework.rs that can be used
to convert from OpenGL to wgpu. This also allows us to set the
winding-order to counter-clockwise, which matches the ordering in the data.
This commit is contained in:
Svenn-Arne Dragly
2019-07-05 15:02:19 +02:00
parent a70eab2e3b
commit f76b41420e
7 changed files with 23 additions and 18 deletions

View File

@@ -98,9 +98,10 @@ impl Example {
let mx_view = cgmath::Matrix4::look_at(
cgmath::Point3::new(1.5f32, -5.0, 3.0),
cgmath::Point3::new(0f32, 0.0, 0.0),
-cgmath::Vector3::unit_z(),
cgmath::Vector3::unit_z(),
);
mx_projection * mx_view
let mx_correction = framework::opengl_to_wgpu_matrix();
mx_correction * mx_projection * mx_view
}
}
@@ -251,7 +252,7 @@ impl framework::Example for Example {
entry_point: "main",
}),
rasterization_state: wgpu::RasterizationStateDescriptor {
front_face: wgpu::FrontFace::Cw,
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::Back,
depth_bias: 0,
depth_bias_slope_scale: 0.0,

View File

@@ -11,6 +11,4 @@ layout(set = 0, binding = 0) uniform Locals {
void main() {
v_TexCoord = a_TexCoord;
gl_Position = u_Transform * a_Pos;
// convert from -1,1 Z to 0,1
gl_Position.z = 0.5 * (gl_Position.z + gl_Position.w);
}

View File

@@ -30,6 +30,14 @@ pub fn load_glsl(code: &str, stage: ShaderStage) -> Vec<u8> {
spv
}
pub fn opengl_to_wgpu_matrix() -> cgmath::Matrix4<f32> {
// converts from -1,1 Z to 0,1 Z and flips Y
cgmath::Matrix4::new(1.0, 0.0, 0.0, 0.0,
0.0, -1.0, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.0, 0.0, 0.5, 1.0)
}
pub trait Example {
fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self;
fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device);

View File

@@ -10,6 +10,4 @@ layout(set = 0, binding = 0) uniform Locals {
void main() {
v_TexCoord = a_Pos.xy / 20.0 + 0.5;
gl_Position = u_Transform * a_Pos;
// convert from -1,1 Z to 0,1
gl_Position.z = 0.5 * (gl_Position.z + gl_Position.w);
}

View File

@@ -62,9 +62,10 @@ impl Example {
let mx_view = cgmath::Matrix4::look_at(
cgmath::Point3::new(0f32, 0.0, 10.0),
cgmath::Point3::new(0f32, 50.0, 0.0),
-cgmath::Vector3::unit_z(),
cgmath::Vector3::unit_z(),
);
mx_projection * mx_view
let mx_correction = framework::opengl_to_wgpu_matrix();
mx_correction * mx_projection * mx_view
}
fn generate_mipmaps(
@@ -110,7 +111,7 @@ impl Example {
entry_point: "main",
}),
rasterization_state: wgpu::RasterizationStateDescriptor {
front_face: wgpu::FrontFace::Cw,
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::None,
depth_bias: 0,
depth_bias_slope_scale: 0.0,
@@ -337,7 +338,7 @@ impl framework::Example for Example {
entry_point: "main",
}),
rasterization_state: wgpu::RasterizationStateDescriptor {
front_face: wgpu::FrontFace::Cw,
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::Back,
depth_bias: 0,
depth_bias_slope_scale: 0.0,

View File

@@ -19,6 +19,4 @@ void main() {
v_Normal = mat3(u_World) * vec3(a_Normal.xyz);
v_Position = u_World * vec4(a_Pos);
gl_Position = u_ViewProj * v_Position;
// convert from -1,1 Z to 0,1
gl_Position.z = 0.5 * (gl_Position.z + gl_Position.w);
}

View File

@@ -106,7 +106,7 @@ impl Light {
fn to_raw(&self) -> LightRaw {
use cgmath::{Deg, EuclideanSpace, Matrix4, PerspectiveFov, Point3, Vector3};
let mx_view = Matrix4::look_at(self.pos, Point3::origin(), -Vector3::unit_z());
let mx_view = Matrix4::look_at(self.pos, Point3::origin(), Vector3::unit_z());
let projection = PerspectiveFov {
fovy: Deg(self.fov).into(),
aspect: 1.0,
@@ -172,9 +172,10 @@ impl Example {
let mx_view = cgmath::Matrix4::look_at(
cgmath::Point3::new(3.0f32, -10.0, 6.0),
cgmath::Point3::new(0f32, 0.0, 0.0),
-cgmath::Vector3::unit_z(),
cgmath::Vector3::unit_z(),
);
mx_projection * mx_view
let mx_correction = framework::opengl_to_wgpu_matrix();
mx_correction * mx_projection * mx_view
}
}
@@ -450,7 +451,7 @@ impl framework::Example for Example {
entry_point: "main",
}),
rasterization_state: wgpu::RasterizationStateDescriptor {
front_face: wgpu::FrontFace::Cw,
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::Back,
depth_bias: 2, // corresponds to bilinear filtering
depth_bias_slope_scale: 2.0,
@@ -573,7 +574,7 @@ impl framework::Example for Example {
entry_point: "main",
}),
rasterization_state: wgpu::RasterizationStateDescriptor {
front_face: wgpu::FrontFace::Cw,
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::Back,
depth_bias: 0,
depth_bias_slope_scale: 0.0,