ເລີ່ມຕົ້ນດ້ວຍ WebGL: ແຕ້ມຮູບສີ່ຫລ່ຽມມົນ

ກະວີ: Laura McKinney
ວັນທີຂອງການສ້າງ: 9 ເດືອນເມສາ 2021
ວັນທີປັບປຸງ: 14 ເດືອນພຶດສະພາ 2024
Anonim
ເລີ່ມຕົ້ນດ້ວຍ WebGL: ແຕ້ມຮູບສີ່ຫລ່ຽມມົນ - Creative
ເລີ່ມຕົ້ນດ້ວຍ WebGL: ແຕ້ມຮູບສີ່ຫລ່ຽມມົນ - Creative

ເນື້ອຫາ

  • ຄວາມຮູ້ທີ່ຕ້ອງການ: ຄວາມຮູ້ HTML / JavaScript ລະດັບປານກາງ
  • ຕ້ອງການ: ລ່າສຸດ Chrome ຫລື Firefox 4/5 ທີ່ຮອງຮັບ WebGL
  • ເວລາຂອງໂຄງການ: 2-3 ຊົ່ວໂມງ
  • ເອກະສານສະ ໜັບ ສະ ໜູນ

ການພົບປະຄັ້ງ ທຳ ອິດກັບ WebGL ສາມາດເປັນການຂົ່ມຂູ່. API ບໍ່ມີສິ່ງໃດທີ່ເປັນຫໍສະມຸດວັດຖຸທີ່ເປັນມິດກັບສິ່ງທີ່ທ່ານອາດຈະໃຊ້. WebGL ແມ່ນອີງໃສ່ OpenGL, ເຊິ່ງເປັນຫໍສະມຸດແບບ C ແບບເກົ່າແກ່ກວ່າເກົ່າ. ມັນມີບັນຊີລາຍຊື່ຍາວຂອງ ໜ້າ ທີ່ທີ່ໃຊ້ໃນການຕັ້ງລັດຕ່າງໆແລະສົ່ງຂໍ້ມູນໃຫ້ GPU. ທັງ ໝົດ ນີ້ແມ່ນໄດ້ຖືກອະທິບາຍໄວ້ໃນສະເພາະຂອງທາງການ. ເອກະສານນີ້ບໍ່ໄດ້ມີຈຸດປະສົງ ສຳ ລັບຜູ້ເລີ່ມຕົ້ນ, ຄິດວ່າມັນຈະເປັນປະໂຫຍດຫຼາຍເມື່ອທ່ານເລີ່ມຊອກຫາເສັ້ນທາງ API. ແຕ່ຢ່າຢ້ານ: ດ້ວຍວິທີທີ່ດີທັງ ໝົດ ນີ້ສາມາດແກ້ໄຂໄດ້, ແລະໄວໆນີ້ທ່ານກໍ່ຈະຮູ້ສຶກສະບາຍໃຈ!

ຄວາມເຂົ້າໃຈຜິດທົ່ວໄປກ່ຽວກັບ WebGL ແມ່ນວ່າມັນແມ່ນບາງເຄື່ອງຈັກ 3D ຫຼື API. ໃນຂະນະທີ່ WebGL ມີຄວາມຈິງຫຼາຍຢ່າງທີ່ຈະຊ່ວຍໃຫ້ທ່ານພັດທະນາໂປແກຼມ 3D, ໃນຕົວມັນກໍ່ບໍ່ແມ່ນ 3D. ມັນຈະດີກວ່າທີ່ທ່ານຄິດວ່າ WebGL ເປັນ API ແຕ້ມທີ່ຊ່ວຍໃຫ້ທ່ານສາມາດເຂົ້າເຖິງກາຟິກທີ່ເລັ່ງໃສ່ຮາດແວ.


01. ການແຕ້ມຮູບສີ່ຫລ່ຽມມົນ

ໃນບົດແນະ ນຳ ນີ້ພວກເຮົາຈະສຸມໃສ່ຄວາມເຂົ້າໃຈກ່ຽວກັບວິທີທີ່ WebGL ເຮັດວຽກໂດຍການແຕ້ມຮູບ 2D ທີ່ລຽບງ່າຍ. ແຕ່ສິ່ງ ທຳ ອິດກ່ອນ. ກ່ອນທີ່ພວກເຮົາຈະຂຽນລະຫັດໃດໆ, ພວກເຮົາຕ້ອງສ້າງເອກະສານ HTML ເພື່ອຖືເອົາມັນ.

html>
ຫົວ>
script id = "vertex" type = "x-shader"> / script>
script id = "ຊິ້ນສ່ວນ" type = "x-shader"> / script>
ປະເພດ script = "text / javascript">
function function () {
}
/ script>
/ ຫົວ>
body onload = "init ()">
canvas id = "mycanvas" width = "800" height = "500"> / ຜ້າໃບ>
/ ຮ່າງກາຍ>
/ html>

ນອກເຫນືອຈາກ stub HTML ປົກກະຕິ, ເອກະສານມີບາງສິ່ງທີ່ສະເພາະເຈາະຈົງກັບ WebGL. ກ່ອນອື່ນ ໝົດ ພວກເຮົາ ກຳ ນົດສອງແທັກ script ທີ່ແທນ JavaScript ຈະເປັນລະຫັດ shader. Shaders ແມ່ນຄຸນລັກສະນະ ສຳ ຄັນຂອງ WebGL ແລະພວກເຮົາຈະກັບມາຫາພວກມັນໃນພາຍຫຼັງ.

ສ່ວນປະກອບອື່ນທີ່ພວກເຮົາຈະຕ້ອງການແມ່ນຜ້າໃບ. WebGL ທັງ ໝົດ ຖືກແຕ້ມໃສ່ສ່ວນປະກອບຂອງຜ້າໃບ.

ສຸດທ້າຍພວກເຮົາ ກຳ ນົດຟັງຊັນທີ່ເອີ້ນວ່າ init ເຊິ່ງຈະຖືກຮຽກຮ້ອງທັນທີທີ່ເອກະສານຈະໂຫລດ. ນີ້ແມ່ນບ່ອນທີ່ພວກເຮົາຈະອອກ ຄຳ ສັ່ງທີ່ ຈຳ ເປັນເພື່ອແຕ້ມສິ່ງໃດສິ່ງ ໜຶ່ງ ໃສ່ ໜ້າ ຈໍ. ໃຫ້ເລີ່ມຕົ້ນເພີ່ມລະຫັດບາງຢ່າງໃນ ໜ້າ ທີ່ນີ້.


02. ສະພາບແລະມຸມມອງຂອງ WebGL

ໃນ ໜ້າ ທີ່ init ພວກເຮົາ ຈຳ ເປັນຕ້ອງໄດ້ຮັບສະພາບການ WebGL ຈາກອົງປະກອບ canvas.

canvas = document.getElementById ("mycanvas");
gl = canvas.getContext ("experimental-webgl");

ພວກເຮົາໄດ້ຮັບເອກະສານອ້າງເຖິງອົງປະກອບຂອງຜ້າໃບທີ່ໄດ້ ກຳ ນົດໄວ້ໃນເອກະສານ HTML ແລະຫຼັງຈາກນັ້ນພວກເຮົາໄດ້ຮັບສະພາບການ WebGL ຂອງມັນ. ວັດຖຸທີ່ຖືກສົ່ງຄືນຈະຊ່ວຍໃຫ້ພວກເຮົາເຂົ້າເຖິງ WebGL API. ທ່ານສາມາດຕັ້ງຊື່ໃຫ້ມັນທຸກຢ່າງທີ່ທ່ານຕ້ອງການ, ແຕ່ວ່າ "gl" ເບິ່ງຄືວ່າເປັນສົນທິສັນຍາທີ່ດີ.

ໃຫ້ສັງເກດວ່າສະພາບການ 3D ຖືກເອີ້ນວ່າ "ການທົດລອງ - ເວບໄຊທ໌". ນີ້ແມ່ນການແກ້ໄຂຊົ່ວຄາວຈົນກ່ວາຜູ້ຜະລິດເບົາເຊີຕັດສິນໃຈວ່າມັນມີຄວາມ ໝັ້ນ ຄົງ. ຮອດເວລານັ້ນຊື່ຈະປ່ຽນເປັນພຽງ "webgl".

ເມື່ອພວກເຮົາມີສະພາບການແລ້ວ, ມັນຮອດເວລາທີ່ຈະ ກຳ ນົດມຸມມອງຂອງມຸມມອງແລະຕັ້ງຄ່າສີໄວ້ກ່ອນ. ມຸມມອງຂອງການ ກຳ ນົດພື້ນທີ່ທີ່ທ່ານຕ້ອງການແຕ້ມເນື້ອຫາ WebGL ຢູ່: ໃນກໍລະນີຂອງພວກເຮົາມັນຈະເປັນຜ້າໃບທັງ ໝົດ. ຕໍ່ໄປພວກເຮົາ ກຳ ນົດສີ ທຳ ມະດາ ສຳ ລັບມຸມມອງຂອງ ໜ້າ ຈໍແລະໂທຫາຟັງຊັນທີ່ຊັດເຈນເພື່ອ ກຳ ນົດມຸມມອງຂອງສີນີ້. ສືບຕໍ່ໂດຍການເພີ່ມສາຍຕໍ່ໄປນີ້:


gl.viewport (0, 0, canvas.width, canvas.height);
gl.clearColor (0, 0.5, 0, 1);
gl.clear (gl.COLOR_BUFFER_BIT);

ສັງເກດເຫັນວ່າສີສັນໃນ WebGL ບໍ່ໄດ້ຖືກ ກຳ ນົດໂດຍໃຊ້ notx hex ແຕ່ຕາມປົກກະຕິແມ່ນ 4 ຕົວເລກ, ແຕ່ລະໄລຍະ [0-1] ທີ່ ກຳ ນົດຄ່າຕ່າງໆ ສຳ ລັບຊ່ອງທາງສີແດງ, ສີຂຽວ, ສີຟ້າແລະ Alpha ຕ່າງຫາກ. ຖ້າທ່ານເປີດແຟ້ມໃນໂປແກຼມທ່ອງເວັບທ່ານຄວນຈະເຫັນພື້ນທີ່ຂອງຜ້າໃບທີ່ຖືກທາສີເປັນສີຂຽວເຂັ້ມ.

ຖ້າທ່ານບໍ່ເຫັນສີຂຽວເຂັ້ມຢູ່ເທິງຜ້າໃບ, ແລະທ່ານບໍ່ແນ່ໃຈວ່າລະຫັດຖືກຕ້ອງ, ກະລຸນາກວດເບິ່ງລິ້ງນີ້. ບາງບັດກາຟິກເກົ່າອາດຈະບໍ່ເຮັດວຽກກັບ WebGL ເຖິງແມ່ນວ່າທ່ານຈະມີ browser ທີ່ຮອງຮັບມັນກໍ່ຕາມ.

03. ຄົນໂກງ: ໜ້າ ຮົ່ມ vertex

ໃນຈຸດນີ້ໃຫ້ປ່ອຍໃຫ້ຫນ້າທີ່ເລີ່ມຕົ້ນເປັນເວລາ ໜຶ່ງ ແລະສຸມໃສ່ຄົນທີ່ shaders. ເຄື່ອງເງົາແມ່ນພື້ນຖານ ສຳ ລັບ WebGL: ພວກເຂົາ ກຳ ນົດວິທີການຫຍັງຖືກແຕ້ມໃສ່ ໜ້າ ຈໍ. ໂປແກມ shader ແມ່ນປະກອບດ້ວຍສອງສ່ວນ: vertex ແລະ shader fragment. shader vertex ປະມວນຜົນຈຸດໃນເລຂາຄະນິດຂອງຮູບຮ່າງທີ່ພວກເຮົາ ກຳ ລັງເຮັດ, ໃນຂະນະທີ່ຊິ້ນສ່ວນທີ່ມີຄວາມເຂັ້ມຂຸ້ນ ດຳ ເນີນການໃນແຕ່ລະ pixels ທີ່ເຮັດໃຫ້ຮູບຮ່າງນີ້ສົມບູນ.

ສໍາລັບຕົວຢ່າງຂອງພວກເຮົາພວກເຮົາຈະສ້າງ shaders ຂັ້ນພື້ນຖານບາງຢ່າງ. ໃຫ້ເລີ່ມຕົ້ນດ້ວຍຮູບແບບ vertex. ພາຍໃນປ້າຍ tag ດ້ວຍ id "vertex" ເພີ່ມສາຍຕໍ່ໄປນີ້:

attribute vec2 aVertexPosition;

void ຫລັກ () {
gl_Position = vec4 (aVertexPosition, 0.0, 1.0);
}

ທຸກໆ shader ມີຫນ້າທີ່ເອີ້ນວ່າຕົ້ນຕໍເຊິ່ງຈະຖືກປະຕິບັດໃນລະຫວ່າງການສະແດງ. ຕົວແປຕ່າງໆທີ່ປະກາດໃນສ່ວນຫົວແມ່ນພາລາມິເຕີຂອງ ໜ້າ ທີ່ນັ້ນ - ພວກມັນສາມາດເປັນທັງຄຸນລັກສະນະຫລືເຄື່ອງແບບ. ພວກເຮົາຈະເຫັນຕົວແປທີ່ເປັນເອກະພາບກັນພາຍຫຼັງ, ຕອນນີ້ໃຫ້ພິຈາລະນາກ່ຽວກັບຄຸນລັກສະນະດັ່ງກ່າວ.

ຄຸນລັກສະນະແມ່ນຂໍ້ມູນທີ່ຈະຖືກປະມວນຜົນ - ໜ້າ ທີ່ຫຼັກຂອງ shader ຈະຖືກຮຽກຮ້ອງໃຫ້ແຕ່ລະອົງປະກອບໃນ array ນີ້. ໂດຍປົກກະຕິຄຸນລັກສະນະຈະຖືຂໍ້ມູນທີ່ກ່ຽວຂ້ອງກັບ ຕຳ ແໜ່ງ ຂອງແນວຕັ້ງ, ສີຂອງພວກມັນຫຼືຕົວປະສານງານດ້ານໂຄງສ້າງ. ເຖິງຢ່າງໃດກໍ່ຕາມ, ມັນບໍ່ໄດ້ ຈຳ ກັດພຽງແຕ່ເທົ່ານັ້ນ - ມັນແມ່ນຕົວເລກຂອງຕົວເລກແລະເງົາສາມາດຕີຄວາມ ໝາຍ ໃຫ້ພວກເຂົາໃນແບບທີ່ທ່ານຕ້ອງການ. ພວກເຮົາຈະສົ່ງຂໍ້ມູນຄຸນລັກສະນະຈາກ JavaScript ໄປຫາເງົາໃນເວລາຕໍ່ມາ.

ສິ່ງທີ່ເກີດຂື້ນຢູ່ນີ້ແມ່ນພວກເຮົາເອົາຄຸນຄ່າຂອງຄຸນລັກສະນະແລະມອບ ໝາຍ ໃຫ້ຕົວແປພິເສດທີ່ມີຊື່ວ່າ gl_Position. ນີ້ແມ່ນວິທີທີ່ຜູ້ໃຫ້ກຽດກັບຄືນຄ່ານິຍົມ - ບໍ່ມີ ຄຳ ວ່າ "ກັບຄືນ", ແຕ່ທ່ານ ຈຳ ເປັນຕ້ອງມອບຄ່າໃຫ້ຕົວແປພິເສດນີ້ແທນ.

ໃຫ້ສັງເກດວ່າພວກເຮົາເລືອກທີ່ຈະໃຊ້ vector ອົງປະກອບສອງເປັນປະເພດຂອງຄຸນລັກສະນະຂອງພວກເຮົາ - ເຊິ່ງເຮັດໃຫ້ມີຄວາມຮູ້ສຶກ, ເພາະວ່າພວກເຮົາຈະແຕ້ມຮູບຮ່າງໂດຍໃຊ້ຕົວປະສານ 2D. ຢ່າງໃດກໍ່ຕາມ gl_Position ຄາດວ່າຈະມີ vector ອົງປະກອບ 4 ຢ່າງ. ສິ່ງທີ່ພວກເຮົາຈະເຮັດ, ແມ່ນເພື່ອຮວບຮວມຂໍ້ມູນສອງຢ່າງທີ່ຍັງເຫຼືອ, ເພາະວ່າມັນຈະຄືກັນໃນກໍລະນີນີ້.

ຖ້າທ່ານສົງໄສວ່າຄຸນຄ່າສອງຢ່າງນີ້ເປັນຕົວແທນແນວໃດ: ຄຸນຄ່າທີສາມ, ເຊິ່ງພວກເຮົາຕັ້ງເປັນ 0, ແມ່ນ "ຄວາມເລິກ" ຂອງ ຄຳ ວ່າ vertex. ມັນສາມາດມີຄຸນຄ່າໃດໆ, ແຕ່ວ່າຖ້າມັນແມ່ນ> 1 ຫຼື -1 ທີ່ວ່າ vertex ຈະບໍ່ຖືກດຶງດູດ. ສິ່ງໃດໃນລະຫວ່າງຈະຖືກແຕ້ມແລະວັດຖຸທີ່ມີຄວາມເລິກນ້ອຍກວ່າຈະຖືກແຕ້ມຢູ່ທາງ ໜ້າ. ຄິດວ່າມັນຄ້າຍຄືກັບ z-index ໃນ CSS. ຄວາມເລິກແມ່ນມີຄວາມ ສຳ ຄັນຫຼາຍໃນການສະແດງພາບ 3D.

ຕົວເລກທີ່ສີ່ແມ່ນຕົວປະສານງານທີ່ເອີ້ນວ່າ homogenous ທີ່ໃຊ້ໃນການຄາດຄະເນທັດສະນະ. ມັນເກີນຂອບເຂດຂອງບົດແນະ ນຳ ນີ້ເພື່ອປຶກສາຫາລື, ແຕ່ວ່າໃນກໍລະນີທີ່ງ່າຍໆເຊັ່ນວ່າບົດນີ້ມັນຄວນຈະມີຄຸນຄ່າ 1.

04. Shaders: shader ຊິ້ນ

ຕອນນີ້ຂໍອະທິບາຍ shader ຊິ້ນສ່ວນ. ພາຍໃນປ້າຍ tag ດ້ວຍ id "fragment" ເພີ່ມສາຍຕໍ່ໄປນີ້:

#ifdef GL_ES
float high precision ຄວາມແມ່ນຍໍາ;
#endif

ເອກະພາບ vec4 uColor;

void ຫລັກ () {
gl_FragColor = uColor;
}

ດຽວກັນກັບ vertex shader, shader fragment ແມ່ນມີຄວາມ ຈຳ ເປັນ ໜຶ່ງ ໃນ ໜ້າ ທີ່, ແລະມັນ ຈຳ ເປັນຕ້ອງເອີ້ນວ່າ "main". ສາມສາຍ ທຳ ອິດແມ່ນລະຫັດແຜ່ນ boiler - ມັນ ກຳ ນົດຄວາມຊັດເຈນທີ່ ນຳ ໃຊ້ກັບຄ່າຈຸດລອຍແລະມັນພຽງແຕ່ຕ້ອງການຢູ່ທີ່ນັ້ນ.

ຕໍ່ໄປພວກເຮົາ ກຳ ນົດ uColor ຕົວແປທີ່ເປັນເອກະພາບ. ກົງກັນຂ້າມກັບຄຸນລັກສະນະ, ຕົວແປທີ່ເປັນເອກະພາບແມ່ນຄົງທີ່. ເມື່ອເຄື່ອງໂກນຫນວດຖືກປະຕິບັດ ສຳ ລັບແຕ່ລະ vertex ແລະ pixel ໃນ ໜ້າ ຈໍ, ຄ່າທີ່ເປັນເອກະພາບຈະຍັງຄົງຄືເກົ່າໃນທຸກໆການໂທ. ພວກເຮົາໃຊ້ມັນເພື່ອ ກຳ ນົດສີຂອງຮູບຮ່າງທີ່ພວກເຮົາຈະແຕ້ມ. ພວກເຮົາຈະຜ່ານມູນຄ່າ ສຳ ລັບສີນີ້ຈາກ JavaScript.

ໃຫ້ສັງເກດວ່າສີຍັງເປັນ vector ສີ່ສ່ວນປະກອບ - ຫນຶ່ງສໍາລັບແຕ່ລະຊ່ອງສີ: ສີແດງ, ສີຂຽວແລະສີຟ້າແລະຫນຶ່ງສໍາລັບຊ່ອງທາງບໍ່ມີເພດ; ກົງກັນຂ້າມກັບ CSS, ຄຸນຄ່າ ສຳ ລັບແຕ່ລະຊ່ອງບໍ່ແມ່ນຢູ່ໃນລະດັບ 0-255 ແຕ່ຢູ່ໃນລະດັບ 0-1.

ເຄື່ອງຕັດຊິ້ນສ່ວນທີ່ແຕກຕ່າງກັນແມ່ນງ່າຍດາຍຫຼາຍ - ມັນພຽງແຕ່ເອົາຄ່າສີແລະມອບໃຫ້ຕົວແປພິເສດທີ່ມີຊື່ວ່າ gl_FragColor. shader ນີ້ພຽງແຕ່ຈະໃຊ້ສີດຽວກັນກັບທຸກໆ pixel ທີ່ຖືກແຕ້ມໃນຫນ້າຈໍ.

05. ການລວບລວມແລະການເຊື່ອມໂຍງ shaders

ເຄື່ອງຂອງພວກເຮົາຢູ່ໃນສະຖານທີ່, ສະນັ້ນໃຫ້ກັບໄປໃຊ້ JavaScript ແລະສືບຕໍ່ໃນ ໜ້າ ທີ່ລິເລີ່ມ. ພຽງແຕ່ຫລັງຈາກການໂທໄປທີ່ gl.clear () ເພີ່ມສາຍຕໍ່ໄປນີ້:

var v = ເອກະສານ .getElementById ("vertex"). firstChild.nodeValue;
var f = document.getElementById ("ຊິ້ນສ່ວນ"). firstChild.nodeValue;

var vs = gl.createShader (gl.VERTEX_SHADER);
gl.shaderSource (vs, v);
gl.compileShader (vs);

var fs = gl.createShader (gl.FRAGMENT_SHADER);
gl.shaderSource (fs, f);
gl.compileShader (fs);

program = gl.createProgram ();
gl.attachShader (program, vs);
gl.attachShader (program, fs);
gl.linkProgram (program);

ມີສິ່ງ ໜຶ່ງ ທີ່ທ່ານ ຈຳ ເປັນຕ້ອງຮູ້ກ່ຽວກັບການໂກນ. ພວກເຂົາບໍ່ໄດ້ຮັບການປະຕິບັດໃນເບົາເຊີຄືກັບລະຫັດ JavaScript ທີ່ເຮັດ. ທ່ານ ຈຳ ເປັນຕ້ອງລວບລວມຮົ່ມເງົາກ່ອນ - ແລະນີ້ແມ່ນສິ່ງທີ່ລະຫັດຂ້າງເທິງເຮັດ. ສອງເສັ້ນ ທຳ ອິດພຽງແຕ່ໃຊ້ຕົວແບບ DOM ເພື່ອຈັບແຫລ່ງທີ່ມາຂອງ shader ເປັນສາຍເຊືອກ. ເມື່ອພວກເຮົາມີແຫລ່ງທີ່ມາ, ພວກເຮົາສ້າງເປັນວັດຖຸ shader ສອງ, ສົ່ງແຫຼ່ງແລະລວບລວມພວກມັນ.

ໃນຂັ້ນຕອນນີ້ພວກເຮົາມີເຄື່ອງຕັດຜົມສອງແຍກແລະພວກເຮົາ ຈຳ ເປັນຕ້ອງເອົາມັນເຂົ້າໄປໃນສິ່ງທີ່ເອີ້ນວ່າ "ໂປແກຼມ" ໃນ WebGL. ນີ້ແມ່ນເຮັດໄດ້ໂດຍການເຊື່ອມໂຍງພວກມັນ - ເຊິ່ງເຮັດກັບສ່ວນສຸດທ້າຍຂອງລະຫັດ.

06. ແກ້ຄວາມໂກດແຄ້ນ

ການແກ້ໄຂບັນຫາ shaders ສາມາດເປັນ tricky. ຖ້າມີຂໍ້ຜິດພາດໃນລະຫັດ shader, ມັນຈະລົ້ມເຫລວຢ່າງງຽບໆແລະບໍ່ມີທາງທີ່ຈະບັນທຶກຄຸນຄ່າຈາກມັນ. ສະນັ້ນມັນດີສະ ເໝີ ໄປທີ່ຈະກວດເບິ່ງວ່າຂະບວນການລວບລວມແລະການເຊື່ອມໂຍງ ດຳ ເນີນໄປໄດ້ດີຫລືບໍ່. ຫຼັງຈາກເຊື່ອມໂຍງໂປແກຼມແລ້ວຕື່ມສາຍຕໍ່ໄປນີ້:

ຖ້າ (! gl.getShaderParameter (vs, gl.COMPILE_STATUS))
console.log (gl.getShaderInfoLog (vs));

ຖ້າ (! gl.getShaderParameter (fs, gl.COMPILE_STATUS))
console.log (gl.getShaderInfoLog (fs));

ຖ້າ (! gl.getProgramParameter (ໂປແກຼມ, gl.LINK_STATUS))
console.log (gl.getProgramInfoLog (program));

ໃນປັດຈຸບັນ, ຖ້າມີບັນຫາໃນລະຫວ່າງການລວບລວມຂໍ້ມູນຫລືການເຊື່ອມໂຍງ, ທ່ານຈະໄດ້ຮັບຂໍ້ຄວາມທີ່ດີໃນ console ຂອງທ່ານ.

ດ້ວຍເຄື່ອງປະດັບຂອງພວກເຮົາຢູ່ໃນສະຖານທີ່ແລະລວບລວມ, ພວກເຮົາສາມາດກ້າວຕໍ່ໄປເພື່ອ ກຳ ນົດຈຸດປະສານງານ ສຳ ລັບຮູບຮ່າງຂອງພວກເຮົາ.

07. ລະບົບປະສານງານແບບພື້ນເມືອງ

ລະບົບການປະສານງານແບບພື້ນເມືອງຂອງ WebGL ມີລັກສະນະດັ່ງນີ້:

ພິກະເຊນດ້ານຊ້າຍດ້ານເທິງແມ່ນຢູ່ທີ່ -1, -1, ດ້ານລຸ່ມແມ່ນຢູ່ທີ່ 1,1 ໂດຍບໍ່ສົນເລື່ອງຂະ ໜາດ ແລະສັດສ່ວນຂອງຜ້າໃບ. ທ່ານ ຈຳ ເປັນຕ້ອງດູແລສັດສ່ວນຂອງຕົວທ່ານເອງ.

ໃນ WebGL ມີສາມປະເພດຂອງຮູບແຕ້ມພື້ນຖານ: ຈຸດ, ເສັ້ນແລະສາມຫຼ່ຽມ. ເສັ້ນແລະຈຸດແມ່ນມີປະໂຫຍດຫຼາຍແຕ່ສາມຫຼ່ຽມແມ່ນມີຄວາມນິຍົມຫຼາຍທີ່ສຸດ - ວັດຖຸ 3D ແຂງທັງ ໝົດ ປະກອບດ້ວຍສາມຫຼ່ຽມ. ພວກເຮົາຕ້ອງການແຕ້ມຮູບສີ່ຫຼ່ຽມມົນ - ແລະສີ່ຫຼ່ຽມມົນສາມາດປະກອບດ້ວຍສອງສາມຫຼ່ຽມ.

ສິ່ງທີ່ພວກເຮົາຕ້ອງເຮັດໃນປັດຈຸບັນແມ່ນການສ້າງຂບວນ, ເຊິ່ງໃນ WebGL ເອີ້ນວ່າ buffer, ໂດຍມີຈຸດປະສານງານຂອງສອງສາມຫຼ່ຽມ. ນີ້ແມ່ນລະຫັດ:

var aspect = canvas.width / canvas.height;

var vertices = Float32Array ໃໝ່ ([
-0.5, 0.5 * ລັກສະນະ, 0.5, 0.5 * ລັກສະນະ, 0.5, -0.5 * ລັກສະນະ, // ສາມຫຼ່ຽມ 1
-0.5, 0.5 * ລັກສະນະ, 0.5, -0.5 * ລັກສະນະ, -0.5, -0.5 * ດ້ານ // ສາມຫຼ່ຽມ 2
]);

vbuffer = gl.createBuffer ();
gl.bindBuffer (gl.ARRAY_BUFFER, vbuffer);
gl.bufferData (gl.ARRAY_BUFFER, ສາຍຕັ້ງ, gl.STATIC_DRAW);

itemSize = 2;
numItems = vertices.length / itemSize;

ກ່ອນອື່ນ ໝົດ, ເພື່ອເຮັດໃຫ້ຮຽບຮ້ອຍມີສັດສ່ວນທີ່ ເໝາະ ສົມກັບຜ້າໃບທີ່ມີຂະ ໜາດ ໃດ, ພວກເຮົາຄິດໄລ່ອັດຕາສ່ວນ. ຕໍ່ໄປພວກເຮົາສ້າງຂບວນການທີ່ພິມດ້ວຍ 12 ຈຸດປະສານງານ - ຫົກຈຸດໃນ 2D ຂະ ໜາດ ປະກອບເປັນສອງສາມຫລ່ຽມ. ພວກເຮົາຄູນຄ່າ Y ຂອງແຕ່ລະ vertex ໂດຍອັດຕາສ່ວນ. ໃຫ້ສັງເກດວ່າສອງສາມຫລ່ຽມ ຄຳ ເຫລົ່ານັ້ນຈະ "ຕິດ" ຢູ່ເບື້ອງ ໜຶ່ງ ເພື່ອສ້າງເປັນຮູບສີ່ຫລ່ຽມ, ແຕ່ມັນບໍ່ໄດ້ເຊື່ອມໂຍງເຂົ້າກັນເລີຍ.

ຕໍ່ໄປພວກເຮົາຍ້າຍໄປ ໜ້າ ທີ່ WebGL ເພື່ອສ້າງ buffer ແລະເຊື່ອມຕໍ່ແຖວ vertex ກັບ buffer ນີ້. ວິທີການໃນການເຮັດສິ່ງນີ້ແມ່ນການຜູກຂໍ້ຄວາມປ້ອງກັນ: ເຮັດໃຫ້ມັນກາຍເປັນ "ປັດຈຸບັນ" ທີ່ຢູ່ໃນ WebGL. ໃນເວລາທີ່ມັນຖືກຜູກມັດ, ການໂທຫາຫນ້າທີ່ໃດກໍ່ຕາມຈະປະຕິບັດງານກັບ buffer ນີ້ແລະນີ້ແມ່ນສິ່ງທີ່ເກີດຂື້ນໃນເວລາທີ່ພວກເຮົາຮຽກຮ້ອງ bufferData.

ນີ້ແມ່ນວິທີການຫຼາຍຢ່າງທີ່ເກີດຂື້ນໃນ WebGL: ທ່ານໄດ້ ກຳ ນົດຄຸນຄ່າຂອງຊັບສິນຫລືທ່ານ ກຳ ນົດວັດຖຸບາງຢ່າງເປັນ "ປັດຈຸບັນ" ແລະຈົນກວ່າທ່ານຈະ ກຳ ນົດມັນໃສ່ສິ່ງອື່ນ, ຫຼືບໍ່ມີຄ່າ, ຄ່ານີ້ຈະຖືກ ນຳ ໃຊ້ໃນທຸກໆການໂທຫາ API . ໃນຄວາມ ໝາຍ ນັ້ນ, ທຸກສິ່ງທຸກຢ່າງແມ່ນທົ່ວໂລກໃນ WebGL, ສະນັ້ນຈົ່ງຮັກສາລະຫັດຂອງທ່ານໃຫ້ເປັນລະບຽບ!

ສຸດທ້າຍພວກເຮົາ ກຳ ນົດຂະ ໜາດ ຂອງ vertex ດຽວໃຫ້ເປັນຕົວແປ ໜຶ່ງ ແລະ ຈຳ ນວນຂອງແນວຕັ້ງໃນຂບວນກັບອີກອັນ ໜຶ່ງ, ສຳ ລັບການ ນຳ ໃຊ້ຕໍ່ມາ.

08. ການ ກຳ ນົດເຄື່ອງແບບແລະຄຸນລັກສະນະຕ່າງໆ

ພວກເຮົາເກືອບຈະເຮັດແລ້ວ, ແຕ່ພວກເຮົາຍັງຕ້ອງໄດ້ສົ່ງຂໍ້ມູນທັງ ໝົດ ຈາກ Javascript ໄປບ່ອນ shaders ກ່ອນທີ່ພວກເຮົາຈະແຕ້ມຫຍັງ. ຖ້າທ່ານຈື່ໄດ້, vertex shader ມີຄຸນລັກສະນະຂອງ vec2 ຊະນິດທີ່ເອີ້ນວ່າ aVertexAttribute ແລະ shader ຊິ້ນສ່ວນມີຕົວແປທີ່ເປັນເອກະພາບຂອງ type vec4 ທີ່ເອີ້ນວ່າ uColor. ເນື່ອງຈາກນັກ shaders ທັງສອງໄດ້ຖືກລວບລວມເຂົ້າໃນໂປແກຼມດຽວ, ພວກເຮົາໃຊ້ເອກະສານອ້າງອີງໃສ່ໂປແກຼມນີ້ເພື່ອໃຫ້ພວກມັນມີຄຸນຄ່າທີ່ມີຄວາມ ໝາຍ.

ໃຫ້ສືບຕໍ່ຢູ່ໃນ ໜ້າ ທີ່ລິເລີ່ມ:

gl.useProgram (program);

program.uColor = gl.getUniformLocation (ໂປຣແກຣມ, "uColor");
gl.uniform4fv (program.uColor, [0.0, 0.3, 0.0, 1.0]);

program.aVertexPosition = gl.getAttribLocation (program, "aVertexPosition");
gl.enableVertexAttribArray (program.aVertexPosition);
gl.vertexAttribPointer (program.aVertexPosition, itemSize, gl.FLOAT, false, 0, 0);

ສາຍ ທຳ ອິດແນະ ນຳ ໃຫ້ WebGL ນຳ ໃຊ້ໂປແກຼມປະຈຸບັນ ສຳ ລັບການໂທຕໍ່ໆໄປ.

ການ ນຳ ໃຊ້ຟັງຊັນ getUniformLocation ພວກເຮົາສາມາດໄດ້ຮັບການອ້າງອີງເຖິງທີ່ຕັ້ງຂອງຕົວແປທີ່ເປັນເອກະພາບໃນບ່ອນທີ່ມີຊິ້ນສ່ວນຂອງພວກເຮົາ. ໃຫ້ສັງເກດວ່າຖ້າຕົວແປທີ່ເປັນເອກະພາບຢູ່ໃນ vertex shader ແທນ, ລະຫັດກໍ່ຈະຄືກັນ. ເມື່ອພວກເຮົາມີມັນ, ພວກເຮົາເກັບຮັກສາມັນໄວ້ໃນຕົວປ່ຽນແປງແບບເຄື່ອນໄຫວຂອງວັດຖຸໂປຼແກຼມ (ພວກເຮົາສາມາດເກັບມັນໄວ້ໃນຕົວແປທົ່ວໂລກຫລືທ້ອງຖິ່ນເຊັ່ນດຽວກັນ, ແຕ່ວິທີນັ້ນເຮັດໃຫ້ລະຫັດນັ້ນຖືກຈັດແຈງຫຼາຍຂື້ນ).

ຕໍ່ໄປພວກເຮົາມອບຄ່າ uColor ເປັນເອກະພາບ. ໃນກໍລະນີນີ້ມັນຕ້ອງເປັນ 4 ແຖວ, ກຳ ນົດຊ່ອງທາງສີແດງ, ສີຂຽວ, ສີຟ້າແລະບໍ່ມີເພດ; ຕາມ ລຳ ດັບ.

ຫຼັງຈາກທີ່ພວກເຮົາ ກຳ ນົດຕົວແປທີ່ເປັນເອກະພາບ, ພວກເຮົາກ້າວໄປສູ່ຄຸນລັກສະນະ. ມັນຮຽກຮ້ອງໃຫ້ມີຂັ້ນຕອນພິເສດບໍ່ຫຼາຍປານໃດ. ພວກເຮົາໄດ້ຮັບທີ່ຕັ້ງຂອງຄຸນລັກສະນະໃນຮົ່ມໃນແບບທີ່ຄ້າຍຄືກັນກັບທີ່ພວກເຮົາໄດ້ຮັບເອກະພາບ - ເຖິງແມ່ນວ່າພວກເຮົາໃຊ້ ໜ້າ ທີ່ອື່ນ ສຳ ລັບສິ່ງນັ້ນ.

ຕໍ່ໄປພວກເຮົາຕ້ອງໄດ້ ກຳ ນົດຄຸນລັກສະນະແລະ ກຳ ນົດຕົວຊີ້ທິດທາງໃຫ້ກັບຄຸນລັກສະນະນີ້. ໃນກໍລະນີທີ່ທ່ານສົງໄສວ່າ WebGL ຮູ້ໄດ້ແນວໃດວ່າພວກເຮົາຕ້ອງການໃຊ້ buffer ທີ່ປະກາດຂ້າງເທິງນີ້ຈື່ ຈຳ ລັກສະນະທົ່ວໂລກຂອງ ໜ້າ ທີ່ຂອງ WebGL. ພວກເຮົາໄດ້ໂທຫາ bindBuffer ສອງສາມສາຍກ່ອນທີ່ຈະເປັນດັ່ງນັ້ນມັນຍັງແມ່ນປັດຈຸບັນ.

ຄໍາຮ້ອງສະຫມັກໃນໂລກທີ່ແທ້ຈິງບໍ່ຄ່ອຍຈະງ່າຍດາຍຄືກັບຕົວຢ່າງນີ້ແລະທ່ານຈະຕ້ອງໄດ້ເອົາໃຈໃສ່ເປັນພິເສດເພື່ອຈະຮູ້ວ່າປັດຈຸບັນຫຼືໂປແກຼມໃດຖືກຜູກມັດແລະນໍາໃຊ້. ພ້ອມກັນນັ້ນ, ກົດລະບຽບຂອງໂປແກມ ສຳ ລັບການເພີ່ມປະສິດທິພາບຂອງລະຫັດແມ່ນການຫຼຸດຜ່ອນ ຈຳ ນວນຂໍ້ຜູກມັດແລະຂໍ້ຜູກມັດທີ່ບໍ່ມີການຜູກມັດຫລືປ່ຽນລະຫວ່າງໂປແກມ shader.

ໃນ ໜ້າ ທີ່ vertexAttribPointer ໂທຫາພວກເຮົາ ກຳ ນົດຂະ ໜາດ ຂອງຂໍ້ມູນໃນຄຸນລັກສະນະ. ມັນເວົ້າຄືວ່າ: ທຸກໆຄຸນລັກສະນະແມ່ນປະກອບດ້ວຍສອງຕົວເລກຕໍ່ໄປໃນແຖວ. WebGL ຈະສະກັດເອົາພວກມັນໂດຍອັດຕະໂນມັດແລະຫຸ້ມຫໍ່ມັນເປັນຕົວແປຂອງ vec2 ປະເພດທີ່ເຂົ້າໄປໃນເງົາ.

09. ຮູບແຕ້ມ

ນີ້ແມ່ນສາຍສຸດທ້າຍແລະ ສຳ ຄັນທີ່ສຸດ:

gl.drawArrays (gl.TRIANGLES, 0, numItems);

ການໂຕ້ຖຽງຄັ້ງທໍາອິດຂອງຟັງຊັນ drawArrays ໄດ້ລະບຸຮູບແບບການແຕ້ມຮູບ. ພວກເຮົາຕ້ອງການແຕ້ມຮູບສີ່ຫຼ່ຽມມົນທີ່ແຂງ, ສະນັ້ນພວກເຮົາໃຊ້ gl.TRIANGLES. ທ່ານຍັງສາມາດລອງໃຊ້ gl.LINES ແລະ gl.POINTS.

ຟັງຊັນນີ້ຈະໃຊ້ buffer ທີ່ຖືກຜູກມັດໃນປະຈຸບັນແລະເອີ້ນວ່າໂປແກຼມ shader ໃນປະຈຸບັນ ສຳ ລັບແຕ່ລະຄຸນລັກສະນະຫຼາຍເທົ່າທີ່ພວກເຮົາໄດ້ລະບຸໃນການໂຕ້ຖຽງຄັ້ງສຸດທ້າຍ. ນັ້ນແມ່ນເຫດຜົນທີ່ພວກເຮົາໄດ້ຄິດໄລ່ມູນຄ່າເລກມັນກ່ອນ. ຖ້າວ່າ buffer ບໍ່ມີສ່ວນປະກອບທີ່ພຽງພໍ, ຂໍ້ຜິດພາດກໍ່ຈະຖືກຖິ້ມເພາະສະນັ້ນຕ້ອງມີການດູແລພິເສດເພື່ອຮັບປະກັນວ່າຂໍ້ມູນຈະບໍ່ມີການສໍ້ລາດບັງຫຼວງ.

ຖ້າທຸກຢ່າງດີ, ທ່ານຄວນຈະເຫັນສີໃດກໍ່ຕາມທີ່ທ່ານປ່ຽນໄປໃນຕົວແປທີ່ເປັນເອກະພາບ. ແຫຼ່ງທີ່ສົມບູນຂອງຕົວຢ່າງສາມາດພົບໄດ້ໃນການສາທິດຢູ່ເທິງສຸດຂອງການສອນນີ້.

10. ສະຫຼຸບ

ມັນອາດຈະເບິ່ງຄືວ່າບໍ່ຫຼາຍປານໃດ - ດັ່ງນັ້ນພວກເຮົາໄດ້ສ້າງຮຽບຮ້ອຍ ... ໃນຄວາມເປັນຈິງມັນເປັນຕົວຢ່າງທີ່ງ່າຍດາຍ, ແຕ່ຖ້າທ່ານເຂົ້າໃຈພື້ນຖານ, ທ່ານຈະສາມາດເຄື່ອນຍ້າຍໄດ້ໄວໃນການຮຽນຮູ້ແລະເຂົ້າໃຈສ່ວນທີ່ເຫຼືອ.

ເພື່ອເລີ່ມຕົ້ນທີ່ດີທີ່ຈະຮູ້ກ່ຽວກັບລະບົບການປະສານງານແບບພື້ນເມືອງ. ເຖິງແມ່ນວ່າທ່ານຈະບໍ່ໄດ້ຮັບການຈັດການກັບມັນໂດຍກົງແຕ່ແທນທີ່ຈະຜ່ານການຫັນປ່ຽນມາຕຣິກເບື້ອງຕ່າງໆ, ມັນຈະເປັນປະໂຫຍດຫລາຍທີ່ຈະຮູ້ວ່າທຸກຢ່າງສິ້ນສຸດລົງຢູ່ໃສ.

ຄຸນລັກສະນະແລະເຄື່ອງແບບນັກຮຽນກໍ່ມີຄວາມ ສຳ ຄັນຫຼາຍ: ພວກມັນແມ່ນວິທີການສື່ສານລະຫວ່າງ JavaScript ກັບ shaders ທີ່ແລ່ນກັບ GPU, ສະນັ້ນໃຫ້ພວກເຂົາຮູ້ຈັກແລະ ນຳ ໃຊ້ມັນ.

ນັ້ນແມ່ນ ສຳ ລັບດຽວນີ້. ຂ້ອຍຫວັງວ່າເຈົ້າຈະມັກການສອນແລະ WebGL!

Bartek ເຮັດວຽກເປັນນັກວິຊາການດ້ານການສ້າງສັນທີ່ Tool of North America. ລາວຂຽນ blog ທີ່ສຸມໃສ່ 3D ແບບໂຕ້ຕອບໃນເວລາຈິງ, ເຊິ່ງເອີ້ນວ່າ Everyday3D ແລະລາວເປັນຜູ້ຂຽນຂອງ J3D, ເປັນເຄື່ອງຈັກເປີດ WebGL. ທ່ານສາມາດຕິດຕາມລາວໃນ Twitter: @bartekd.

ສິ່ງພິມໃຫມ່
7 ທ່າອ່ຽງພາບເຄື່ອນໄຫວຂະ ໜາດ ໃຫຍ່ຂອງປີ 2020
ອ່ານ​ຕື່ມ

7 ທ່າອ່ຽງພາບເຄື່ອນໄຫວຂະ ໜາດ ໃຫຍ່ຂອງປີ 2020

ພາບເຄື່ອນໄຫວ ກຳ ລັງມີຊ່ວງເວລາ, ສະນັ້ນການຮູ້ກ່ຽວກັບແນວໂນ້ມການເຄື່ອນໄຫວລ້າສຸດສາມາດເປັນສິ່ງທີ່ດີ. ກັບບັນດາຍີ່ຫໍ້ທີ່ໃຫ້ຄວາມໂປດປານຈາກສື່ກາງໃນການສື່ສານຂະ ໜາດ ໃຫຍ່ແລະບັນດາຫົວຂໍ້ທີ່ສັບສົນໃນວິທີທີ່ກົງໄປກົງມາ, ...
ເປັນຫຍັງເວັບໄຊທ໌້ຂອງເຈົ້າຕ້ອງການອົງປະກອບຕົວຈິງ
ອ່ານ​ຕື່ມ

ເປັນຫຍັງເວັບໄຊທ໌້ຂອງເຈົ້າຕ້ອງການອົງປະກອບຕົວຈິງ

ເລື້ອຍໆເມື່ອພວກເຮົາເລີ່ມຕົ້ນເຮັດວຽກໃນການອອກແບບເວບໄຊທ໌ ໃໝ່, ພວກເຮົາສຸມໃສ່ການສ້າງຊັບສິນທາງສາຍຕາທັງ ໝົດ ພາຍໃນຕົວເອງໃນການອອກແບບຂອງພວກເຮົາ.ພວກເຮົາເລີ່ມຕົ້ນດ້ວຍຮູບຮ່າງແລະຕົວອັກສອນ, ຫຼັງຈາກນັ້ນກ້າວໄປສູ່ການຄິ...
ວິທີການສ້າງ monster ກາຕູນ 3D
ອ່ານ​ຕື່ມ

ວິທີການສ້າງ monster ກາຕູນ 3D

ໂດຍໄດ້ທົດລອງໃຊ້ພາບເຄື່ອນໄຫວ 2D ສັ້ນໆແລະຕົວແບບຕົວແບບໃນຮູບພາບເຄື່ອນໄຫວ, Alex Ruiz ໄດ້ສ້າງ The Terrible Hulken tein ເປັນໂຄງການສ່ວນຕົວເພື່ອຊ່ວຍລາວໃນການ ສຳ ພາດວຽກ ສຳ ລັບບໍລິສັດເກມ.ລາວອະທິບາຍວ່າ“ ນີ້ແມ່ນໂຄງ...