Lab7

预览
taska页面链接
taskb页面链接
taskc页面链接

taska. 一个带有多重纹理的立方体

顶点着色器代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#version 300 es
in vec4 vPosition;
in vec4 vColor;
in vec2 vTexCoord;

out vec4 aColor;
out vec2 aTexCoord;

uniform vec3 theta;

void main()
{
vec3 angles = radians(theta);
vec3 c = cos(angles);
vec3 s = sin(angles);

mat4 rx = mat4(1.0, 0.0, 0.0, 0.0,
0.0, c.x, s.x, 0.0,
0.0, -s.x, c.x, 0.0,
0.0, 0.0, 0.0, 1.0);
mat4 ry = mat4(c.y, 0.0, -s.y, 0.0,
0.0, 1.0, 0.0, 0.0,
s.y, 0.0, c.y, 0.0,
0.0, 0.0, 0.0, 1.0);
mat4 rz = mat4(c.z, s.z, 0.0, 0.0,
-s.z, c.z, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);

aColor = vColor;
aTexCoord = vTexCoord;
}

片元着色器代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#version 300 es    
precision mediump float;

in vec4 aColor;
in vec2 aTexCoord;

out vec4 fColor;

uniform sampler2D texture1;
uniform sampler2D texture2;

void main()
{
fColor = aColor * (texture( texture1, aTexCoord ) * texture( texture2, aTexCoord ));
}

图形如图:

taska页面链接


taskb. 通过实现不同的纹理坐标形式,映射到球体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
configureTexture: function () {
var image1 = new Uint8Array(4 * this.texSize * this.texSize);
for (var i = 0; i < this.texSize; i++) {
for (var j = 0; j < this.texSize; j++) {
this.c = 255 * (((i & 0x20) == 0) ^ ((j & 0x20) == 0));
image1[4 * i * this.texSize + 4 * j] = this.c;
image1[4 * i * this.texSize + 4 * j + 1] = this.c;
image1[4 * i * this.texSize + 4 * j + 2] = this.c;
image1[4 * i * this.texSize + 4 * j + 3] = 255;
}
}

var image2 = new Uint8Array(4 * this.texSize * this.texSize);
for (var i = 0; i < this.texSize; i++) {
for (var j = 0; j < this.texSize; j++) {
image2[4 * i * this.texSize + 4 * j] = 127 + 127 * Math.sin(0.1 * i * j);
image2[4 * i * this.texSize + 4 * j + 1] = 127 + 127 * Math.sin(0.1 * i * j);
image2[4 * i * this.texSize + 4 * j + 2] = 127 + 127 * Math.sin(0.1 * i * j);
image2[4 * i * this.texSize + 4 * j + 3] = 255;
}
}

this.texture1 = this.gl.createTexture();
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture1);
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.texSize, this.texSize, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, image1);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST_MIPMAP_LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);

this.texture2 = this.gl.createTexture();
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture2);
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, true);
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.texSize, this.texSize, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, image2);
this.gl.generateMipmap(this.gl.TEXTURE_2D);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST_MIPMAP_LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
}

图形如图:

taskb页面链接


taskc. 通过实现不同的纹理坐标形式,映射到圆柱体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
makeCylinder: function (radius, height, latitudeBands, longitudeBands) {
this.points = [];
this.colors = [];
this.texCoords = [];

// 生成圆柱体侧面
for (var latNumber = 0; latNumber <= latitudeBands; latNumber++) {
var y = height * (latNumber / latitudeBands - 0.5);
for (var longNumber = 0; longNumber <= longitudeBands; longNumber++) {
var theta = longNumber * 2 * Math.PI / longitudeBands;
var x = radius * Math.cos(theta);
var z = radius * Math.sin(theta);
var u = longNumber / longitudeBands;
var v = latNumber / latitudeBands;

this.points.push(x, y, z);
this.texCoords.push(u, v);
this.colors.push(1.0, 1.0, 1.0, 1.0);
}
}

for (var latNumber = 0; latNumber < latitudeBands; latNumber++) {
for (var longNumber = 0; longNumber < longitudeBands; longNumber++) {
var first = (latNumber * (longitudeBands + 1)) + longNumber;
var second = first + longitudeBands + 1;

this.points.push(this.points[first * 3], this.points[first * 3 + 1], this.points[first * 3 + 2]);
this.points.push(this.points[second * 3], this.points[second * 3 + 1], this.points[second * 3 + 2]);
this.points.push(this.points[(first + 1) * 3], this.points[(first + 1) * 3 + 1], this.points[(first + 1) * 3 + 2]);

this.points.push(this.points[second * 3], this.points[second * 3 + 1], this.points[second * 3 + 2]);
this.points.push(this.points[(second + 1) * 3], this.points[(second + 1) * 3 + 1], this.points[(second + 1) * 3 + 2]);
this.points.push(this.points[(first + 1) * 3], this.points[(first + 1) * 3 + 1], this.points[(first + 1) * 3 + 2]);

this.texCoords.push(this.texCoords[first * 2], this.texCoords[first * 2 + 1]);
this.texCoords.push(this.texCoords[second * 2], this.texCoords[second * 2 + 1]);
this.texCoords.push(this.texCoords[(first + 1) * 2], this.texCoords[(first + 1) * 2 + 1]);

this.texCoords.push(this.texCoords[second * 2], this.texCoords[second * 2 + 1]);
this.texCoords.push(this.texCoords[(second + 1) * 2], this.texCoords[(second + 1) * 2 + 1]);
this.texCoords.push(this.texCoords[(first + 1) * 2], this.texCoords[(first + 1) * 2 + 1]);

// 根据纬度选择颜色
var colorIndex = Math.floor(latNumber / (latitudeBands / 6));
for (var i = 0; i < 6; i++) {
this.colors.push(this.vertexColors[colorIndex][0], this.vertexColors[colorIndex][1], this.vertexColors[colorIndex][2], this.vertexColors[colorIndex][3]);
}
}
}

// 生成底面
var baseCenterIndex = this.points.length / 3;
this.points.push(0.0, -height / 2, 0.0);
this.texCoords.push(0.5, 0.5);
this.colors.push(1.0, 1.0, 1.0, 1.0);

for (var longNumber = 0; longNumber <= longitudeBands; longNumber++) {
var theta = longNumber * 2 * Math.PI / longitudeBands;
var x = radius * Math.cos(theta);
var z = radius * Math.sin(theta);
var u = 0.5 + 0.5 * Math.cos(theta);
var v = 0.5 + 0.5 * Math.sin(theta);

this.points.push(x, -height / 2, z);
this.texCoords.push(u, v);
this.colors.push(1.0, 1.0, 1.0, 1.0);

if (longNumber > 0) {
this.points.push(0.0, -height / 2, 0.0);
this.points.push(this.points[(baseCenterIndex + longNumber) * 3], this.points[(baseCenterIndex + longNumber) * 3 + 1], this.points[(baseCenterIndex + longNumber) * 3 + 2]);
this.points.push(this.points[(baseCenterIndex + longNumber + 1) * 3], this.points[(baseCenterIndex + longNumber + 1) * 3 + 1], this.points[(baseCenterIndex + longNumber + 1) * 3 + 2]);

this.texCoords.push(0.5, 0.5);
this.texCoords.push(this.texCoords[(baseCenterIndex + longNumber) * 2], this.texCoords[(baseCenterIndex + longNumber) * 2 + 1]);
this.texCoords.push(this.texCoords[(baseCenterIndex + longNumber + 1) * 2], this.texCoords[(baseCenterIndex + longNumber + 1) * 2 + 1]);

for (var i = 0; i < 3; i++) {
this.colors.push(1.0, 1.0, 1.0, 1.0);
}
}
}

// 生成顶面
var topCenterIndex = this.points.length / 3;
this.points.push(0.0, height / 2, 0.0);
this.texCoords.push(0.5, 0.5);
this.colors.push(1.0, 1.0, 1.0, 1.0);

for (var longNumber = 0; longNumber <= longitudeBands; longNumber++) {
var theta = longNumber * 2 * Math.PI / longitudeBands;
var x = radius * Math.cos(theta);
var z = radius * Math.sin(theta);
var u = 0.5 + 0.5 * Math.cos(theta);
var v = 0.5 + 0.5 * Math.sin(theta);

this.points.push(x, height / 2, z);
this.texCoords.push(u, v);
this.colors.push(1.0, 1.0, 1.0, 1.0);

if (longNumber > 0) {
this.points.push(0.0, height / 2, 0.0);
this.points.push(this.points[(topCenterIndex + longNumber) * 3], this.points[(topCenterIndex + longNumber) * 3 + 1], this.points[(topCenterIndex + longNumber) * 3 + 2]);
this.points.push(this.points[(topCenterIndex + longNumber + 1) * 3], this.points[(topCenterIndex + longNumber + 1) * 3 + 1], this.points[(topCenterIndex + longNumber + 1) * 3 + 2]);

this.texCoords.push(0.5, 0.5);
this.texCoords.push(this.texCoords[(topCenterIndex + longNumber) * 2], this.texCoords[(topCenterIndex + longNumber) * 2 + 1]);
this.texCoords.push(this.texCoords[(topCenterIndex + longNumber + 1) * 2], this.texCoords[(topCenterIndex + longNumber + 1) * 2 + 1]);

for (var i = 0; i < 3; i++) {
this.colors.push(1.0, 1.0, 1.0, 1.0);
}
}
}
}

图形如图:

taskc页面链接