SlideShare a Scribd company logo
1 of 40
WebGL
입문2
ProjectBS – WebGL 소모임
+
Triangle 
Rect
var rectData = [
-.5, -.5, 0.0,
-.5, .5, 0.0,
.5, -.5, 0.0,
-.5, .5, 0.0,
.5, -.5, 0.0,
.5, .5, 0.0
]
rectBuffer.itemSize = 3
rectBuffer.numItem = 6
2개의 삼각형 정의 1
var rectData = [
-.5, -.5, 0.0,
-.5, .5, 0.0,
.5, -.5, 0.0,
.5, .5, 0.0
]
rectBuffer.itemSize = 3
rectBuffer.numItem = 4
2개의 삼각형 정의 2
Index Buffer
0
1
2
3
0,1,2, 1,2,3
var rectIndexData = [ 0,1,2, 1,2,3 ]
var rectIndexBuffer = gl.createBuffer()
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, rectIndexBuffer)
gl.bufferData(
gl.ELEMENT_ARRAY_BUFFER,
new Uint16Array(rectIndexData), gl.STATIC_DRAW
)
rectIndexBuffer.itemSize = 1
rectIndexBuffer.numItem = 6
HOW TO..
//gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer);
…
// gl.drawArrays(gl.TRIANGLES, 0, rectBuffer.numItem);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, rectIndexBuffer)
gl.drawElements(gl.TRIANGLES, rectIndexBuffer.numItem,
gl.UNSIGNED_SHORT, 0);
Render Update
http://ligo.kr/krd
0,1,2,3,4,5,6..
gl.drawArrays(gl.TRIANGLE_ST
RIP)
gl.drawArrays(gl.TRIANGLES)
0,1,2,3,4,5,6..
0,1,2 1,2,3
2,3,4 4,5,6
0,1,2 3,4,5
6,7,8 9,10,11
한 붓 그리기 개별적 그리기
구조체를 만들어보자
렌더링에 필요한 것은?
1. 프로그램
2. 버텍스 버퍼 (VBO : 지오메트리 정보)
3. 인덱스 버퍼 (IBO : 인덱스 정보)
4. Position
5. Rotation
6. 앞으로 필요한 어떤 것들…
function Mesh() {
var result = {
program : firstProgram,
vbo : rectBuffer, // ( VBO : 지오메트리 정보 )
ibo : rectIndexBuffer, // ( IBO : 인덱스 정보 )
position : new Float32Array( [ 0, 0, 0 ] ),
rotation : new Float32Array( [ 0, 0, 0 ] ),
scale : new Float32Array( [ 1, 1, 1 ] )
}
return result
}
HOW TO…
var children = []
function render() {
// .. 생략
var i = children.length
var tObject, tProgram, tVBO, tIBO
while (i--) {
tObject = children[i]
tProgram = tObject.program, tVBO = tObject.vbo, tIBO = tObject.ibo
gl.useProgram(tProgram),
gl.bindBuffer(gl.ARRAY_BUFFER, tVBO);
gl.enableVertexAttribArray(tProgram.aVertexPosition);
gl.vertexAttribPointer(tProgram.aVertexPosition, tVBO.itemSize, gl.FLOAT, false, 0, 0);
gl.uniform3fv(tProgram.uRotation,tObject.rotation)
gl.uniform3fv(tProgram.uPosition,tObject.position)
gl.uniform3fv(tProgram.uScale,tObject.scale)
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, tIBO)
gl.drawElements(gl.TRIANGLES, tIBO.numItem, gl.UNSIGNED_SHORT, 0);
}
}
Render Update
for (var i = 0; i < 1000; i++) {
var item = new Mesh()
item.position[0] = Math.random() - 0.5 // X
item.position[1] = Math.random() - 0.5 // Y
// Z는 아직 사용 못합니다!
item.scale[0] =
item.scale[1] =
item.scale[2] = Math.random()/5
children.push(item)
}
Host Code
Result
http://ligo.kr/k87
베어링(varying) Vertex Shader에서 Fragment Shader로 전달되는 변수
Vertex
Shader Fragment Shader
시스템 적 전달
특정 연산결과 의사적 전달 특정 연산결과 반영
varying
베어링(varying) Vertex Shader에서 Fragment Shader로 전달되는 변수
"uniform vec3 uColor;" +
"varying vec3 vColor;" +
.. 생략
"void main(void) {" +
" gl_Position = " +
" positionMTX(uPosition) * " +
" rotationMTX(uRotation) * " +
" vec4(aVertexPosition, 1.0);" +
“vColor = uColor;" +
"}"
Vertex Shader
베어링(varying) Vertex Shader에서 Fragment Shader로 전달되는 변수
"precision mediump float;" +
"varying vec3 vColor;" + // vertex Shader와 반드시 동일하게 선언
"void main(void) {" +
" gl_FragColor = vec4(vColor, 1.0);" +
//" gl_FragColor = vec4(vColor[0], vColor[1], vColor[2], 1.0);" +
"}"
Fragment Shader
Result
http://ligo.kr/eqy
DrawCall
활성화된 Buffer를 그리는 명령
프레임당 1000번 정도가 한계!
DrawCall 줄이자!
DrawCall 감소의 결과
1000개(1000콜)  12만개(1콜)
모바일 (1만개이상)
http://ligo.kr/gn3
모든 물체는 삼각형의 조합
하나의 버퍼에
삼각형 조합을 모두 입력!
1. 모든 정보를 1개의 버퍼에 입력하는 방법
2. 유동 버퍼와 고정 버퍼를 나눠서 입력하는 방법
3. 유동버퍼를 세분화 하는 방법
HOW TO…
Local Vertex
position
Position,
Color,
Rotation,
..
.
Local Vertex position
Position,
Color,
Rotation,
..
.
Local Vertex position
Position
Rotation
Etc….
Think - 모든 정보를 1개의 버퍼에 입력하는 방법
1개의 정점정보 관리만 잘하면 된다
정점 1개의 변화에 대한 성능적 손실이 크다.
maxVertexAttri 제한 (정점별 정보입력수)
장
단
gl.getParameter(gl.MAX_VERTEX_ATTRIBS)
1개의 정점 구성
Local Vertex position
Position,
Color,
Rotation,
..
.
Think - 유동 버퍼와 고정 버퍼를 나눠서 입력하는 방법
정점 1개의 변화에 대한 손실이 적다.
maxVertexAttri 제한을 피할 수 있다.
관리 복잡성이 증가.
장
단
1개의 정점 구성
Local Vertex position
Position,
Color,
Rotation,
...
고정버퍼 유동버
퍼
CPU 연산비용 소비
Think - 유동버퍼를 세분화 하는 방법
정점 1개의 변화에 대한 손실이 적다.
maxVertexAttri 제한을 피할 수 있다.
관리 복잡성이 더더더더더 증가.
장
단
1개의 정점 구성
Local Vertex position
Position
Rotation
Etc….
CPU 연산비용 개별적 소비
HOW TO... 생성된 메쉬 정보를 병합한다!
고정 Buffer
var rectData = [
-.5, -.5, 0.0,
-.5, .5, 0.0,
.5, -.5, 0.0,
.5, .5, 0.0
]
var rectData = [
-.5, -.5, 0.0,
-.5, .5, 0.0,
.5, -.5, 0.0,
.5, .5, 0.0
]
var rectData = [
-.5, -.5, 0.0,
-.5, .5, 0.0,
.5, -.5, 0.0,
.5, .5, 0.0
]+ +
var mergedData = [
…………
]
HOW TO... 생성된 메쉬 정보를 병합한다!
function mergeMesh($list) {
var item, i, len = $list.length, tempVBO = [], tempIBO = []
for (i = 0; i < len; i++) {
item = $list[i]
tempVBO.push(rectData[0], rectData[1], rectData[2])
tempVBO.push(rectData[3], rectData[4], rectData[5])
tempVBO.push(rectData[6], rectData[7], rectData[8])
tempVBO.push(rectData[9], rectData[10], rectData[11])
tempIBO.push(
i * 4 + 0, i * 4 + 1, i * 4 + 2, // 사각형의 첫번째 삼각형
I * 4 + 1, I * 4 + 2, I * 4 + 3 // 사각형의 두번째 삼각형
)
}
}
Vertex 1
Vertex 2
Vertex 3
Vertex 4
HOW TO... 생성된 메쉬 정보를 병합한다!
function mergeMesh($list) {varitem, i, len = $list.length, tempVBO = [], tempIBO = []
for (i = 0; i < len; i++){
item = $list[i]
tempVBO.push(rectData[0], rectData[1], rectData[2])
tempVBO.push(rectData[3], rectData[4], rectData[5])
tempVBO.push(rectData[6], rectData[7], rectData[8])
tempVBO.push(rectData[9], rectData[10], rectData[11])
tempIBO.push(
i * 4 + 0, i * 4 + 1, i * 4 + 2, // 사각형의 첫번째 삼각형
I * 4 + 1, I * 4 + 2, I * 4 + 3 // 사각형의 두번째 삼각형
)
}
var vboBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, vboBuffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tempVBO), gl.STATIC_DRAW)
vboBuffer.itemSize = 3, vboBuffer.numItem = 4 * len
var indexBuffer = gl.createBuffer()
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(tempIBO), gl.STATIC_DRAW)
indexBuffer.itemSize = 1, indexBuffer.numItem = 6 * len
}
HOW TO... 생성된 메쉬 정보를 병합한다!
유동 Property Buffer
하나의 지오메트리를 구성하는 버텍스는
모두 같은 Property를 가진다.
var mesh = {
position : [ 0, 0, 0 ],
rotation : [ 0, 0, 0 ].
scale : [ 1, 1, 1 ]
}
Geometry
mesh.position
mesh.position
mesh.position
HOW TO... 생성된 메쉬 정보를 병합한다!
유동 Property Buffer
function mergeMesh($list) {
.. 생략
tempPositionBO.push(item.position[0], item.position[1], 0)
tempPositionBO.push(item.position[0], item.position[1], 0)
tempPositionBO.push(item.position[0], item.position[1], 0)
tempPositionBO.push(item.position[0], item.position[1], 0)
}
var positionBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tempPositionBO), gl.DYNAMIC_DRAW)
positionBuffer.itemSize = 3
positionBuffer.numItem = 4 * len
HOW TO... 생성된 메쉬 정보를 병합한다!
메쉬 병합 결과
var result = {}
result.vbo = vboBuffer
result.ibo = indexBuffer
result.rotationBo = rotationBuffer
result.positionBo = positionBuffer
result.scaleBo = scaleBuffer
result.colorBo = colorBuffer
고정 버퍼
유동버퍼
반 고정 버퍼
Shader Update
유니폼 기반에서 버퍼 기반으로 변경
"attribute vec3 aVertexPosition;" +
"attribute vec3 aRotation;" +
"attribute vec3 aPosition;" +
"attribute vec3 aScale;" +
"attribute vec3 aColor;" +
"varying vec3 vColor;" +
"attribute vec3 aVertexPosition;" +
"uniform vec3 uRotation;" +
"uniform vec3 uPosition;" +
"uniform vec3 uScale;" +
"uniform vec3 uColor;" +
"varying vec3 vColor;" +
Shader Update
유니폼 기반에서 버퍼 기반으로 변경
"void main(void) {" +
" gl_Position = " +
" positionMTX(aPosition) * " +
"rotationMTX(aRotation) * " +
"scaleMTX(aScale) * " +
"vec4(aVertexPosition, 1.0);" +
'vColor = aColor;' +
"}"
"void main(void) {" +
" gl_Position = " +
"positionMTX(uPosition) * " +
"rotationMTX(uRotation) * " +
"scaleMTX(uScale) * " +
"vec4(aVertexPosition, 1.0);" +
"vColor = uColor;" +
"}"
Program Location Update
유니폼 기반에서 버퍼 기반으로 변경
colorProgram.aVertexPosition = gl.getAttribLocation(colorProgram, "aVertexPosition");
colorProgram.aRotation = gl.getAttribLocation(colorProgram, "aRotation");
colorProgram.aPosition = gl.getAttribLocation(colorProgram, "aPosition");
colorProgram.aScale = gl.getAttribLocation(colorProgram, "aScale");
colorProgram.aColor = gl.getAttribLocation(colorProgram, "aColor");
Render Update
gl.useProgram(tProgram)
gl.bindBuffer(gl.ARRAY_BUFFER, tObject.vbo);
gl.vertexAttribPointer(tProgram.aVertexPosition, tObject.vbo.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, tObject.rotationBo);
gl.vertexAttribPointer(tProgram.aRotation, tObject.rotationBo.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, tObject.positionBo);
gl.vertexAttribPointer(tProgram.aPosition, tObject.positionBo.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, tObject.scaleBo);
gl.vertexAttribPointer(tProgram.aScale, tObject.scaleBo.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, tObject.colorBo);
gl.vertexAttribPointer(tProgram.aColor, tObject.colorBo.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, tIBO)
gl.drawElements(gl.TRIANGLES, tIBO.numItem, gl.UNSIGNED_SHORT, 0);
Render Update – 유동 버퍼 데이터 갱신
gl.bindBuffer(gl.ARRAY_BUFFER, tObject.rotationBo)
var temp= tObject.rotationBo.data
for (var k = 0, len = temp.length / 12; k < len; k++) {
var gap = 0.01
var start = k * 12
temp[start] += gap, temp[start + 1] += gap, temp[start + 2] += gap
temp[start + 3] += gap, temp[start + 4] += gap, temp[start + 5] += gap
temp[start + 6] += gap, temp[start + 7] += gap, temp[start + 8] += gap
temp[start + 9] += gap, temp[start + 10] += gap, temp[start + 11] += gap
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(temp), gl.DYNAMIC_DRAW)
Result
http://ligo.kr/hx9
음 정말로 12만개가 그려지는가!!!!
gl.drawElements(gl.TRIANGLES, tIBO.numItem, gl.UNSIGNED_SHORT, 0)
gl.UNSIGNED_SHORT – 0~ 65,535
그런데 범위 이상 그려지는 것 같다 -_-? 느낌….
연구대상...
그려지지 않는다면 65k 수준에서 2콜로 분기하는 걸 연구 해야함……..
세번째 시간에는..
엔진화를 하려면 뭘 해야 하나…
1. webGL 초기화
2. 버텍스 버퍼 제너레이터/매니저
3. 인덱스 버퍼 제너레이터/매니저
4. Mesh 객체 생성
5. Child 관리
6. 객체별 렌더러
7. 병합메쉬 렌더러
유니폼 배열을 이용해 보자!
또 다른 무언가......
End
www.Bswebgl.com – 런치프로젝트 webGL
https://github.com/projectBS/webGL
https://www.facebook.com/groups/bs5js/

More Related Content

What's hot

[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅NAVER D2
 
[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍NAVER D2
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSCirculus
 
제 5회 Lisp 세미나 - 클로저 개발팀을 위한 지속적인 통합
제 5회 Lisp 세미나 - 클로저 개발팀을 위한 지속적인 통합제 5회 Lisp 세미나 - 클로저 개발팀을 위한 지속적인 통합
제 5회 Lisp 세미나 - 클로저 개발팀을 위한 지속적인 통합NAVER D2
 
ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!WooYoung Cho
 
Angular2 router&http
Angular2 router&httpAngular2 router&http
Angular2 router&httpDong Jun Kwon
 
Secrets of the JavaScript Ninja - Chapter 12. DOM modification
Secrets of the JavaScript Ninja - Chapter 12. DOM modificationSecrets of the JavaScript Ninja - Chapter 12. DOM modification
Secrets of the JavaScript Ninja - Chapter 12. DOM modificationHyuncheol Jeon
 
7주 JavaScript Part2
7주 JavaScript Part27주 JavaScript Part2
7주 JavaScript Part2지수 윤
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs기동 이
 
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로Jaeseung Ha
 
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)주영 송
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crowJaeseung Ha
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기jongho jeong
 
c++ opencv tutorial
c++ opencv tutorialc++ opencv tutorial
c++ opencv tutorialTaeKang Woo
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple OverviewKim Hunmin
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?NAVER D2
 
Node.js 현재와 미래
Node.js 현재와 미래Node.js 현재와 미래
Node.js 현재와 미래JeongHun Byeon
 
Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신Circulus
 

What's hot (20)

[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅[D2 오픈세미나]5.robolectric 안드로이드 테스팅
[D2 오픈세미나]5.robolectric 안드로이드 테스팅
 
[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍
 
What is the meteor?
What is the meteor?What is the meteor?
What is the meteor?
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JS
 
제 5회 Lisp 세미나 - 클로저 개발팀을 위한 지속적인 통합
제 5회 Lisp 세미나 - 클로저 개발팀을 위한 지속적인 통합제 5회 Lisp 세미나 - 클로저 개발팀을 위한 지속적인 통합
제 5회 Lisp 세미나 - 클로저 개발팀을 위한 지속적인 통합
 
ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!ECMAScript 6의 새로운 것들!
ECMAScript 6의 새로운 것들!
 
Angular2 router&http
Angular2 router&httpAngular2 router&http
Angular2 router&http
 
Secrets of the JavaScript Ninja - Chapter 12. DOM modification
Secrets of the JavaScript Ninja - Chapter 12. DOM modificationSecrets of the JavaScript Ninja - Chapter 12. DOM modification
Secrets of the JavaScript Ninja - Chapter 12. DOM modification
 
Node.js at OKJSP
Node.js at OKJSPNode.js at OKJSP
Node.js at OKJSP
 
7주 JavaScript Part2
7주 JavaScript Part27주 JavaScript Part2
7주 JavaScript Part2
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
 
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
 
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기
 
c++ opencv tutorial
c++ opencv tutorialc++ opencv tutorial
c++ opencv tutorial
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple Overview
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
Node.js 현재와 미래
Node.js 현재와 미래Node.js 현재와 미래
Node.js 현재와 미래
 
Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신
 

Viewers also liked

[1A3]지금까지 상상한 표현의 한계를 넘자 WebGL
[1A3]지금까지 상상한 표현의 한계를 넘자 WebGL[1A3]지금까지 상상한 표현의 한계를 넘자 WebGL
[1A3]지금까지 상상한 표현의 한계를 넘자 WebGLNAVER D2
 
Bs webgl소모임004
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004Seonki Paik
 
ELD12: Badge Design
ELD12: Badge DesignELD12: Badge Design
ELD12: Badge Designhalavais
 
개발자여! 스터디를 하자!
개발자여! 스터디를 하자!개발자여! 스터디를 하자!
개발자여! 스터디를 하자!changehee lee
 
The Power of WebGL - Hackeando sua GPU com JavaScript
The Power of WebGL - Hackeando sua GPU com JavaScriptThe Power of WebGL - Hackeando sua GPU com JavaScript
The Power of WebGL - Hackeando sua GPU com JavaScriptRaphael Amorim
 
쉽게 풀어보는 WebGL
쉽게 풀어보는 WebGL쉽게 풀어보는 WebGL
쉽게 풀어보는 WebGLMyung Woon Oh
 
WebGL: GPU acceleration for the open web
WebGL: GPU acceleration for the open webWebGL: GPU acceleration for the open web
WebGL: GPU acceleration for the open webpjcozzi
 
[9xD] 개발자, 스터디로 성장하기
[9xD] 개발자, 스터디로 성장하기[9xD] 개발자, 스터디로 성장하기
[9xD] 개발자, 스터디로 성장하기한재 제
 
WebGL: The Next Generation
WebGL:  The Next GenerationWebGL:  The Next Generation
WebGL: The Next GenerationTony Parisi
 

Viewers also liked (9)

[1A3]지금까지 상상한 표현의 한계를 넘자 WebGL
[1A3]지금까지 상상한 표현의 한계를 넘자 WebGL[1A3]지금까지 상상한 표현의 한계를 넘자 WebGL
[1A3]지금까지 상상한 표현의 한계를 넘자 WebGL
 
Bs webgl소모임004
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004
 
ELD12: Badge Design
ELD12: Badge DesignELD12: Badge Design
ELD12: Badge Design
 
개발자여! 스터디를 하자!
개발자여! 스터디를 하자!개발자여! 스터디를 하자!
개발자여! 스터디를 하자!
 
The Power of WebGL - Hackeando sua GPU com JavaScript
The Power of WebGL - Hackeando sua GPU com JavaScriptThe Power of WebGL - Hackeando sua GPU com JavaScript
The Power of WebGL - Hackeando sua GPU com JavaScript
 
쉽게 풀어보는 WebGL
쉽게 풀어보는 WebGL쉽게 풀어보는 WebGL
쉽게 풀어보는 WebGL
 
WebGL: GPU acceleration for the open web
WebGL: GPU acceleration for the open webWebGL: GPU acceleration for the open web
WebGL: GPU acceleration for the open web
 
[9xD] 개발자, 스터디로 성장하기
[9xD] 개발자, 스터디로 성장하기[9xD] 개발자, 스터디로 성장하기
[9xD] 개발자, 스터디로 성장하기
 
WebGL: The Next Generation
WebGL:  The Next GenerationWebGL:  The Next Generation
WebGL: The Next Generation
 

Similar to Bs webgl소모임002

3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택JinTaek Seo
 
Implements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture ArrayImplements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture ArrayYEONG-CHEON YOU
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
R 스터디 첫번째
R 스터디 첫번째R 스터디 첫번째
R 스터디 첫번째Jaeseok Park
 
불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 명신 김
 
Higher order procedure2 with conventional interface
Higher order procedure2 with conventional interface Higher order procedure2 with conventional interface
Higher order procedure2 with conventional interface fromitive
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기Jongwook Choi
 
R 스터디 두번째
R 스터디 두번째R 스터디 두번째
R 스터디 두번째Jaeseok Park
 
5-4. html5 offline and storage
5-4. html5 offline and storage5-4. html5 offline and storage
5-4. html5 offline and storageJinKyoungHeo
 
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌Seok-joon Yun
 
공간데이터베이스(Spatial db)
공간데이터베이스(Spatial db)공간데이터베이스(Spatial db)
공간데이터베이스(Spatial db)H.J. SIM
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리ETRIBE_STG
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍Young-Beom Rhee
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀beom kyun choi
 
ECMA Script 5 & 6
ECMA Script 5 & 6ECMA Script 5 & 6
ECMA Script 5 & 6sewoo lee
 
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)Circulus
 
Day by day iPhone Programming
Day by day iPhone ProgrammingDay by day iPhone Programming
Day by day iPhone ProgrammingYoung Oh Jeong
 

Similar to Bs webgl소모임002 (20)

Nexacro
NexacroNexacro
Nexacro
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택
 
Implements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture ArrayImplements Cascaded Shadow Maps with using Texture Array
Implements Cascaded Shadow Maps with using Texture Array
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
R 스터디 첫번째
R 스터디 첫번째R 스터디 첫번째
R 스터디 첫번째
 
D2 Rain (2/2)
D2 Rain (2/2)D2 Rain (2/2)
D2 Rain (2/2)
 
불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14
 
Higher order procedure2 with conventional interface
Higher order procedure2 with conventional interface Higher order procedure2 with conventional interface
Higher order procedure2 with conventional interface
 
프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기
 
R 스터디 두번째
R 스터디 두번째R 스터디 두번째
R 스터디 두번째
 
5-4. html5 offline and storage
5-4. html5 offline and storage5-4. html5 offline and storage
5-4. html5 offline and storage
 
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌[C++ Korea] Effective Modern C++ Study item14 16 +신촌
[C++ Korea] Effective Modern C++ Study item14 16 +신촌
 
4. stack
4. stack4. stack
4. stack
 
공간데이터베이스(Spatial db)
공간데이터베이스(Spatial db)공간데이터베이스(Spatial db)
공간데이터베이스(Spatial db)
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
 
Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀Tensorflow regression 텐서플로우 회귀
Tensorflow regression 텐서플로우 회귀
 
ECMA Script 5 & 6
ECMA Script 5 & 6ECMA Script 5 & 6
ECMA Script 5 & 6
 
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
 
Day by day iPhone Programming
Day by day iPhone ProgrammingDay by day iPhone Programming
Day by day iPhone Programming
 

Bs webgl소모임002

  • 3. var rectData = [ -.5, -.5, 0.0, -.5, .5, 0.0, .5, -.5, 0.0, -.5, .5, 0.0, .5, -.5, 0.0, .5, .5, 0.0 ] rectBuffer.itemSize = 3 rectBuffer.numItem = 6 2개의 삼각형 정의 1
  • 4. var rectData = [ -.5, -.5, 0.0, -.5, .5, 0.0, .5, -.5, 0.0, .5, .5, 0.0 ] rectBuffer.itemSize = 3 rectBuffer.numItem = 4 2개의 삼각형 정의 2
  • 6. var rectIndexData = [ 0,1,2, 1,2,3 ] var rectIndexBuffer = gl.createBuffer() gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, rectIndexBuffer) gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(rectIndexData), gl.STATIC_DRAW ) rectIndexBuffer.itemSize = 1 rectIndexBuffer.numItem = 6 HOW TO..
  • 7. //gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer); … // gl.drawArrays(gl.TRIANGLES, 0, rectBuffer.numItem); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, rectIndexBuffer) gl.drawElements(gl.TRIANGLES, rectIndexBuffer.numItem, gl.UNSIGNED_SHORT, 0); Render Update
  • 10. 구조체를 만들어보자 렌더링에 필요한 것은? 1. 프로그램 2. 버텍스 버퍼 (VBO : 지오메트리 정보) 3. 인덱스 버퍼 (IBO : 인덱스 정보) 4. Position 5. Rotation 6. 앞으로 필요한 어떤 것들…
  • 11. function Mesh() { var result = { program : firstProgram, vbo : rectBuffer, // ( VBO : 지오메트리 정보 ) ibo : rectIndexBuffer, // ( IBO : 인덱스 정보 ) position : new Float32Array( [ 0, 0, 0 ] ), rotation : new Float32Array( [ 0, 0, 0 ] ), scale : new Float32Array( [ 1, 1, 1 ] ) } return result } HOW TO…
  • 12. var children = [] function render() { // .. 생략 var i = children.length var tObject, tProgram, tVBO, tIBO while (i--) { tObject = children[i] tProgram = tObject.program, tVBO = tObject.vbo, tIBO = tObject.ibo gl.useProgram(tProgram), gl.bindBuffer(gl.ARRAY_BUFFER, tVBO); gl.enableVertexAttribArray(tProgram.aVertexPosition); gl.vertexAttribPointer(tProgram.aVertexPosition, tVBO.itemSize, gl.FLOAT, false, 0, 0); gl.uniform3fv(tProgram.uRotation,tObject.rotation) gl.uniform3fv(tProgram.uPosition,tObject.position) gl.uniform3fv(tProgram.uScale,tObject.scale) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, tIBO) gl.drawElements(gl.TRIANGLES, tIBO.numItem, gl.UNSIGNED_SHORT, 0); } } Render Update
  • 13. for (var i = 0; i < 1000; i++) { var item = new Mesh() item.position[0] = Math.random() - 0.5 // X item.position[1] = Math.random() - 0.5 // Y // Z는 아직 사용 못합니다! item.scale[0] = item.scale[1] = item.scale[2] = Math.random()/5 children.push(item) } Host Code
  • 15. 베어링(varying) Vertex Shader에서 Fragment Shader로 전달되는 변수 Vertex Shader Fragment Shader 시스템 적 전달 특정 연산결과 의사적 전달 특정 연산결과 반영 varying
  • 16. 베어링(varying) Vertex Shader에서 Fragment Shader로 전달되는 변수 "uniform vec3 uColor;" + "varying vec3 vColor;" + .. 생략 "void main(void) {" + " gl_Position = " + " positionMTX(uPosition) * " + " rotationMTX(uRotation) * " + " vec4(aVertexPosition, 1.0);" + “vColor = uColor;" + "}" Vertex Shader
  • 17. 베어링(varying) Vertex Shader에서 Fragment Shader로 전달되는 변수 "precision mediump float;" + "varying vec3 vColor;" + // vertex Shader와 반드시 동일하게 선언 "void main(void) {" + " gl_FragColor = vec4(vColor, 1.0);" + //" gl_FragColor = vec4(vColor[0], vColor[1], vColor[2], 1.0);" + "}" Fragment Shader
  • 19. DrawCall 활성화된 Buffer를 그리는 명령 프레임당 1000번 정도가 한계! DrawCall 줄이자!
  • 20. DrawCall 감소의 결과 1000개(1000콜)  12만개(1콜) 모바일 (1만개이상) http://ligo.kr/gn3
  • 21. 모든 물체는 삼각형의 조합 하나의 버퍼에 삼각형 조합을 모두 입력!
  • 22. 1. 모든 정보를 1개의 버퍼에 입력하는 방법 2. 유동 버퍼와 고정 버퍼를 나눠서 입력하는 방법 3. 유동버퍼를 세분화 하는 방법 HOW TO… Local Vertex position Position, Color, Rotation, .. . Local Vertex position Position, Color, Rotation, .. . Local Vertex position Position Rotation Etc….
  • 23. Think - 모든 정보를 1개의 버퍼에 입력하는 방법 1개의 정점정보 관리만 잘하면 된다 정점 1개의 변화에 대한 성능적 손실이 크다. maxVertexAttri 제한 (정점별 정보입력수) 장 단 gl.getParameter(gl.MAX_VERTEX_ATTRIBS) 1개의 정점 구성 Local Vertex position Position, Color, Rotation, .. .
  • 24. Think - 유동 버퍼와 고정 버퍼를 나눠서 입력하는 방법 정점 1개의 변화에 대한 손실이 적다. maxVertexAttri 제한을 피할 수 있다. 관리 복잡성이 증가. 장 단 1개의 정점 구성 Local Vertex position Position, Color, Rotation, ... 고정버퍼 유동버 퍼 CPU 연산비용 소비
  • 25. Think - 유동버퍼를 세분화 하는 방법 정점 1개의 변화에 대한 손실이 적다. maxVertexAttri 제한을 피할 수 있다. 관리 복잡성이 더더더더더 증가. 장 단 1개의 정점 구성 Local Vertex position Position Rotation Etc…. CPU 연산비용 개별적 소비
  • 26. HOW TO... 생성된 메쉬 정보를 병합한다! 고정 Buffer var rectData = [ -.5, -.5, 0.0, -.5, .5, 0.0, .5, -.5, 0.0, .5, .5, 0.0 ] var rectData = [ -.5, -.5, 0.0, -.5, .5, 0.0, .5, -.5, 0.0, .5, .5, 0.0 ] var rectData = [ -.5, -.5, 0.0, -.5, .5, 0.0, .5, -.5, 0.0, .5, .5, 0.0 ]+ + var mergedData = [ ………… ]
  • 27. HOW TO... 생성된 메쉬 정보를 병합한다! function mergeMesh($list) { var item, i, len = $list.length, tempVBO = [], tempIBO = [] for (i = 0; i < len; i++) { item = $list[i] tempVBO.push(rectData[0], rectData[1], rectData[2]) tempVBO.push(rectData[3], rectData[4], rectData[5]) tempVBO.push(rectData[6], rectData[7], rectData[8]) tempVBO.push(rectData[9], rectData[10], rectData[11]) tempIBO.push( i * 4 + 0, i * 4 + 1, i * 4 + 2, // 사각형의 첫번째 삼각형 I * 4 + 1, I * 4 + 2, I * 4 + 3 // 사각형의 두번째 삼각형 ) } } Vertex 1 Vertex 2 Vertex 3 Vertex 4
  • 28. HOW TO... 생성된 메쉬 정보를 병합한다! function mergeMesh($list) {varitem, i, len = $list.length, tempVBO = [], tempIBO = [] for (i = 0; i < len; i++){ item = $list[i] tempVBO.push(rectData[0], rectData[1], rectData[2]) tempVBO.push(rectData[3], rectData[4], rectData[5]) tempVBO.push(rectData[6], rectData[7], rectData[8]) tempVBO.push(rectData[9], rectData[10], rectData[11]) tempIBO.push( i * 4 + 0, i * 4 + 1, i * 4 + 2, // 사각형의 첫번째 삼각형 I * 4 + 1, I * 4 + 2, I * 4 + 3 // 사각형의 두번째 삼각형 ) } var vboBuffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, vboBuffer) gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tempVBO), gl.STATIC_DRAW) vboBuffer.itemSize = 3, vboBuffer.numItem = 4 * len var indexBuffer = gl.createBuffer() gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer) gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(tempIBO), gl.STATIC_DRAW) indexBuffer.itemSize = 1, indexBuffer.numItem = 6 * len }
  • 29. HOW TO... 생성된 메쉬 정보를 병합한다! 유동 Property Buffer 하나의 지오메트리를 구성하는 버텍스는 모두 같은 Property를 가진다. var mesh = { position : [ 0, 0, 0 ], rotation : [ 0, 0, 0 ]. scale : [ 1, 1, 1 ] } Geometry mesh.position mesh.position mesh.position
  • 30. HOW TO... 생성된 메쉬 정보를 병합한다! 유동 Property Buffer function mergeMesh($list) { .. 생략 tempPositionBO.push(item.position[0], item.position[1], 0) tempPositionBO.push(item.position[0], item.position[1], 0) tempPositionBO.push(item.position[0], item.position[1], 0) tempPositionBO.push(item.position[0], item.position[1], 0) } var positionBuffer = gl.createBuffer() gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer) gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(tempPositionBO), gl.DYNAMIC_DRAW) positionBuffer.itemSize = 3 positionBuffer.numItem = 4 * len
  • 31. HOW TO... 생성된 메쉬 정보를 병합한다! 메쉬 병합 결과 var result = {} result.vbo = vboBuffer result.ibo = indexBuffer result.rotationBo = rotationBuffer result.positionBo = positionBuffer result.scaleBo = scaleBuffer result.colorBo = colorBuffer 고정 버퍼 유동버퍼 반 고정 버퍼
  • 32. Shader Update 유니폼 기반에서 버퍼 기반으로 변경 "attribute vec3 aVertexPosition;" + "attribute vec3 aRotation;" + "attribute vec3 aPosition;" + "attribute vec3 aScale;" + "attribute vec3 aColor;" + "varying vec3 vColor;" + "attribute vec3 aVertexPosition;" + "uniform vec3 uRotation;" + "uniform vec3 uPosition;" + "uniform vec3 uScale;" + "uniform vec3 uColor;" + "varying vec3 vColor;" +
  • 33. Shader Update 유니폼 기반에서 버퍼 기반으로 변경 "void main(void) {" + " gl_Position = " + " positionMTX(aPosition) * " + "rotationMTX(aRotation) * " + "scaleMTX(aScale) * " + "vec4(aVertexPosition, 1.0);" + 'vColor = aColor;' + "}" "void main(void) {" + " gl_Position = " + "positionMTX(uPosition) * " + "rotationMTX(uRotation) * " + "scaleMTX(uScale) * " + "vec4(aVertexPosition, 1.0);" + "vColor = uColor;" + "}"
  • 34. Program Location Update 유니폼 기반에서 버퍼 기반으로 변경 colorProgram.aVertexPosition = gl.getAttribLocation(colorProgram, "aVertexPosition"); colorProgram.aRotation = gl.getAttribLocation(colorProgram, "aRotation"); colorProgram.aPosition = gl.getAttribLocation(colorProgram, "aPosition"); colorProgram.aScale = gl.getAttribLocation(colorProgram, "aScale"); colorProgram.aColor = gl.getAttribLocation(colorProgram, "aColor");
  • 35. Render Update gl.useProgram(tProgram) gl.bindBuffer(gl.ARRAY_BUFFER, tObject.vbo); gl.vertexAttribPointer(tProgram.aVertexPosition, tObject.vbo.itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, tObject.rotationBo); gl.vertexAttribPointer(tProgram.aRotation, tObject.rotationBo.itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, tObject.positionBo); gl.vertexAttribPointer(tProgram.aPosition, tObject.positionBo.itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, tObject.scaleBo); gl.vertexAttribPointer(tProgram.aScale, tObject.scaleBo.itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, tObject.colorBo); gl.vertexAttribPointer(tProgram.aColor, tObject.colorBo.itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, tIBO) gl.drawElements(gl.TRIANGLES, tIBO.numItem, gl.UNSIGNED_SHORT, 0);
  • 36. Render Update – 유동 버퍼 데이터 갱신 gl.bindBuffer(gl.ARRAY_BUFFER, tObject.rotationBo) var temp= tObject.rotationBo.data for (var k = 0, len = temp.length / 12; k < len; k++) { var gap = 0.01 var start = k * 12 temp[start] += gap, temp[start + 1] += gap, temp[start + 2] += gap temp[start + 3] += gap, temp[start + 4] += gap, temp[start + 5] += gap temp[start + 6] += gap, temp[start + 7] += gap, temp[start + 8] += gap temp[start + 9] += gap, temp[start + 10] += gap, temp[start + 11] += gap } gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(temp), gl.DYNAMIC_DRAW)
  • 38. 음 정말로 12만개가 그려지는가!!!! gl.drawElements(gl.TRIANGLES, tIBO.numItem, gl.UNSIGNED_SHORT, 0) gl.UNSIGNED_SHORT – 0~ 65,535 그런데 범위 이상 그려지는 것 같다 -_-? 느낌…. 연구대상... 그려지지 않는다면 65k 수준에서 2콜로 분기하는 걸 연구 해야함……..
  • 39. 세번째 시간에는.. 엔진화를 하려면 뭘 해야 하나… 1. webGL 초기화 2. 버텍스 버퍼 제너레이터/매니저 3. 인덱스 버퍼 제너레이터/매니저 4. Mesh 객체 생성 5. Child 관리 6. 객체별 렌더러 7. 병합메쉬 렌더러 유니폼 배열을 이용해 보자! 또 다른 무언가......
  • 40. End www.Bswebgl.com – 런치프로젝트 webGL https://github.com/projectBS/webGL https://www.facebook.com/groups/bs5js/

Editor's Notes

  1. Gl.TRIANGLES 만 이용한다고 했을떄.. 삼각형에서 사각형을 그려면 어떻게? 정점을 6개 정의 하면되지!
  2. 삼각형을 그릴때 마다 정점 3개가 추가되어야 하는가? 사각형은 정점 4개만 있으면되는데 6개를 정의해야하는가 -_-;;;
  3. 삼각형을 그릴때 마다 정점 3개가 추가되어야 하는가? 사각형은 정점 4개만 있으면되는데 6개를 정의해야하는가 -_-;;; 정점을 4개만 입력하고 삼각형을 어떻게 그릴건가에 대한 고민으로 전환  메모리 사용량과 엑세스 비용이 줄어든다!
  4. gl.enableVertexAttribArray(tProgram.aVertexPosition) 설정비용도 비싸므로.. 널버퍼 사용에 대해서 ….이야기..