Skip to content
Snippets Groups Projects
Commit 8c76d8a9 authored by 201221016Kim Haeram's avatar 201221016Kim Haeram
Browse files

final confirm

parent 058ff06d
Branches
No related tags found
No related merge requests found
README.md 0 → 100644
# WebGL Transform Tutorial
WebGL에서 transform을 이용할 때 좌표계가 어떻게 변화하는지 확인할 수 있는 예제입니다.
![](./blob/ss.png)
(CC-NC-BY) Haeram Kim 2019
### Features
- Three transform functions: translate, rotate, scale
- View matrix setting
- Logging transforms and model matrix
- Reset cube position and logs
- Some animation for fun
### APIs
- WebGL: version 1.0
- [gl-matrix: version 3.0.0](<https://github.com/toji/gl-matrix/tree/master/dist>)
## Structure Details
### Vertexes
- Vertex Attribute: 3 attributes(총 9차원):
XYZ coordinates(3), RGBA(4), Texture XY coordinates(2)
- 총 72개 vertex 사용:
XYZ plane(3 planes * 4 vertexes), arrows(6 arrows * 6 vertexes), cube(6 planes * 4 vertexes)
- array structure [here](./vertex.js)
### Texture
![](./blob/grid.png)
- 64px * 64px png file, 좌/하단 1px굵기의 검은 직선 외에 투명
- XYZ plane에만 사용되어, 32번 반복해 격자 무늬를 만듬
- [Base64 Image Encoder](<https://www.base64-image.de/>)로 png파일을 base64로 encode해 html파일 내에 hard coding
```
const GRID = "data:image/png;base64,/*...*/"
```
- 기타 image loading, mipmapping 처리 과정 등은 4차 과제 제출물 [facecube/WebGLHelloAPI.js](<http://git.ajou.ac.kr/ajouramram/facecube>)와 같습니다.
### View matrix
- gl-matrix.mat4.lookAt() function 사용
```js
var view_eye = [5,5,5];
// ...in function renderScene()
mat4.lookAt(view_matrix,view_eye,[0,0,0],[0,0,-1]);
```
- WebGL의 view matrix 기본값은 `view_eye=[0,0,0]`이고 `up=[0,1,0]`이지만,
view_eye는 HTML input element를 이용해 조정하도록 하였고
익숙한 xyz좌표계와 비슷한 시점을 구현하기 위해 `up=[0,0,-1]`으로 설정
```HTML
<--- HTML --->
eye_matrix of View matrix:
<input id="viewX" type="range" min="3" max="7" step="1" value="5">
<input id="viewY" type="range" min="3" max="7" step="1" value="5">
<input id="viewZ" type="range" min="3" max="7" step="1" value="5">
[x,y,z]=[<span id="viewtext">5,5,5</span>]
```
```js
// javascript
var viewX = document.getElementById("viewX");
var viewY = document.getElementById("viewY");
var viewZ = document.getElementById("viewZ");
var viewtext = document.getElementById("viewtext");
viewX.oninput = () => { view_eye[0] = viewX.value; viewtext.innerHTML = view_eye; };
viewY.oninput = () => { view_eye[1] = viewY.value; viewtext.innerHTML = view_eye; };
viewZ.oninput = () => { view_eye[2] = viewZ.value; viewtext.innerHTML = view_eye; };
```
### Model Matrix
- XYZ planes model matrix: 4*4 identity matrix 사용
- Arrows: HTML button element를 이용해 조작된 transform이 적용(상단 snapshot 참고)
transform은 gl-matrix.mat4 library 내의 function을 사용
```HTML
<-- HTML -->
<button onclick="scale(true)">Scale *1.50</button>
<button onclick="scale(false)">Scale *0.67</button><br>
<button class="x" onclick="translateX(0.5)">TranslateX +0.5</button>
<button class="x" onclick="translateX(1.0)">TranslateX +1.0</button>
<button class="y" onclick="translateY(0.5)">TranslateY +0.5</button>
<button class="y" onclick="translateY(1.0)">TranslateY +1.0</button>
<button class="z" onclick="translateZ(0.5)">TranslateZ +0.5</button>
<button class="z" onclick="translateZ(1.0)">TranslateZ +1.0</button><br>
<button class="x" onclick="translateX(-0.5)">TranslateX -0.5</button>
<button class="x" onclick="translateX(-1.0)">TranslateX -1.0</button>
<button class="y" onclick="translateY(-0.5)">TranslateY -0.5</button>
<button class="y" onclick="translateY(-1.0)">TranslateY -1.0</button>
<button class="z" onclick="translateZ(-0.5)">TranslateZ -0.5</button>
<button class="z" onclick="translateZ(-1.0)">TranslateZ -1.0</button><br><button class="x" onclick="rotateX(true)">RotateX +30deg</button>
<button class="y" onclick="rotateY(true)">RotateY +30deg</button>
<button class="z" onclick="rotateZ(true)">RotateZ +30deg</button><br>
<button class="x" onclick="rotateX(false)">RotateX -30deg</button>
<button class="y" onclick="rotateY(false)">RotateY -30deg</button>
<button class="z" onclick="rotateZ(false)">RotateZ -30deg</button><br>
```
```js
// js
var mov_matrix = mat4.create();
const DEG30 = 30*Math.PI/180;
mat4.fromTranslation(mov_matrix,[1,1,1]);
function translateX(d){ mat4.translate(mov_matrix,mov_matrix,[d,0,0]); }
function translateY(d){ mat4.translate(mov_matrix,mov_matrix,[0,d,0]); }
function translateZ(d){ mat4.translate(mov_matrix,mov_matrix,[0,0,d]); }
function rotateX(p){ mat4.rotateX(mov_matrix,mov_matrix,(p? DEG30:-DEG30)); }
function rotateY(p){ mat4.rotateY(mov_matrix,mov_matrix,(p? DEG30:-DEG30)); }
function rotateZ(p){ mat4.rotateZ(mov_matrix,mov_matrix,(p? DEG30:-DEG30)); }
function scale(p){ mat4.scale(mov_matrix,mov_matrix,(p? [1.5,1.5,1.5]:[0.67,0.67,0.67])); }
```
- Cube: arrow와 같은 model matrix에, 박동하는 듯한 animation 효과를 덧씌워 적용
```js
var animstatus = true;
var animvalue = 0;
// ...in function renderScene()
if(animstatus){
var t = 1 + ((Math.cos(animvalue)+1)/2)*0.05;
gl.uniformMatrix4fv(LocMmatrix, gl.FALSE, mat4.scale(mat4.create(),mov_matrix,[t,t,t]));
if (!testGLError("gl.vertexAttribPointer")) { return false; }
animvalue += 0.1;
}
```
### Logging
- Arrow의 model matrix의 특정 값들을 이용해 cube의 center position과 delta를 표시해
transform에 따라 model matrix가 어떻게 계산되는지 확인
- center position:
```js
var pos = [mov_matrix[12],mov_matrix[13],mov_matrix[14]].map(i => i.toFixed(2));
```
- delta:
```js
var dx = [mov_matrix[0],mov_matrix[1],mov_matrix[2]].map(i => i.toFixed(2));
var dy = [mov_matrix[4],mov_matrix[5],mov_matrix[6]].map(i => i.toFixed(2));
var dz = [mov_matrix[8],mov_matrix[9],mov_matrix[10]].map(i => i.toFixed(2));
```
- css를 적용해 transform에 따라 어떤 값이 바뀌었는지 시각적으로 확인시켜줌
### Others
- Fragment/vertex shader codes: [here](./shader.js)
- Depth test: Less than or equal to(LEQUAL) 적용
Stencil, Blending 미적용
- Projection matrix: gl-matrix.mat4.perspective() function 사용
```js
// POV: 180 degree, aspect ratio: 1.0, z-near: 1, z-far: 15
mat4.perspective(proj_matrix,180,1,1,15);
```
- 설명을 위해 첨부한 [vertex.js](./vertex.js)[shader.js](./shader.js)[index.html](./index.html)과 연결되어 있지 않으므로 유의
- 기타 상세 내역은 실제 code([index.html](./index.html)) 참조
\ No newline at end of file
blob/ss.png

453 KiB | W: | H:

blob/ss.png

516 KiB | W: | H:

blob/ss.png
blob/ss.png
blob/ss.png
blob/ss.png
  • 2-up
  • Swipe
  • Onion skin
This diff is collapsed.
var fragmentShaderSource = '\
varying mediump vec4 color; \
varying mediump vec2 texCoord;\
uniform sampler2D sampler2d; \
void main(void) \
{ \
gl_FragColor = color + texture2D(sampler2d, texCoord); \
}';
var vertexShaderSource = '\
attribute highp vec3 myVertex; \
attribute highp vec4 myColor; \
attribute highp vec2 myUV; \
uniform mediump mat4 Pmatrix; \
uniform mediump mat4 Vmatrix; \
uniform mediump mat4 Mmatrix; \
varying mediump vec4 color; \
varying mediump vec2 texCoord;\
void main(void) \
{ \
gl_Position = Pmatrix*Vmatrix*Mmatrix*vec4(myVertex, 1.0);\
color = myColor; \
texCoord = myUV; \
}';
\ No newline at end of file
var vertexData = [
// XYZ plane coordinate: using TRIANGLES_STRIP method
0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5, 0, 0, // x-plane vertex 0
0.0, 0.0, 10.0, 0.5, 0.0, 0.0, 0.5, 0, 32, // x-plane vertex 1
0.0, 10.0, 0.0, 0.5, 0.0, 0.0, 0.5, 32, 0, // x-plane vertex 2
0.0, 10.0, 10.0, 0.5, 0.0, 0.0, 0.5, 32, 32, // x-plane vertex 3
0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0, 0, // y-plane vertex 0
0.0, 0.0, 10.0, 0.0, 0.5, 0.0, 0.5, 0, 32, // y-plane vertex 1
10.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 32, 0, // y-plane vertex 2
10.0, 0.0, 10.0, 0.0, 0.5, 0.0, 0.5, 32, 32, // y-plane vertex 3
0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0, 0, // z-plane vertex 0
0.0, 10.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0, 32, // z-plane vertex 1
10.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 32, 0, // z-plane vertex 2
10.0, 10.0, 0.0, 0.0, 0.0, 0.5, 0.5, 32, 32, // z-plane vertex 3
// arrows: using TRIANGLES method
2.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
1.5, 0.33, 0.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
1.5, -0.33, 0.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
2.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
1.66, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
1.66, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 0, 0, // +x
0.0, 2.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
0.0, 1.5, 0.33, 0.0, 1.0, 0.0, 1.0, 0, 0,
0.0, 1.5, -0.33, 0.0, 1.0, 0.0, 1.0, 0, 0,
0.0, 2.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
0.0, 1.66, 0.5, 0.0, 1.0, 0.0, 1.0, 0, 0,
0.0, 1.66, -0.5, 0.0, 1.0, 0.0, 1.0, 0, 0, // +y
0.0, 0.0, 2.0, 0.0, 0.0, 1.0, 1.0, 0, 0,
0.33, 0.0, 1.5, 0.0, 0.0, 1.0, 1.0, 0, 0,
-0.33, 0.0, 1.5, 0.0, 0.0, 1.0, 1.0, 0, 0,
0.0, 0.0, 2.0, 0.0, 0.0, 1.0, 1.0, 0, 0,
0.5, 0.0, 1.66, 0.0, 0.0, 1.0, 1.0, 0, 0,
-0.5, 0.0, 1.66, 0.0, 0.0, 1.0, 1.0, 0, 0, // +z
-1.5, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
-2.0, 0.0, 0.33, 1.0, 0.0, 0.0, 1.0, 0, 0,
-2.0, 0.0, -0.33, 1.0, 0.0, 0.0, 1.0, 0, 0,
-1.5, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
-1.88, 0.0, 0.5, 1.0, 0.0, 0.0, 1.0, 0, 0,
-1.88, 0.0, -0.5, 1.0, 0.0, 0.0, 1.0, 0, 0, // -x
0.0, -1.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
0.33, -2.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
-0.33, -2.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
0.0, -1.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
0.5, -1.88, 0.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
-0.5, -1.88, 0.0, 0.0, 1.0, 0.0, 1.0, 0, 0, // -y
0.0, 0.0, -1.5, 0.0, 0.0, 1.0, 1.0, 0, 0,
0.0, 0.33, -2.0, 0.0, 0.0, 1.0, 1.0, 0, 0,
0.0, -0.33, -2.0, 0.0, 0.0, 1.0, 1.0, 0, 0,
0.0, 0.0, -1.5, 0.0, 0.0, 1.0, 1.0, 0, 0,
0.0, 0.5, -1.88, 0.0, 0.0, 1.0, 1.0, 0, 0,
0.0, -0.5, -1.88, 0.0, 0.0, 1.0, 1.0, 0, 0, // -z
// cube: using TRIANGLE_STRIP method
1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0, 0,
1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0, 0,
1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0, 0, // +x
-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0, 0,
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0, 0,
1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0, 0, // +y
-1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0, 0,
1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0, 0,
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0, 0,
1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0, 0, // +z
-1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0, 0,
-1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
-1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0, 0,
-1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0, 0, // -x
-1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0, 0,
1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
-1.0, -1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0, 0,
1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0, 0, // -y
-1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0, 0,
1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 0, 0,
-1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 0, 0,
1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0, 0, // -z
];
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment