当前位置: 首页 > news >正文

网站备案通过后怎么办房产网站建设什么类型

网站备案通过后怎么办,房产网站建设什么类型,网站开发成app,铭万魔方做网站怎么样文章目录 前言一、视点和视线1. 视点、观察目标点和上方向2. 实例#xff1a;通过键盘改变视点观察立方体 二、可视空间1. 正射投影正交投影本质#xff1a; 2. 透视投影透视投影矩阵本质#xff1a; 3. 隐藏面设置 前言 本篇继续前面文章来讲解投影矩阵相关内容。本篇标题… 文章目录 前言一、视点和视线1. 视点、观察目标点和上方向2. 实例通过键盘改变视点观察立方体 二、可视空间1. 正射投影正交投影本质 2. 透视投影透视投影矩阵本质 3. 隐藏面设置 前言 本篇继续前面文章来讲解投影矩阵相关内容。本篇标题为进入三维世界那么我们需要用我们真实的三维世界来观察我们绘制的三维图形。 首先我们要知道视并不存在真正的摄像机只不过是在世界坐标系里面选择一个点作为摄像机的位置。然后根据一些参数在这个点构建一个坐标系。然后通过 视图矩阵将世界坐标系的坐标变换到摄像机坐标系下。 WebGL 成像采用的是虚拟相机模型。在场景中你通过模型变换将物体放在场景中不同位置后最终哪些部分需要成像显示在屏幕上主要由视变换和后面要 介绍的投影变换、视口变换等决定。其中视变换阶段通过假想的相机来处理矩阵计算能够方便处理。对于 WebGL 来说并不存在真正的相机所谓的相机坐标空间(camera space 或者 eye space)只是为了方便处理而引入的坐标空间。 首先要明白的是投影变换是将摄像机坐标系下的物体变换到剪裁坐标系投影变换是通过乘以投影矩阵实现。投影方式有两种一种是正交投影一种透视投影。 一、视点和视线 首先我们来研究一下如何定义三维世界的观察者在什么地方、朝哪里看、视野有多宽、能看多远。 三维物体与二维图形的最显著的区别就是三维物体有深度也就是 z 轴。事实上我们最后还是得把三维场景绘制到二维的屏幕上即绘制观察者看到的世界而观察者可以处在任意位置观察。为了定义一个观察者我们需要考虑下面两点 观察方向也就是观察者自己在什么位置朝向哪里观看可视距离就是观察者能够看多远 我们将观察者所处的位置定义为视点从视点出发沿着观察方向的射线称作为视线。在之前绘制 “F” 图形的时候默认情况下视点处于圆点 (0, 0, 0)视线为 z 轴负半轴指向屏幕里面。 1. 视点、观察目标点和上方向 为了确定观察者的状态需要确定三个信息 视点观察者的位置视线的起点下面表述都用坐标 (eyeX, eyeY, eyeZ) 表示观察目标点被观察目标所在的点他可以同来确定视线。观察目标点是一个点。观察点坐标用 (atX, atY, atZ) 表示上方向为了将观察到的景色绘制到屏幕上它是具有三个分量的矢量用 (upX, upY, upZ) 表示 也就是说通过视点、视线、上方向我们可以定义一个观察坐标系。也就是说我们真实看到的物体是需要下面坐标系的转换 观察坐标系 眼睛在原点z 轴是视线方向x y 平面和 z 轴垂直 首先是模型坐标也就是我们绘制 “F” 时定义的坐标这里需要注意的是也是之前一直在强调我们定义坐标的时候是将 y 轴看做是从下往上的我们在转换时候需要将 y 轴坐标进行取反以为 canvas 的坐标是从上往下的方向然后我们需要将模型坐标转换为世界坐标世界坐标就是 webgl 显示坐标[-1, 1]范围。然后需要将世界坐标进一步换系转换到观察坐标。最后通过投影、剪裁空间进行显示物体。 至于将世界坐标转换到我们观察者坐标系。如下图 观察者坐标系 (xv, yv, zv)世界坐标系xyz对于观察坐标系其实就是首先将坐标移动到世界坐标系。反过来的过程也就是先旋转然后进行平移操作然后将世界坐标系的坐标乘以该变换矩阵就可以得到在观察者坐标系下的坐标。 下面是视图矩阵的推导过程 封装对应生成视图矩阵方法如下 我们将设置从哪里看图形的矩阵称为视图矩阵。 /*** 创建视图矩阵* param eyeX, 指定视点* param atX, 指定观察点* param upX, 指定上方向如果上方向是 Y 轴正方向那么传入(0, 1, 0)* return this*/ Matrix4.prototype.setLookAt function(eyeX, eyeY, eyeZ, atX, atY, atZ, upX, upY, upZ) {var e, fx, fy, fz, rlf, sx, sy, sz, rls, ux, uy, uz;fx atX - eyeX;fy atY - eyeY;fz atZ - eyeZ;// Normalize f.rlf 1 / Math.sqrt(fx*fx fy*fy fz*fz);fx * rlf;fy * rlf;fz * rlf;// 计算上方向通过叉乘得到法向量sx fy * upZ - fz * upY;sy fz * upX - fx * upZ;sz fx * upY - fy * upX;// Normalize s.rls 1 / Math.sqrt(sx*sx sy*sy sz*sz);sx * rls;sy * rls;sz * rls;// Calculate cross product of s and f.ux sy * fz - sz * fy;uy sz * fx - sx * fz;uz sx * fy - sy * fx;e this.elements;e[0] sx;e[1] ux;e[2] -fx;e[3] 0;e[4] sy;e[5] uy;e[6] -fy;e[7] 0;e[8] sz;e[9] uz;e[10] -fz;e[11] 0;e[12] 0;e[13] 0;e[14] 0;e[15] 1;return this.elements };2. 实例通过键盘改变视点观察立方体 整体代码如下 import React, { useRef, useEffect } from react import { VSHADERR_SOURCE, FSHADER_SOURCE } from ./glsl import { initShader } from ../../utils/webglFunc import { vertices, indices, colors } from ../HelloCube/data import Matrix4 from ../../utils/matrix import ./index.cssconst LookAtF () {const canvasDom useRefHTMLCanvasElement | null(null)const requestID useRefnumber()const initArrayBuffer (gl: WebGLRenderingContext, data: Float32Array, num: number, type: number, attribute: string) {var buffer gl.createBuffer() // 创建缓冲区对象if (!buffer) {console.log(Failed to create the buffer object)return false}// 将数据写入缓冲区对象gl.bindBuffer(gl.ARRAY_BUFFER, buffer)gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW)var a_attribute gl.getAttribLocation((gl as any).program, attribute)if (a_attribute 0) {console.log(Failed to get the storage location of attribute)return false}gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0)// 将缓冲区对象分配给 attribute 变量gl.enableVertexAttribArray(a_attribute)return true}const initVertexBuffers (gl: WebGLRenderingContext) {// 创建缓冲区对象const indexBuffer gl.createBuffer()if (!indexBuffer) {console.log(Failed to create the vertexColorBuffer object)return -1}// 将顶点坐标和颜色写入缓冲区if (!initArrayBuffer(gl, vertices, 3, gl.FLOAT, a_Position)) {return -1}if (!initArrayBuffer(gl, colors, 3, gl.FLOAT, a_Color)) {return -1}// 将顶点索引写入缓冲区对象gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)return indices.length}const draw (gl: WebGLRenderingContext, n: number, modelMatrix: any, u_ModelMatrix: any) {// 设置视点和视线u_ModelMatrix.setLookAt(g_eyeX, g_eyeY, g_eyeZ, 0, 0, -1, 0, 1, 0)gl.uniformMatrix4fv(modelMatrix, false, u_ModelMatrix.elements)// 清空颜色和深度缓冲区gl.clear(gl.COLOR_BUFFER_BIT)// 绘制立方体gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0)}const main () {if (!canvasDom.current) returnconst gl canvasDom.current.getContext(webgl)if (!gl) {console.log(Failed to get the rendering context for WebGL)return}gl.canvas.width (gl as any).canvas.clientWidthgl.canvas.height (gl as any).canvas.clientHeight// 初始化着色器if (!initShader(gl, VSHADERR_SOURCE, FSHADER_SOURCE)) {console.log(Failed to intialize shaders.)return}const n initVertexBuffers(gl)if (n 0) {console.log(Failed to set the vertex information)return}// 指定清空 canavs 的颜色gl.clearColor(0.0, 0.0, 0.0, 1.0)// 开启隐藏面消除gl.enable(gl.DEPTH_TEST)// 创建 Matrix4 对象以进行模型变换const u_ViewMatrix gl.getUniformLocation((gl as any).program, u_ViewMatrix)if (u_ViewMatrix u_ViewMatrix 0) {console.log(Failed to get the storage location of u_MvpMatrix)return}// 创建 Matrix4 对象以进行模型变换const viewMatrix new Matrix4()gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)// 清空颜色和深度缓冲区gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)if (!n || !u_ViewMatrix) returndocument.onkeydown (ev) {keydown(ev, gl, n, u_ViewMatrix, viewMatrix)}draw(gl, n, u_ViewMatrix, viewMatrix)}// 视点let g_eyeX 0.20,g_eyeY 0.25,g_eyeZ 1const keydown (ev: any, gl: WebGLRenderingContext, n: number, u_ViewMatrix: WebGLUniformLocation, viewMatrix: Matrix4) {// 按下右键if (ev.keyCode 39) {g_eyeX 0.01} else if (ev.keyCode 37) {// 按下左键g_eyeX - 0.01} else {return}draw(gl, n, u_ViewMatrix, viewMatrix)}useEffect(() {main()// eslint-disable-next-line react-hooks/exhaustive-deps}, [])return (canvas ref{canvasDom}/canvas) }export default LookAtF着色器部分 export const VSHADERR_SOURCE attribute vec4 a_Position;attribute vec4 a_Color;uniform mat4 u_ViewMatrix;varying vec4 v_Color;void main() {// 如果 gl_Position 最后一个分量为 1.0那么前三个分量就可以表示一个点的三维坐标。平移不改变缩放比例所以 u_Translation 第四个参数为 0.01.0 表示不缩放gl_Position u_ViewMatrix * a_Position;v_Color a_Color;} export const FSHADER_SOURCE #ifdef GL_ESprecision mediump float;#endifvarying vec4 v_Color;void main() {gl_FragColor v_Color;}我们会发现显示的物体在旋转过程中会发生一个角的缺失一部分。是因为我们没有指定可视范围也就是实际观察得到的区域边界。webgl 只显示可视范围内的区域这样可以降低程序的开销。webgl 通过定义水平视角、垂直视角和可视深度能够看多远来定义可视空间。 二、可视空间 有两类常用的可视空间 长方体可视空间也称盒状空间由正射投影产生。四棱锥/金字塔可视空间由透视投影产生。 所以对应投影方式有两种一种是正交投影一种透视投影。 正交投影投影到近平面上相同尺寸大小的图形大小相同不会有真实世界那种近大远小的感觉。 透视投影同样尺寸的物体近处的物体投影出来大远处的物体投影出小会产生与真实世界一样近大远小的感觉。 在乘以投影矩阵后任何一个点的坐标 [x,y,z,w] 中的下x,y,z的分量将在 -w~w 内。 透视投影分两步 从 Frustun 内一点投影到近裁剪平面的过程由近平面到规范化设备坐标系的过程 首先将视体内的点投影到近裁剪平面然后将近裁剪平面上的点规范化到设备坐标系。 其实 gl_Position 的第四个参数也就是缩放系数。 1. 正射投影 下面是正射投影的盒状可视空间的工作原理 正射投影 盒状可视空间的形状如上图可视空间由前后两个矩形表面确定分别称为近裁剪面和远裁剪面。canvas 上显示的就是可视空间中物体在近裁剪面上的投影。如果剪裁面的宽高比跟 canvas 不一样那么画面就会被按照 canvas 的宽高比进行压缩物体会被扭曲。近裁剪面与远裁剪面之间的盒状空间就是可视空间只有在此空间内的物体会被显示出来。 这也就是为什么上面我们通过键盘移动立方体有的会被隐藏。 有关在线的例子可以看这里的运行的效果 https://webglfundamentals.org/webgl/webgl-visualize-camera-with-orthographic.html 正交投影本质 他其实就是我们规定的一个盒状的可视空间然后需要将这个盒装的可视空间进行变化压缩到一个规范化的裁剪空间中也就是正交投影矩阵的视锥体是一个长方体 [l,r][b,t][f,n]我们要把这个长方体转换到一个正方体[-1,1][-1,1][-1,1]中 首先第一步需要计算这个长方体的中心点然后将这个中心点移动到坐标轴的原点。长方体的中心点很容易计算[(lr)/2,(bt)/2,(fn)/2] 所以得到此步骤需要变换的矩阵 接下来第二步就是需要对长方体进行缩放例如从[l,r]缩放到[-1,1]缩放系数为2/(r-l)所以得到缩放矩阵为: 所以正交矩阵 缩放矩阵 * 平移矩阵 正交投影的推导过程 封装对应代码如下 export const orthographic (left: number, right: number, bottom: number, top: number, near: number, far: number) {return [2 / (right - left), 0, 0, 0,0, 2 / (top - bottom), 0, 0,0, 0, 2 / (near - far), 0,(left right) / (left - right),(bottom top) / (bottom - top),(near far) / (near - far),1,] }2. 透视投影 透视一种绘制物体的空间位置关系的绘图技术透视投影的观察体 具有近大远小的特性。 透视投影更接近我们的世界就是近大远小而正射投影的好处是用户可以方便地比较场景中的物体的大小因为物体看上去的大小与其所在的位置没有关系。 透视投影矩阵本质 他其实就是将上面的锥形盒子进行压缩到规范化盒子在这个过程中我们需要把握以下三个原则 近平面的所有点坐标不变也就是 (x, y, n, 1) 经过变换后仍然是他本身远平面的所有点坐标 z 值不变 都是 f远平面的中心点坐标值不变 为 (0,0,f)可以将这个点带入方程组计算关系式 相似三角形Y’ n / z * Y 所以首先需要计算出将锥形进行缩放变换到正交投影的长方体然后执行上面推导正交投影矩阵的步骤也就是说 透视投影矩阵 正交投影矩阵 * 变换矩阵 对于透视投影矩阵的推导其实我们可以找到相似三角形得到不同比例 考虑用双曲线描述 z 方向的剪裁坐标值 封装对应代码 export const perspective (fov: number, aspect: number, zNear: number, zFar: number) {const f 1 / Math.tan(fov * 0.5)const inv 1 / (zNear - zFar)const m [f / aspect, 0, 0, 0,0, f, 0, 0,0, 0, (zNear zFar) * inv, -1,0, 0, 2 * zNear * zFar * inv, 0]return m }3. 隐藏面设置 在现实世界中如果我们眼睛看到的物体有前后关系那么后面的物体遮住的话会看不到。所以这部分可以不进行绘制。在默认情况下webgl 为了加速绘图操作是按照顶点在缓冲区中的顺序来处理他们的所以都会进行绘制而且后绘制的图形覆盖先绘制的图形。 WebGL 中的三角形有正反面的概念正面三角形的顶点顺序是逆时针方向 反面三角形是顺时针方向。 对于WebGL而言一个三角形是顺时针还是逆时针是根据裁剪空间中的顶点顺序判断的 换句话说WebGL是根据你在顶点着色器中运算后提供的结果来判定的 这就意味着如果你把一个顺时针的三角形沿 X 轴缩放 -1 它将会变成逆时针 或者将顺时针的三角形旋转180度后变成逆时针。由于我们没有开启 CULL_FACE 所以可以同时看到顺时针正面和逆时针反面三角形。现在开启了 任何时候正面三角形无论是缩放还是旋转的原因导致翻转了WebGL就不会绘制它。 这件事很有用因为通常情况下你只需要看到你正面对的面。 WebGL可以只绘制正面或反面三角形可以这样开启 // 隐藏面消除gl.enable(gl.CULL_FACE);这个功能会帮助我们消除那些被遮挡的表面。 对应的如果开启了隐藏面消除我们需要在绘制之前清除深度缓冲区 gl.clear(gl.DEPTH_BUFFER_BIT)gl.enable(cap)方法的使用,可以去查看MDN接口文档介绍 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/enable 对于为什么需要清空深度缓冲区。是因为深度缓冲区是一个隐藏对象其作用就是帮助webgl进行隐藏面消除webgl在颜色缓冲区中绘制几何图形绘制完成之后将颜色缓冲区显示到canvas上要将隐藏面消除就必须知道几何图形的深度信息而深度缓冲区就是用来存储深度信息的由于深度方向通常是z轴方向所以有时候也曾为z缓冲区 在绘制每一帧之前都必须清除深度缓冲区以消除绘制上一帧时在其中留下的痕迹 当然还需要清除颜色缓冲区因此可以这样写 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);至此投影系列算是讲完了。
http://www.hyszgw.com/news/91417.html

相关文章:

  • 湖北专业网站建设市面价国外vps私人
  • 网站所有权 备案人力资源公司加盟合作
  • 深圳建设项目环保网站办事指南lofter wordpress
  • 新建网站百度搜不到多平台网站建设
  • 企业网站模板html下载国际外贸网站推广
  • 宝安龙华积分商城网站建设什么是seo如何进行seo
  • 对电子商务网站建设的认识大气简洁网站
  • 欧米伽男士手表官方网站怎么生成网页链接
  • 大学科研项目做网站网站上线要多久
  • 营销型单页面网站网站开发需要什么资质
  • 做外汇可以参考的网站flashfxp上传多个网站
  • 靖江网站建设开发商和物业的关系
  • 医院网站建设台账很那网站建设
  • 如何在百度做网站推广做网站手机端需要pc端的源代码吗
  • 新手怎么建立网站工商网站查询个人信息
  • 广州做外贸网站建设博士后是否可以做网站负责人
  • 网站镜像 动态公司网站开发费用放在什么科目
  • 毕业生对于网站建设感受wordpress dux 下载
  • 企业建设网站的主要目的有哪些布吉网站建设哪家服务周到
  • flash网站模板源码wordpress后台添加主题设置
  • 做后期哪个网站素材好专业构建网站的公司
  • 内容管理网站建设方案wordpress 页面nofollow
  • 福建建设工程交易中心网站wordpress模板不显示文章页
  • 网页制作网站厦门网站建设680元
  • 网站建设与管理书长沙第三方网站建设公司
  • 做网站和APP需要多少钱网络规划设计师报考
  • 网站建设与管理就业前景怎么做网站注册推广
  • 淮安网站建设淮安网站制作什么网站可以做兼职
  • 做一款网站注意啥wordpress网站换空间
  • 手机网站建设哪家专业什么是大型门户网站