<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      碼農(nóng)干貨系列【9】--javascript光線追蹤基礎(chǔ)

      2013-03-12 16:31  【當(dāng)耐特】  閱讀(3716)  評(píng)論(4)    收藏  舉報(bào)

      簡(jiǎn)介

      光線追蹤(ray tracing)(也叫raytracing或者光束投射法)是一個(gè)在二維(2D)屏幕上呈現(xiàn)三維(3D)圖像的方法。為了嘗試光線追蹤算法,并且盡可能得保證javascript代碼精煉,我做了一些嘗試。

      射線與球體相交檢測(cè)

      最開(kāi)始嘗試了射線與球體的相交檢測(cè)(不計(jì)算交點(diǎn)),只判斷相交還是未相交。代碼如下所示:

      var Vector3 = function (x, y, z) { this.x = x; this.y = y; this.z = z; };
      Vector3.prototype ={
          dot: function (v) { return this.x * v.x + this.y * v.y + this.z * v.z; },
          sub: function (v) { return new Vector3(this.x - v.x, this.y - v.y, this.z - v.z); },
          normalize: function () {      return this.divideScalar(this.length());  },
          divideScalar: function (s) {  return new Vector3(this.x/s, this.y/s, this.z/s);   },
          length: function () {     return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);  },
          sqrDistanceToline:function(a,b){
              var ab = b.sub(a), ac = this.sub(a), bc = this.sub(b);
              var e = ac.dot(ab.normalize());
              var f = ac.length();
              return f * f - e * e;
          }
      } 

      其中sqrDistanceToline為計(jì)算點(diǎn)到直線之間的距離的平方(開(kāi)跟號(hào)性能損耗大)。使用如下:

      ball.p.sqrDistanceToline(v, camera.p) < sqrBallR

      其中v是屏幕上的點(diǎn)的坐標(biāo),camera.p為視點(diǎn)的坐標(biāo),ball.p為球體中心坐標(biāo),sqrBallR為球體半徑的平方。當(dāng)上面返回true時(shí),判定為相交;反之亦然。

      相交測(cè)試

      for (var y = 0; y < canvas.height; y++) {
          for (var x = 0; x < canvas.width; x++) {
              var v = new Vector3(-canvas.width / 2 + x, canvas.height - y, 0);
              var cv = new Vector3(camera.p.y * v.x / (camera.p.y - v.y), 0, camera.p.z * v.y / (v.y - camera.p.y));
                 
              if (cv.z > -planeLength && cv.z < 0) {
                  if (ball.p.sqrDistanceToline(v, camera.p) < sqrBallR) {
                      pixels[i] = pixels[i + 1] = pixels[i + 2] = 111;
                  } else {
                      pixels[i] = pixels[i + 1] = pixels[i + 2] = (Math.ceil(cv.x / sideLength) + Math.ceil(cv.z / sideLength)) % 2 === 0 ? 148 : 0;
                  }
                  pixels[i + 3] = 255 * (planeLength - Math.abs(cv.z)) / planeLength;
              }
              i += 4;
          }
      }

      由于沒(méi)有獲取交點(diǎn)坐標(biāo),無(wú)法計(jì)算視點(diǎn)到球體上點(diǎn)的距離,所以無(wú)法進(jìn)行球體深度渲染。所以得到了以下的圖像:

      image

      獲取交點(diǎn)

      所以現(xiàn)在目的很明確,不僅要判定相交不相交,還需要找到交點(diǎn)的坐標(biāo)。當(dāng)然,上面的方法不是一無(wú)是處,可以進(jìn)行一些初步坐標(biāo)的篩選(如果性能好于找交點(diǎn)計(jì)算一個(gè)數(shù)量級(jí)的話,這個(gè)待測(cè)試)。那么怎么獲取射線與球體的交點(diǎn)呢?該點(diǎn)要滿足以下兩個(gè)條件:

      1.交點(diǎn)在在光線上
      x=S+dt

      2.交點(diǎn)在球上
      |x-C|=r

      C 表示球心,r 表示半徑,光線起點(diǎn)是 S,方向是 d(單位向量),交點(diǎn) x。

      所以得到:8140727a73c4b1e91b3ec987e4d780e0

      簡(jiǎn)化 dfd1908c7d8603bab746c9e5a487fb06

      那么a27ce21daa6b36c14bc25f8646d44e79

      所以a44286afce8014729e85436a846749fd

      最后得到:039de90713792a92c20398f4a059962a

      所有小球的代碼如下所示:

      var Ball = function (p, r) {
          this.p = p;
          this.r = r;
          this.sqrR = this.r * this.r;
      }
      Ball.prototype = {
          intersect: function (p1, p2) {
              var v = p1.sub(this.p);
              var a0 = v.sqrLength() - this.sqrR;
              var np = p2.sub(p1).normalize();
              var dotV = np.dot(v);
              if (dotV <= 0) {
                  var discr = dotV * dotV - a0;
                  if (discr >= 0) {
                      return p1.add(np.multiplyScalar(-dotV - Math.sqrt(discr)));
                  }
              }
              return null;
          }
      }

      拿到了交點(diǎn)坐標(biāo),現(xiàn)在可以做深度渲染:

      var result = ball.intersect(camera.p, screenP);
      if (result) {
          (pixels[i] = pixels[i + 1] = pixels[i + 2] = ((result.z - ball.p.z) / ball.r) * 255)
          pixels[i + 3] = 255;
      }

      在線演示

      請(qǐng)使用現(xiàn)代瀏覽器,你的瀏覽器過(guò)時(shí)了!

      修改里面的參數(shù)試一試!

      參考文獻(xiàn)

      用JavaScript玩轉(zhuǎn)計(jì)算機(jī)圖形學(xué)(一)光線追蹤入門

      光線跟蹤 - 維基百科,自由的百科全書(shū)

       

      Have Fun!

      主站蜘蛛池模板: 免费国产一区二区不卡| 国产色视频网站免费| 欧美一本大道香蕉综合视频| 国产精品任我爽爆在线播放6080| 色一乱一伦一图一区二区精品| 仁布县| 久久久久亚洲AV色欲av| 国产亚洲国产精品二区| 中国亚洲女人69内射少妇| 亚洲区一区二区激情文学| 国产精品中文字幕视频| 四虎成人精品无码永久在线| 欧洲亚洲色一区二区色99| 亚洲综合无码明星蕉在线视频| 芦溪县| 国产欧美日韩精品第二区| 日韩人妻无码精品久久| 亚洲av日韩在线资源| 老熟妇老熟女老女人天堂| 国产一区二区视频啪啪视频 | 国内自拍视频一区二区三区| 久久午夜无码鲁丝片午夜精品| 无码三级av电影在线观看| 欧美精品一区二区在线观看播放| 成人网站免费观看永久视频下载| 久久综合综合久久高清免费| 国产精品一区在线蜜臀| 最近免费中文字幕大全免费版视频| 亚洲国产成人久久精品不卡| 国产啪视频免费观看视频| 国产精品第一页一区二区| 最新精品露脸国产在线| 国产h视频在线观看| 人妻少妇偷人一区二区| 18岁日韩内射颜射午夜久久成人| 亚洲一区二区三区人妻天堂| 蜜桃在线一区二区三区| 欧美色欧美亚洲高清在线视频 | 国内少妇偷人精品免费| 国产精品人妻一区二区高| 亚洲熟女一区二区av|