Perspective
7242 ワード
https://github.com/glium/glium/blob/master/book/tuto-10-perspective.md
水筒を描くときにシェーダに渡される行列には、水筒モデルの位置、回転、サイズが含まれます.
OpenGLでは、行列はColumn Major
例)
AddressRow-major OrderColumn-major order0a[1, 1]a[1, 1]1a[1, 2]a[2, 1]2a[1, 3]a[1, 2]3a[2, 1]a[2, 2]4a[2, 2]a[1, 3]5a[2, 3]a[2, 3]
以前の内容では,z成分の増加または減少が変化しなかったのは直交投影に起因した.
遠くの物体をより小さく見せるには、x座標とy座標をz座標に分けるだけです.
z座標はゼロにすることができるので、頂点シェーダ演算後にw値で除算する
原点がスクリーンの中央にあるため、距離が遠い物体ほどスクリーンの原点に近づくように見えます
現在、レンダリングされたイメージはウィンドウサイズの増加に伴って減少します.
-1~1の座標は、ウィンドウの幅または高さに一致するため、通常の状態です.
画面の高さ/幅にx座標を乗じて、ウィンドウの幅や幅が変化したときに画面に表示される内容が大きくなったり小さくなったりしないようにすることができます.
aspect ratio = height/width fov:カメラ目線 znear:カメラ視野角の最小深さ zfar:カメラ視野角の最大深さ 頂点シェーダを修正するには
水筒を描くときにシェーダに渡される行列には、水筒モデルの位置、回転、サイズが含まれます.
Column Major
OpenGLでは、行列はColumn Major
例)
AddressRow-major OrderColumn-major order0a[1, 1]a[1, 1]1a[1, 2]a[2, 1]2a[1, 3]a[1, 2]3a[2, 1]a[2, 2]4a[2, 2]a[1, 3]5a[2, 3]a[2, 3]
以前の内容では,z成分の増加または減少が変化しなかったのは直交投影に起因した.
Correcting the perspective
遠くの物体をより小さく見せるには、x座標とy座標をz座標に分けるだけです.
z座標はゼロにすることができるので、頂点シェーダ演算後にw値で除算する
原点がスクリーンの中央にあるため、距離が遠い物体ほどスクリーンの原点に近づくように見えます
Aspect ratio
現在、レンダリングされたイメージはウィンドウサイズの増加に伴って減少します.
-1~1の座標は、ウィンドウの幅または高さに一致するため、通常の状態です.
画面の高さ/幅にx座標を乗じて、ウィンドウの幅や幅が変化したときに画面に表示される内容が大きくなったり小さくなったりしないようにすることができます.
Introducing the perspective matrix
let perspective = {
let (width, height) = target.get_dimensions();
let aspect_ratio = height as f32 / width as f32;
let fov: f32 = 3.141592 / 3.0;
let zfar = 1024.0;
let znear = 0.1;
let f = 1.0 / (fov / 2.0).tan();
[
[f * aspect_ratio, 0.0, 0.0 , 0.0],
[ 0.0 , f , 0.0 , 0.0],
[ 0.0 , 0.0, (zfar+znear)/(zfar-znear) , 1.0],
[ 0.0 , 0.0, -(2.0*zfar*znear)/(zfar-znear), 0.0],
]
};
パース投影マトリクスを作成するには4つのパラメータが必要です#version 140
in vec3 position;
in vec3 normal;
out vec3 v_normal;
uniform mat4 perspective; // new
uniform mat4 matrix;
void main() {
v_normal = transpose(inverse(mat3(matrix))) * normal;
gl_Position = perspective * matrix * vec4(position, 1.0); // new
}
drawコードの変更target.draw((&positions, &normals), &indices, &program,
&uniform! { matrix: matrix, perspective: perspective, u_light: light },
¶ms).unwrap();
マトリックスの修正let matrix = [
[0.01, 0.0, 0.0, 0.0],
[0.0, 0.01, 0.0, 0.0],
[0.0, 0.0, 0.01, 0.0],
[0.0, 0.0, 2.0, 1.0f32]
];
完全なコード#[macro_use]
extern crate glium;
mod teapot;
fn main() {
#[allow(unused_imports)]
use glium::{glutin, Surface};
let mut event_loop = glutin::event_loop::EventLoop::new();
let wb = glutin::window::WindowBuilder::new();
let cb = glutin::ContextBuilder::new().with_depth_buffer(24);
let display = glium::Display::new(wb, cb, &event_loop).unwrap();
let positions = glium::VertexBuffer::new(&display, &teapot::VERTICES).unwrap();
let normals = glium::VertexBuffer::new(&display, &teapot::NORMALS).unwrap();
let indices = glium::IndexBuffer::new(
&display,
glium::index::PrimitiveType::TrianglesList,
&teapot::INDICES,
)
.unwrap();
let light = [-1.0, 0.4, 0.9f32];
let vertex_shader_src = r#"
#version 150 // updated
in vec3 position;
in vec3 normal;
out vec3 v_normal;
uniform mat4 perspective; // new
uniform mat4 matrix;
void main() {
v_normal = transpose(inverse(mat3(matrix))) * normal;
gl_Position = perspective * matrix * vec4(position, 1.0); // new
}
"#;
let fragment_shader_src = r#"
#version 140
in vec3 v_normal;
out vec4 color;
uniform vec3 u_light;
void main() {
float brightness = dot(normalize(v_normal), normalize(u_light));
vec3 dark_color = vec3(0.6, 0.0, 0.0);
vec3 regular_color = vec3(1.0, 0.0, 0.0);
color = vec4(mix(dark_color, regular_color, brightness), 1.0);
}
"#;
let program =
glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None)
.unwrap();
let params = glium::DrawParameters {
depth: glium::Depth {
test: glium::draw_parameters::DepthTest::IfLess,
write: true,
.. Default::default()
},
.. Default::default()
};
let mut t: f32 = -0.5;
event_loop.run(move |event, _, control_flow| {
match event {
glutin::event::Event::WindowEvent { event, .. } => match event {
glutin::event::WindowEvent::CloseRequested => {
*control_flow = glutin::event_loop::ControlFlow::Exit;
return;
}
_ => return,
},
glutin::event::Event::NewEvents(cause) => match cause {
glutin::event::StartCause::ResumeTimeReached { .. } => (),
glutin::event::StartCause::Init => (),
_ => return,
},
_ => return,
}
let next_frame_time =
std::time::Instant::now() + std::time::Duration::from_nanos(16_666_667);
*control_flow = glutin::event_loop::ControlFlow::WaitUntil(next_frame_time);
t += 0.002;
if t > 0.5 {
t = -0.5;
}
let mut target = display.draw();
target.clear_color_and_depth((0.3, 0.5, 0.7, 1.0), 1.0);
let perspective = {
let (width, height) = target.get_dimensions();
let aspect_ratio = height as f32 / width as f32;
let fov: f32 = 3.141592 / 3.0;
let zfar = 1024.0;
let znear = 0.1;
let f = 1.0 / (fov / 2.0).tan();
[
[f * aspect_ratio , 0.0, 0.0 , 0.0],
[ 0.0 , f , 0.0 , 0.0],
[ 0.0 , 0.0, (zfar+znear)/(zfar-znear) , 1.0],
[ 0.0 , 0.0, -(2.0*zfar*znear)/(zfar-znear), 0.0],
]
};
let uniforms = uniform! {
// matrix: [
// [ t.cos(), t.sin(), 0.0, 0.0],
// [-t.sin(), t.cos(), 0.0, 0.0],
// [0.0, 0.0, 1.0, 0.0],
// [0.0, 0.0, 0.0, 1.0f32],
// ]
matrix: [
[0.01, 0.0, 0.0, 0.0],
[0.0, 0.01, 0.0, 0.0],
[0.0, 0.0, 0.01, 0.0],
[0.0, 0.0, 2.0, 1.0f32]
],
perspective: perspective,
u_light: light
};
target
.draw(
(&positions, &normals),
&indices,
&program,
&uniforms,
¶ms,
)
.unwrap();
target.finish().unwrap();
});
}
Reference
この問題について(Perspective), 我々は、より多くの情報をここで見つけました https://velog.io/@dunyazad/Perspectiveテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol