Direct 3D绘制流水线(渲染管线)
来源:互联网 发布:朋友圈小视频软件 编辑:程序博客网 时间:2024/04/30 17:30
一个3D模型要在显示器屏幕显示,必须顺序经过【世界变换】、【观察变换】和【投影变换】,顺序完成三个变换并在显示器显示的过程被称作绘制流水线。
1、世界变换
搭建3D场景时,首先要使用一个坐标系统来定位所有的3D模型的摆放位置,称为世界坐标系统。
每次在世界空间(3D场景)中放入一个3D模型,都必须根据该模型在世界空间的位置为其指定世界变换矩阵。
可以用以下函数得到世界变换矩阵,将这些变换矩阵相乘可以得到复杂的变换关系,使3D模型完成复杂的运动:
public static Matrix RotationYawPitchRoll(float yaw, float pitch, float roll);public static Matrix Translation(float x, float y, float z);public static Matrix RotationY(float yaw);public static Matrix RotationX(float pitch);public static Matrix RotationZ(float roll);public static Matrix Scaling(float x, float y, float z);public static Matrix Scaling(Vector3 vertex);
2、观察变换
一个观察者在世界空间中进行观察,所看到的部分场景就是要投影到显示器屏幕上的场景。
观察者在世界空间的不同位置所看到的是世界空间不同部分的场景。
摄像坐标系统:
首先,观察者必须在这个坐标系同原点;
其次,z轴坐标表示观察者到被观察模型的距离;
最后,要求投影面(即显示器屏幕)平行坐标系统的xy平面。
观察变换就是把观察者在场景中所看到的3D模型顶点的世界坐标系统坐标变换为摄像坐标系统坐标,为投影做好准备。
生成变换矩阵的函数:
public static Matrix LookAtLH(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector);
参数cameraPosition为观察者在世界空间中的位置参数cameraTarget为观察目标在世界空间中的位置
参数cameraUpVector为摄像坐标系统的y轴正方向
3、投影变换
将摄像空间中的3D模型转换为在显示器屏幕上显示的具有立体感的平面图形。
有两种类型的投影:透视投影,正交投影。(其中,正交投影忽略距离——z值的影响)
生成左手系统透视投影矩阵的函数:
public static Matrix PerspectiveFovLH(float fieldOfViewY, float aspectRatio, float znearPlane, float zfarPlane);
参数fieldOfViewY是y轴方向上的视场角(FoV),以弧度为单位参数aspectRatio是纵横比
参数znearPlane是近裁剪面到坐标原点(摄像机位置)的距离
参数zfarPlane是远裁剪面到坐标原点(摄像机位置)的距离
具体可以想象一个四棱台,小的面是近裁剪面,大的面是远裁剪面,这两个平行的面是平行于xy平面的,棱台的高即zfarPlane减去znearPlane的差值。
4、简单的显示
CustomVertex.TransformedColored结构只能定义已根据透视原理进行了变换的顶点,模型是静止的,无法控制。
要定义未经变换的顶点,可使用CustomVertex.PositionColored结构。
【显示三角形】
增加变量:
private VertexBuffer vertexBuffer = null;
修改OnCreateDevice方法:public void OnCreateDevice(object sender, EventArgs e) { /* * 其他Device初始化工作; */ Device dev = (Device) sender; this.vertexBuffer = new VertexBuffer( typeof(CustomVertex.PositionColored), 3, dev, 0, CustomVertex.PositionColored.Format, Pool.Default); this.vertexBuffer.Created += this.OnCreateVertexBuffer; this.OnCreateVertexBuffer(this.vertexBuffer, null); }
增加OnCreateVertexBuffer方法:public void OnCreateVertexBuffer(object sender, EventArgs e) { CustomVertex.PositionColored[] verts = (CustomVertex.PositionColored[])((VertexBuffer)sender).Lock(0, 0); verts[0].Position = new Vector3(-1.0f, -1.0f, 0.0f); verts[0].Color = Color.Red.ToArgb(); verts[1].Position = new Vector3(1.0f, -1.0f, 0.0f); verts[1].Color = Color.Green.ToArgb(); verts[2].Position = new Vector3(0.0f, 1.0f, 0.0f); verts[2].Color = Color.Blue.ToArgb(); this.vertexBuffer.Unlock(); }
增加绘制流水线的方法:private void SetupMatrices() { this.device.Transform.World = Matrix.RotationY(0); this.device.Transform.View = Matrix.LookAtLH( new Vector3(0.0f, 3.0f, -5.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f)); this.device.Transform.Projection = Matrix.PerspectiveFovLH( (float) Math.PI / 4, 1.0f, 1.0f, 100.0f); }
修改OnResetDevice方法:public void OnResetDevice(object sender, EventArgs e) { /* * Device参数变化时调用; */ Device dev = (Device) sender; dev.RenderState.CullMode = Cull.None; dev.RenderState.Lighting = false; this.SetupMatrices(); }
修改渲染方法:public void Render() { if (this.device == null) return; if (this.pause) //当窗口最小化或者不是可视化时,停止渲染; return; this.device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.WhiteSmoke, 1.0f, 0); this.device.BeginScene(); /* * 渲染代码必须放在这里; */ this.device.SetStreamSource(0, this.vertexBuffer, 0); this.device.VertexFormat = CustomVertex.PositionColored.Format; this.device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1); this.device.EndScene(); this.device.Present(); }
效果:
- Direct 3D绘制流水线(渲染管线)
- C# Managed DirectX 三角形旋转(修改Direct 3D绘制流水线(渲染管线)中代码)
- 对3D渲染管线(渲染流水线)的理解
- 3D渲染流水线
- 3D渲染流水线
- 3D渲染流水线
- 3D渲染流水线
- 3D渲染管线
- 3D渲染管线
- 3D渲染管线
- 渲染管线计算机如何绘制3d物体
- 3D图形渲染管线 (转)
- (一) 3D图形渲染管线
- 3D图形渲染管线
- 3D图形渲染管线
- 3D图形渲染管线
- 3D图形渲染管线
- 3D图形渲染管线
- Android面试题精选
- 关于研发核心团队建设的一些思考
- ZOJ Problem Set - 1315 Excuses, Excuses!(字符串处理的好题)
- Tomcat 6.0 日志处理
- SQL中的where条件,在数据库中提取与应用浅析
- Direct 3D绘制流水线(渲染管线)
- Qpython : 如何上传自己写的脚本
- Sublime Text 2 激活码
- 利用apache负载均衡热备份给内网穿透接口备份
- ORA-16032: parameter LOG_ARCHIVE_DEST_3 destination string cannot be translated
- HDU 3271 SNIBB(数位DP+构造)
- LeetCode --- 2. Add Two Numbers
- SecureCRTP配置几个小技巧
- 与身份验证HTTP服务器通信(Communicating with Authenticating HTTP Servers)