WebGL鐨勪笘鐣岋紒骞朵笖涓嶄細娑夊強D3/ThreeJS绛?WebGL搴擄紝灏辩敤鍘熺敓鐨?codeclass="mq-7">WebGLAPI缁樺埗涓€涓偣锛?/p>馃搾鍓嶈█棣栧厛锛?codeclass="mq-11">WebGL骞朵笉鏄竴闂ㄨ瑷€锛屽"/>

浣犺窛绂?WebGL 鍙樊涓€鐐癸紒

Posted freeCodeCamp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浣犺窛绂?WebGL 鍙樊涓€鐐癸紒相关的知识,希望对你有一定的参考价值。

浣犺窛绂讳簡瑙?WebGL 鍙樊涓€鐐癸細

杩欐锛屾垜浼氶€氳繃缁樺埗涓€涓偣锛屽甫棰嗗ぇ瀹惰蛋杩?code class="mq-5">WebGL鐨勪笘鐣岋紒骞朵笖涓嶄細娑夊強 D3 / ThreeJS 绛?WebGL 搴擄紝灏辩敤鍘熺敓鐨?code class="mq-7">WebGL API缁樺埗涓€涓偣锛?/p>

馃搾鍓嶈█

棣栧厛锛?code class="mq-11">WebGL骞朵笉鏄竴闂ㄨ瑷€锛屽畠鏄竴涓爣鍑嗭紝瀹冩槸鍦?code class="mq-12">OpenGL ES鐨勫熀纭€涓婃墍寤虹珛鐨勪竴濂楅€傜敤浜庢祻瑙堝櫒鐨勫浘褰㈠鏍囧噯锛涜€?code class="mq-13">OpenGL ES鍒欐槸OpenGL鐨勪竴涓壒娈婄増鏈紙濂楀▋璀﹀憡馃憖锛夛紝ES鐗堟湰琚箍娉涚殑搴旂敤浜庢墜鏈恒€佸鐢ㄦ父鎴忔満绛夎澶囥€傛兂浜嗚В鏇村鍏充簬WebGL鏍囧噯鍐呭鐨勫皬浼欎即鍙互杩涘叆Khronos Group鐨勭綉绔欒嚜琛屾祻瑙堛€?/p>

WebGL鐨勫紑鍙戜笌鎴戜滑鏅€氱殑鍓嶇寮€鍙戝苟娌℃湁浠€涔堝お澶у樊寮傦紝涓€涓祻瑙堝櫒鐨勭綉椤典竴鑸槸鐢憋細HTML銆?JavaScript銆佹覆鏌撳紩鎿庣瓑閮ㄥ垎缁勬垚锛屽鏋滄垜浠寮€鍙?code class="mq-19">WebGL鐨勮瘽锛岃繕闇€瑕佷粈涔堝憿锛熻鎴戜滑鏉ユ€濊€冧竴涓嬶紝鎴戜滑鍦ㄩ珮涓涔犲嚑浣曠殑鏃跺€欒€佸笀璁茶繃鈥滅偣鍔ㄦ垚绾匡紝绾垮姩鎴愰潰锛岄潰鍔ㄦ垚浣撯€濓紝閭f垜浠氨浠ユ渶鍩虹鐨?span class="mq-20">鐐?/strong>涓轰緥锛岄鍏?span class="mq-21">鐐?/strong>鏈変粈涔堝睘鎬т箞锛?span>鐐圭殑浣嶇疆銆佺偣鐨勯鑹层€佺偣鐨勫ぇ灏?/strong>锛屾垜浠浣曞畾涔変竴涓?span class="mq-22">鐐?/strong>鐨勮繖浜涘睘鎬у憿锛熻繖灏辫寮曞叆GLSL ES(OpenGL Shader Language ES)锛堝悗绉扮潃鑹插櫒锛変簡锛岀潃鑹插櫒鐨勫啓娉曚笌C璇█璇硶鏈変簺鐩镐技锛屼粠鍚嶅瓧涔熻兘鐪嬪嚭WebGL涓?code class="mq-25">OpenGL ES鏄湁鈥滆缂樺叧绯烩€濈殑锛佸叾娆★紝鎴戜滑杩橀渶瑕佺殑灏辨槸娴忚鍣ㄥ巶鍟嗗熀浜?code class="mq-26">WebGL鏍囧噯鎻愪緵鐨?code class="mq-27">API銆?/p>

WebGL骞朵笉鍍?code class="mq-30">OpenGL涓€鏍锋湁绻佺悙鐨勭幆澧冮厤缃殑娴佺▼锛屼篃娌℃湁瀵圭郴缁熺殑瑕佹眰锛屽彧瑕佹湁涓€涓敮鎸?code class="mq-31">WebGL鐨勬祻瑙堝櫒鍗冲彲锛?/p>

鏈鎴戜滑浣跨敤瀛楃涓茬殑褰㈠紡缂栧啓鐫€鑹插櫒锛屾殏鏃朵笉鏂板缓鍗曠嫭鐨勭潃鑹插櫒鏂囦欢:)

馃審缁欒繖涓€滅偣鈥濅竴鐐硅嚜鐢辩殑绌洪棿

涓轰簡浣跨敤娴忚鍣ㄦ彁渚涚殑WebGL鎺ュ彛锛屾垜浠渶瑕佷娇鐢?code class="mq-38"><canvas>鏉ヨ幏鍙?code class="mq-39">WebGL涓婁笅鏂囷細

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Point</title>
</head>
<body onload="main()" style="padding: 0; margin: 0;">
  <canvas id="webgl" width="600" height="400">
    鎮ㄤ娇鐢ㄧ殑娴忚鍣ㄤ笉鏀寔 WebGL锛?br>  </canvas>
  <script>
      function main({
      // get canvas element
          const canvas = document.getElementById("webgl");
      const gl = canvas.getContext('webgl');
    }
  
</script>
</body>
</html>

gl灏辨槸鎴戜滑鎵€鑾峰彇鍒扮殑WebGL娓叉煋鐨勪笂涓嬫枃馃ぉ璁╂垜浠粰鐢诲竷濉厖涓儗鏅壊鍚э細

<!DOCTYPE html>
<html lang="en">
    <!-- ... -->
  <script>
      function main({
      // ...
      const gl = canvas.getContext('webgl');

      gl.clearColor(0.00.00.01.0);
      gl.clear(gl.COLOR_BUFFER_BIT);
    }
  
</script>
    <!-- ... -->
</html>

杩欐牱鎴戜滑瑕佺粯鍒剁偣鐨勭敾甯冨氨鎷ユ湁浜嗘旦鐎氬畤瀹欎竴鑸繁閭冪殑榛戣壊:)鍠濈偣搴嗙涓€涓嬸煃?/span>

浣犺窛绂?WebGL 鍙樊涓€鐐癸紒

瑙i噴涓€涓?code class="mq-129">gl.clearColor鏂规硶鏄缃竻闄ょ敾甯冪殑鑳屾櫙鑹诧紝褰㈠紡鏄?code class="mq-130">RGBA锛?code class="mq-131">gl.clear鍒欐槸璋冪敤娓呴櫎鐢诲竷鐨勬柟娉曪紝鍙紶閫掔殑鍙傛暟gl.COLOR_BUFFER_BIT鏄釜浠€涔堝憿馃鍏跺疄璇ユ柟娉曠户鎵胯嚜OpenGL锛?code class="mq-134">OpenGL鏄熀浜庡缂撳啿鍖烘ā鍨嬬殑锛屾竻绌虹粯鍥惧尯鍩熷疄闄呬笂鏄湪娓呯┖棰滆壊缂撳啿鍖猴紝浼犻€掑弬鏁?code class="mq-135">gl.COLOR_BUFFER_BIT鏄湪鍛婅瘔WebGL娓呯┖棰滆壊缂撳啿鍖猴紱闄ゆ涔嬪杩樻湁娣卞害缂撳啿鍖轰互鍙婃ā鏉跨紦鍐插尯锛屽彲鏌ョ湅姝や簡瑙c€?br>

馃惖璁╄窛绂昏繎涓€鈥滅偣鈥?/span>

涓嬮潰鎴戜滑寮€濮嬬粯鍒?span class="mq-140">鐐?/strong>馃コ鍦ㄥ墠闈㈡垜浠垎鏋愰亾涓€涓偣鏈?span class="mq-141">浣嶇疆銆侀鑹插強澶у皬涓変釜灞炴€э紝涓嬮潰鎴戜滑灏嗙紪鍐欑潃鑹插櫒缁欐繁閭冪殑鐢诲竷澧炴坊涓€鐐硅壊褰煂?/p>

<!DOCTYPE html>
<html lang="en">
    <!-- ... -->
  <script>
      function main({
      // ...
      const VertexShader = `
        void main() {
          gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
          gl_PointSize = 10.0;
        }
      `
;
      const FragmentShader = `
        void main() {
          gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
        }
      `
;
    }
  
</script>
    <!-- ... -->
</html>

涓婇潰鎴戜滑瀹氫箟浜?code class="mq-168">VertexShader鍜?code class="mq-169">FragmentShader锛屽湪WebGL涓湁涓ょ鐫€鑹插櫒鍒嗗埆鏄細椤剁偣鐫€鑹插櫒鍜岀墖鍏冪潃鑹插櫒锛?/p>

  • 椤剁偣鐫€鑹插櫒锛氱敤鏉ユ弿杩伴《鐐圭殑鐗规€х殑绋嬪簭锛屾瘮濡備綅缃€佸ぇ灏忕瓑銆傞《鐐规槸鎸囦簩缁存垨涓夌淮绌洪棿涓殑涓€涓偣锛屾瘮濡備簩缁村浘褰㈡垨涓夌淮鍥惧舰鐨勯《鐐规垨浜ょ偣锛?/span>

  • 鐗囧厓鐫€鑹插櫒锛氫篃绉板儚绱犵潃鑹插櫒锛岃繘琛岄€愮墖鐨勫鐞嗚繃绋嬫瘮濡傚厜鐓с€傜墖鍏冨彲浠ョ悊瑙d负鍍忕礌銆?/span>

鍚屾椂锛屾瘡涓潃鑹插櫒閮芥湁涓€涓?code class="mq-177">main()鏂规硶锛屽苟涓旇鏂规硶涓嶈兘鎸囧畾鍙傛暟锛屾瘡琛岃鍙ョ粨鏉熶箣鍚庡繀椤绘湁鍒嗗彿锛侊紒锛?code class="mq-179">gl_Position銆?code class="mq-180">gl_PointSize鍜?code class="mq-181">gl_FragColor涓変釜鍙橀噺鍒欐槸鐫€鑹插櫒鍐呯疆鐨勫彉閲忥紝鍏朵腑gl_PointSize鍙互涓嶈祴鍊硷紝榛樿鍊间负1.0銆傚悇浣嶆敞鎰忓埌锛屼笂闈㈣祴鍊艰鍙ヤ腑鎴戜滑缁欑殑鍊兼槸0.0鑰屼笉鏄?code class="mq-185">0锛岃繖鏄洜涓鸿繖浜涘唴缃彉閲忔槸鏈夊叾鍙橀噺绫诲瀷鐨勶細

鍙橀噺鍚?/th> 绫诲瀷 鎻忚堪
gl_Position vec4 椤剁偣浣嶇疆
gl_PointSize float 鐐圭殑澶у皬
gl_FragColor vec4 鐗囧厓棰滆壊

闂細鏄庢槑涓€涓偣鐨勫潗鏍囧彧鏈?code class="mq-205">(x, y, z)锛屼负浠€涔堣浼?涓€煎憿锛?br>

绛旓細杩欓噷浣跨敤鐨勬槸榻愭鍧愭爣鐨勫舰寮忥紝浜嗚В榻愭鍧愭爣鍙煡鐪嬫垜涓婄瘒鏂囩珷銆?/p>

闂細浣跨敤涓婇潰瀹氫箟鐨勯《鐐圭潃鑹插櫒鍜岀墖鍏冪潃鑹插櫒鍒嗗嚑姝ュ憿锛?/p>

绛旓細鍒嗕笁姝ワ紒绗竴姝ワ紝鍒涘缓鐫€鑹插櫒锛涚浜屾锛屽垱寤虹潃鑹插櫒绋嬪簭锛涚涓夋锛屽湪WebGL涓婁笅鏂囦腑浣跨敤鐫€鑹插櫒绋嬪簭銆?/p>

1锔忊儯鍒涘缓鐫€鑹插櫒

涓轰簡鏂逛究浣跨敤鎴戞妸鍒涘缓鐫€鑹插櫒鐨勬楠ゆ娊鍙栦簡涓€涓?code class="mq-213">createShader()鏂规硶锛?/p>

function createShader (gl, type, source{
  const shader = gl.createShader(type);
  if (shader == null) {
    console.warn('鏃犳硶鍒涘缓鐫€鑹插櫒');
    return null;
  }

  gl.shaderSource(shader, source);
  gl.compileShader(shader);

  const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  if (!compiled) {
    console.log('缂栬瘧鐫€鑹插櫒澶辫触锛?nbsp;' + gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  }

  return shader;
}

gl.shaderSource鏄皢gl.createShader鍒涘缓鐨勭潃鑹插櫒鐨?code class="mq-237">source璁剧疆涓烘垜浠畾涔夌殑VertextShader鎴?code class="mq-239">FragmentShader锛屽墿涓嬬殑灏变笉瑙i噴浜嗭紝鍑芥暟鍚嶉兘寰堣〃鎰?)

2锔忊儯鍒涘缓鐫€鑹插櫒绋嬪簭

涔熶负浜嗘洿绠€娲侊紝鍒涘缓鐫€鑹插櫒绋嬪簭鐨勬楠や篃鎶芥垚浜?code class="mq-243">createProgram()鏂规硶锛?/p>

function createProgram (gl, vshader, fshader{
  const vertexShader = createShader(gl, gl.VERTEX_SHADER, vshader);
  const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fshader);
  if (!vertexShader || !fragmentShader) {
    return null;
  }

  const program = gl.createProgram();
  if (!program) {
    return null;
  }

  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);

  gl.linkProgram(program);

  const linked = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (!linked) {
    console.warn('Link 鐫€鑹插櫒绋嬪簭澶辫触锛?nbsp;' + gl.getProgramInfoLog(program));
    gl.deleteProgram(program);
    gl.deleteShader(fragmentShader);
    gl.deleteShader(vertexShader);
    return null;
  }
  return program;
}

gl.attachShader鏄皢鍒涘缓濂界殑鐫€鑹插櫒attach鍒版垜浠潃鑹插櫒绋嬪簭涓婏紝鐒跺悗璋冪敤gl.linkProgram鏂规硶灏?code class="mq-270">program鏁村悎璧锋潵銆?/p>

3锔忊儯鍦ㄤ笂涓嬫枃涓娇鐢ㄧ潃鑹插櫒绋嬪簭

function initShaders(gl, vshader, fshader{
  const program = createProgram(gl, vshader, fshader);
  if (!program) {
    console.warn('鍒涘缓鐫€鑹插櫒绋嬪簭澶辫触锛?);
    return false;
  }

  gl.useProgram(program);
  gl.program = program;

  return true;
}

杩欓噷灏卞緢绠€鍗曞暒锛屽氨涓嶅仛杩囧浠嬬粛浜嗭紒鐒跺悗鍦?code class="mq-288">main()涓皟鐢ㄦ鏂规硶鍒濆鍖栫潃鑹插櫒锛?/p>

<!DOCTYPE html>
<html lang="en">
    <!-- ... -->
  <script>
      function main({
      const canvas = document.getElementById('webgl');
      const gl = canvas.getContext('webgl');

      if (!initShaders(gl, VertexShader, FragmentShader)) {
        return alert('鍒濆鍖栫潃鑹插櫒澶辫触');
      }

      gl.clearColor(0.00.00.01.0);
      gl.clear(gl.COLOR_BUFFER_BIT);
      gl.drawArrays(gl.POINTS, 01);
    }
    // createShader
    // createProgram
    // initShaders
  
</script>
    <!-- ... -->
</html>

gl.drawArrays鐨勭涓€涓弬鏁版槸鎸囧畾缁樺埗鏂瑰紡锛岀浜屼釜鍙傛暟鏄粠鍝釜椤剁偣寮€濮嬬粯鍒讹紝绗笁涓弬鏁版槸鎸囧畾缁樺埗瑕佺敤鍒板灏戜釜椤剁偣銆傝繖鏍锋垜浠氨鑳藉湪榛戣壊鐨勭敾甯冧笂鐨勬涓績鐪嬪埌涓€涓摑鑹茬殑鐐癸細

浣犺窛绂?WebGL 鍙樊涓€鐐癸紒

浣嗘槸锛屽皬鏈嬪弸浣犳槸鍚︽湁寰堝鐨勯棶鍙凤紵

浣犺窛绂?WebGL 鍙樊涓€鐐癸紒

鏄庢槑瀹氫箟鐨勭偣鐨勪綅缃湪(0, 0, 0)锛屼负浠€涔堢偣浼氬嚭鐜板湪<canvas>鐨勬涓ぎ鍛紵WebGL鐩稿浜?code class="mq-337"><canvas>鐨勪綅缃涓嬪浘锛?/p>

浣犺窛绂?WebGL 鍙樊涓€鐐癸紒

涓棿鐨勬槸WebGL鐩稿浜?code class="mq-342"><canvas>鐨勫潗鏍囷紝鑰?code class="mq-343">canvas鐨勫潗鏍囧垯鏄浉瀵逛簬灞忓箷鐨勶紒WebGL鐩稿浜?code class="mq-345"><canvas>鐨勫潗鏍囧苟涓嶆槸缁濆鐨勫儚绱犲€硷紝鑰屾槸鐩稿鐨?code class="mq-346">[-1.0, 1.0]銆傪煂颁妇涓緥瀛愶細鎴戜滑灞曠ず鐨勭偣鍦?code class="mq-347">canvas鐨勬涓ぎ锛屽鏋滄垜浠妸鐐圭殑鍧愭爣璁剧疆涓?code class="mq-348">(1.0, 0.0, 0.0, 1.0)锛岄偅涔堢偣灏变細鍑虹幇鍦?code class="mq-349">canvas鐨勬渶鍙充晶锛屽悓鐞嗚缃负(-1.0, 1.0, 0.0, 1.0)锛岀偣鍒欏睍绀哄湪canvas鐨勫乏涓婅:P

馃暪娓叉煋杩欎釜鐐圭粡鍘嗕簡浠€涔堬紵

馃え灏辫繖涔堢粨鏉熶簡锛?/span>

鎬庝箞鍙兘灏辫繖涔堢粨鏉燂紒璁╂垜浠粰缁樺埗鐐?/strong>鐨勭▼搴忓崌绾т竴涓嬶紝鐜板湪鎴戜滑鐨勪綅缃€佸ぇ灏忛兘鏄湪鐫€鑹插櫒涓畾涔夊ソ鐨勩€傚綋鐒?code class="mq-359">WebGL涔熶负鎴戜滑鎻愪緵浜嗘柟娉曡鎴戜滑鍙互浠庡閮ㄤ紶鍏ョ浉搴斿弬鏁板€笺€傝鎴戜滑瀵圭潃鑹插櫒鏀归€犱竴涓嬶細

const VertexShader = `
  attribute vec4 a_Position;
  void main() {
    gl_Position = a_Position;
    gl_PointSize = 10.0;
  }
`
;

attribute鏄竴绉?code class="mq-366">GLSL SE鍙橀噺锛岃鐢ㄦ潵浠庡閮ㄥ悜椤剁偣鐫€鑹插櫒鍐呬紶鏁版嵁锛?span class="mq-367">鍙湁椤剁偣鐫€鑹插櫒鍙互浣跨敤锛涘悓鏃惰繕鏈変竴绉嶅彉閲忕被鍨?code class="mq-368">uniform锛?code class="mq-369">uniform鍙橀噺浼犺緭鐨勬槸瀵逛簬鎵€鏈夐《鐐归兘鐩稿悓锛堟垨涓庨《鐐规棤鍏筹級鐨勬暟鎹€備笂闈㈡槸鐫€鑹插櫒浠g爜涓紝鎴戜滑灏嗕粠澶栭儴鑾峰彇鍒扮殑a_Position鍜?code class="mq-371">a_PointSize鍒嗗埆璧嬪€肩粰gl_Position鍜?code class="mq-373">gl_PointSize銆傛€庝箞閫氳繃JavaScript鍚戠潃鑹插櫒鐨?code class="mq-374">attribute鍙橀噺浼犲€煎憿锛?/p>

function main ({
  // ...
  if (!initShaders(gl, VertexShader, FragmentShader)) {
    return alert('鍒濆鍖栫潃鑹插櫒澶辫触');
  }

  const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  gl.vertexAttrib3f(a_Position, 1.00.00.0);
  // ...
}

浣跨敤vertextAttrib3f鏂规硶灏卞彲浠ュ皢浣跨敤getAttribLocation鑾峰彇鍒扮殑attribute鍙橀噺璧嬪€硷紝vertexAttrib3f鏂规硶浼氬皢榻愭鍧愭爣鐨勬渶鍚庝竴涓€奸粯璁よ祴鍊间负1.0锛屽綋鐒朵娇鐢?code class="mq-397">vertexAttrib4f涔熸槸鍙互鐨?)

馃ぉ鍐嶅姞鐐瑰姛鑳?/span>

褰撴垜鍦?code class="mq-401">canvas涓婄偣鍑荤殑鏃跺€欙紝灏卞湪鐐瑰嚮canvas鐨勫湴鏂瑰睍绀轰竴涓偣锛岃繖灏遍渶瑕佹垜浠粰canvas缁戝畾鏂规硶浜嗭細

canvas.onmousedown = function (e{
  click(e, gl, canvas, a_Position);
};

鍦ㄦ灏变笉缁欒缁嗕唬鐮佷簡锛?code class="mq-410">canvas缁戝畾浜嬩欢鏂瑰紡濡備笂锛屽苟绠€鍗曡涓€涓嬫€濊矾锛氬綋鐐瑰嚮涔嬪悗鑾峰彇榧犳爣鍦?code class="mq-411">canvas鐐瑰嚮鐨勫潗鏍囧€硷紱鐒跺悗灏嗗潗鏍囪浆鎹负WebGL鐩稿浜?code class="mq-413">canvas鐨?code class="mq-414">[-1.0, 1.0]褰㈠紡鐨勫潗鏍囷紱鐒跺悗娓呯┖鐢诲竷锛屽湪閲嶆柊缁樺埗鐐广€傚潗鏍囪浆鎹㈢殑浠g爜濡備笅锛?/p>

let x = e.clientX;
let y = e.clientY;
const rect = e.target.getBoundingClientRect();

x = (x - rect.left - canvas.width / 2) / (canvas.width / 2);
y = (canvas.height / 2 - y + rect.top) / (canvas.height / 2);

姣斿杩樿兘鍐嶇粰姣忎釜鐐硅缃笉鍚岀殑棰滆壊锛?span class="mq-425">鎻愮ず锛氫娇鐢?uniform 鍙橀噺銆?/strong>

馃缁撴潫璇?/span>

浣跨敤鍘熺敓WebGL缁樺埗涓€涓€滅畝鍗曠殑鐐光€濆氨璁插埌杩欓噷鍟?)鎴戣嚜宸变篃鍦ㄤ笉鏂殑瀛︿範涓紝鍚庣画浼氬嚭鏇村鍏充簬WebGL鐨勬枃绔狆煒?/p>

闈炶惀鍒╃粍缁?/span> freeCodeCamp.org 鑷?2014 骞存垚绔嬩互鏉ワ紝浠モ€滃府鍔╀汉浠厤璐瑰涔犵紪绋嬧€濅负浣垮懡锛屽垱寤轰簡澶ч噺鍏嶈垂鐨勭紪绋嬫暀绋嬶紝鍖呮嫭浜や簰寮忚绋嬨€佽棰戣绋嬨€佹枃绔犵瓑銆?/span>鎴戜滑姝e湪甯姪鍏ㄧ悆鏁扮櫨涓囦汉瀛︿範缂栫▼锛屽笇鏈涜涓栫晫涓婃瘡涓汉閮芥湁鏈轰細鑾峰緱鍏嶈垂鐨勪紭璐ㄧ殑缂栫▼鏁欒偛璧勬簮锛屾垚涓哄紑鍙戣€呮垨鑰呰繍鐢ㄧ紪绋嬪幓瑙e喅闂銆?/span>

浣犱篃鎯虫垚涓?/span>

freeCodeCamp 绀惧尯鐨勮础鐚€呭悧

娆㈣繋鐐瑰嚮浠ヤ笅鏂囩珷浜嗚В

鉁ㄢ湪



鐐瑰嚮鈥滈槄璇诲師鏂団€?/span>

鍦?nbsp;freeCodeCamp 涓撴爮闃呰鏇村

以上是关于浣犺窛绂?WebGL 鍙樊涓€鐐癸紒的主要内容,如果未能解决你的问题,请参考以下文章

浠婃櫄8鐐癸紝鏂屽彅浜茶韩鏁欎綘缃戦〉缂栫▼鍟︼紒鍏嶈垂锛?宀佷互涓婇浂鍩虹閮藉彲浠ュ惉鎳傦紒

Phong 和 Gouraud 着色 WebGL

闆惰窛绂绘帴瑙ebsocket馃殌