html导入外部webgl,【WebGL教程】Lesson 3 引入纹理以及简单的图像处理

第三话,传递uniform变量以及引入纹理, 做一些简单的2D处理

上一期讲到了从文件和从html标签加载shader,这一期直接上纹理了。所有教程内容包括教程本身都可以在https://github.com/wysaid/WebGL-Lessons直接获得,喜欢的话就fork&star吧。这里就不放上一话的代码了。

先卖个萌:我是手写html的!什么叫手写html呢?意思就是像“

进入正题,天依酱镇楼。

vocaloid.jpg

第一步

首先说明,本次我们要加入的纹理图片就是上面的天依酱了。不但要加入她,还要在此图像上进行一些处理,此处理仅在Fragment Shader之上进行更改。

加载图片资源的方式

我们要知道,加载图片跟加载shader也是很相似的,你可以用代码方式把图片内容写进来,比如常见的img标签里面src后面跟data:image/png;base64 + base64 编码的图像数据等。你可以用js创建一个img标签或者一个image对象,然后把这些数据写入进去直接使用。但是这种方法显然不适用于此处,我们不会把图片的编码写到代码里面的。我们只需要用到图片文件。

第一种方式:直接从img标签里面加载。这种方式的跟直接把shader代码直接写到script标签里面是一个意思,用起来方便快捷。当然,你也许并不希望把这个img标签显示出来,那么,你只需要给这个img标签加上属性 style=”display:none”就ok了。

使用方式:

function createTextureByImgObject(imgObj){

//webgl 对象为前面教程里面函数创建的全局WebGL上下文对象。

//下面这一句可有可无,但为了养成良好习惯,还是写上吧。

//把临时纹理绑定设定在0号。

webgl.activeTexture(webgl.TEXTURE0);

//创建纹理对象,并设置其属性。需要注意的是,

//在GLES里面,TEXTURE_WRAP_S/T 只能设置为GL_CLAMP_TO_EDGE,所以也是可以不写的哟。

var textureObject = webgl.createTexture();

webgl.bindTexture(webgl.TEXTURE_2D, textureObject);

webgl.texImage2D(webgl.TEXTURE_2D, 0, webgl.RGBA, webgl.RGBA, webgl.UNSIGNED_BYTE, imgObj);

webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MIN_FILTER, webgl.NEAREST);

webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MAG_FILTER, webgl.NEAREST);

webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.CLAMP_TO_EDGE);

webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_T, webgl.CLAMP_TO_EDGE);

return textureObject;

}

//在此,我们封装出一个通过img标签的id创建一个纹理的函数:

function createTextureByImgID(imgID){

var imgObj = document.getElementById(imgID);

if(imgObj == null) {

return null; //这里应该写一些容错代码,但是本阶段属于初级阶段,暂不考虑。

}

return createTextureByImgObject(imgObj);

}

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

functioncreateTextureByImgObject(imgObj){

//webgl 对象为前面教程里面函数创建的全局WebGL上下文对象。

//下面这一句可有可无,但为了养成良好习惯,还是写上吧。

//把临时纹理绑定设定在0号。

webgl.activeTexture(webgl.TEXTURE0);

//创建纹理对象,并设置其属性。需要注意的是,

//在GLES里面,TEXTURE_WRAP_S/T 只能设置为GL_CLAMP_TO_EDGE,所以也是可以不写的哟。

vartextureObject=webgl.createTexture();

webgl.bindTexture(webgl.TEXTURE_2D,textureObject);

webgl.texImage2D(webgl.TEXTURE_2D,0,webgl.RGBA,webgl.RGBA,webgl.UNSIGNED_BYTE,imgObj);

webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_MIN_FILTER,webgl.NEAREST);

webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_MAG_FILTER,webgl.NEAREST);

webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_WRAP_S,webgl.CLAMP_TO_EDGE);

webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_WRAP_T,webgl.CLAMP_TO_EDGE);

returntextureObject;

}

//在此,我们封装出一个通过img标签的id创建一个纹理的函数:

functioncreateTextureByImgID(imgID){

varimgObj=document.getElementById(imgID);

if(imgObj==null){

returnnull;//这里应该写一些容错代码,但是本阶段属于初级阶段,暂不考虑。

}

returncreateTextureByImgObject(imgObj);

}

第二种方式:通过JavaScript动态请求。在这一步上,我们必须做一个变通。

首先需要知道的是,每个浏览器都会缓存图片,所以,我们动态请求的话,就算对某一张图片请求很多次,实际上真正用到网络的只是第一次请求而已。以及,有的浏览器,比如firefox,ctrl+f5都很难清楚这种缓存,只能打开设置清除。所以如果我们是在做测试,图片经常替换而图片url不换的话,很容易遇到这种问题(img标签方式的话,只需要多刷新几次就好了):我们明明替换了图片文件,但不管怎么刷新,还是显示的前面的一张。 解决方法就是给我们请求的文件加上随机的get参数……当然,最终发布产品的时候肯定要去掉,毕竟有缓存对于服务器来说是好事。

其次,我们请求的image对象和纹理不需要共存,如果你长期保存了创建的纹理,那么这个请求的image对象就不需要保存,或者你可以删除纹理保存这个image对象……再或者,你可以创建一个隐藏的img标签悄悄地把这张图保存下来……对于用到大量纹理且纹理需要重复使用的时候更要注意,因为纹理是很占内存的。

使用方式:(这里先提供较为简单的直接写入img标签的方式, 将用到上面的函数。)

//参数一为图片的url, 参数二为此图片写入的img标签的id,

//参数三为图片加载好之后需要执行的函数。

function loadImageByURL(url, imgID, imageOnLoad) {

var obj = document.createElement("img");

obj.id = imgID;

obj.onload = function() {

//createTextureByImgObject 由上面方法一里面给出

var texObj = createTextureByImgObject(this);

imageOnLoad(texObj);

}

obj.src = url;

obj.setAttribute("style", "display:none");

var body = document.getElementsByTagName("body").item(0);

body.appendChild(obj);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

//参数一为图片的url, 参数二为此图片写入的img标签的id,

//参数三为图片加载好之后需要执行的函数。

functionloadImageByURL(url,imgID,imageOnLoad){

varobj=document.createElement("img");

obj.id=imgID;

obj.οnlοad=function(){

//createTextureByImgObject 由上面方法一里面给出

vartexObj=createTextureByImgObject(this);

imageOnLoad(texObj);

}

obj.src=url;

obj.setAttribute("style","display:none");

varbody=document.getElementsByTagName("body").item(0);

body.appendChild(obj);

}

上面的方法并不好用,并且也不直观。正确的方法应该是用户在运行程序之前就把需要加载的纹理资源全部或者说当前需要用到的部分加载完毕。因为js的回调看起来并不那么直观。上面的方法仅仅提供了一种思路,如果你要加载多张图片,希望你能想出更好的方法。后面的章节会提到更好的解决办法

第二步

有了纹理对象,那么接下来只要使用这个纹理对象,传递给我们的fragment shader就ok了。

这个过程异常轻松,我们就直接写完吧。

首先我们必须要有shader 代码, 本章用到的顶点着色器代码:

precision mediump float;

attribute vec4 position;

attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

void main()

{

gl_Position = position;

// 这是一种取巧的做法,强行把顶点坐标映射为纹理坐标,

// 但是仅适用于本章用到的刚好占满整个viewport的顶点哦。

textureCoordinate = vec2((position.x+1.0)/2.0, 1.0-(position.y+1.0)/2.0);

}

1

2

3

4

5

6

7

8

9

10

11

precisionmediumpfloat;

attributevec4position;

attributevec4inputTextureCoordinate;

varyingvec2textureCoordinate;

voidmain()

{

gl_Position=position;

// 这是一种取巧的做法,强行把顶点坐标映射为纹理坐标,

// 但是仅适用于本章用到的刚好占满整个viewport的顶点哦。

textureCoordinate=vec2((position.x+1.0)/2.0,1.0-(position.y+1.0)/2.0);

}

本章用到的简单片元着色器代码:

//显示原图:

precision mediump float;

varying vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

void main()

{

gl_FragColor = texture2D(inputImageTexture, textureCoordinate);

}

//显示反色:

precision mediump float;

varying vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

void main()

{

vec3 v = texture2D(inputImageTexture, textureCoordinate).rgb;

float f = (v.r + v.g + v.b) / 3.0;

gl_FragColor = vec4(f, f, f, 1.0);

}

//浮雕效果:

precision mediump float;

varying vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

uniform vec2 steps;

const float stride = 2.0;

void main()

{

vec3 tmpColor = texture2D(inputImageTexture, textureCoordinate + steps * stride).rgb;

tmpColor = texture2D(inputImageTexture, textureCoordinate).rgb - tmpColor + 0.5;

float f = (tmpColor.r + tmpColor.g + tmpColor.b) / 3.0;

gl_FragColor = vec4(f, f, f, 1.0);

}

//显示边缘:

precision mediump float;

varying vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

uniform vec2 steps;

const float stride = 2.0;

void main()

{

vec3 tmpColor = texture2D(inputImageTexture, textureCoordinate + steps * stride).rgb;

tmpColor = abs(texture2D(inputImageTexture, textureCoordinate).rgb - tmpColor);

gl_FragColor = vec4(tmpColor * 2.0, 1.0);

}

//波纹:

precision mediump float;

varying vec2 textureCoordinate;

uniform sampler2D inputImageTexture;

uniform float motion;

uniform float angle;

void main()

{

vec2 tmp = textureCoordinate;

tmp.x = tmp.x + 0.01 * sin(motion + tmp.x * angle);

tmp.y = tmp.y + 0.01 * sin(motion + tmp.y * angle);

gl_FragColor = texture2D(inputImageTexture, tmp);

}

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

//显示原图:

precisionmediumpfloat;

varyingvec2textureCoordinate;

uniformsampler2DinputImageTexture;

voidmain()

{

gl_FragColor=texture2D(inputImageTexture,textureCoordinate);

}

//显示反色:

precisionmediumpfloat;

varyingvec2textureCoordinate;

uniformsampler2DinputImageTexture;

voidmain()

{

vec3v=texture2D(inputImageTexture,textureCoordinate).rgb;

floatf=(v.r+v.g+v.b)/3.0;

gl_FragColor=vec4(f,f,f,1.0);

}

//浮雕效果:

precisionmediumpfloat;

varyingvec2textureCoordinate;

uniformsampler2DinputImageTexture;

uniformvec2steps;

constfloatstride=2.0;

voidmain()

{

vec3tmpColor=texture2D(inputImageTexture,textureCoordinate+steps *stride).rgb;

tmpColor=texture2D(inputImageTexture,textureCoordinate).rgb-tmpColor+0.5;

floatf=(tmpColor.r+tmpColor.g+tmpColor.b)/3.0;

gl_FragColor=vec4(f,f,f,1.0);

}

//显示边缘:

precisionmediumpfloat;

varyingvec2textureCoordinate;

uniformsampler2DinputImageTexture;

uniformvec2steps;

constfloatstride=2.0;

voidmain()

{

vec3tmpColor=texture2D(inputImageTexture,textureCoordinate+steps *stride).rgb;

tmpColor=abs(texture2D(inputImageTexture,textureCoordinate).rgb-tmpColor);

gl_FragColor=vec4(tmpColor *2.0,1.0);

}

//波纹:

precisionmediumpfloat;

varyingvec2textureCoordinate;

uniformsampler2DinputImageTexture;

uniformfloatmotion;

uniformfloatangle;

voidmain()

{

vec2tmp=textureCoordinate;

tmp.x=tmp.x+0.01*sin(motion+tmp.x *angle);

tmp.y=tmp.y+0.01*sin(motion+tmp.y *angle);

gl_FragColor=texture2D(inputImageTexture,tmp);

}

好了,有了着色器代码,我们就可以写调用代码了:

// 本期教程用到的顶点为下方顶点,为了节省篇幅,就写为全局了。

var vertices =

[

1.0, 1.0,

1.0, -1.0,

-1.0, 1.0,

-1.0, -1.0

];

//参考上一期,我们依旧使用我们封装出来的函数,

//但是renderWebGL 这个函数显然已经不能满足我们了,

//我们需要提供更多的东西给WebGL。把这个函数整改一下。

//直接绘制原图:

function renderOrigin(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

var vsh = getScriptTextByID("vsh_lesson3");

var fsh = getScriptTextByID("fsh_origin");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh, fsh);

initShaderProgram("position");

var buffer = webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);

webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex, 2, webgl.FLOAT, false, 0, 0);

//在这里把我们的纹理交给WebGL:

var texObj = createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0); // 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

var uniform = webgl.getUniformLocation(programObject, "inputImageTexture");

webgl.uniform1i(uniform, 0);

webgl.clearColor(0.0, 0.0, 0.0, 1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4);

}

//绘制反色:

function renderInverse(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

var vsh = getScriptTextByID("vsh_lesson3");

var fsh = getScriptTextByID("fsh_inverse");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh, fsh);

initShaderProgram("position");

var buffer = webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);

webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex, 2, webgl.FLOAT, false, 0, 0);

//在这里把我们的纹理交给WebGL:

var texObj = createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0); // 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

var uniform = webgl.getUniformLocation(programObject, "inputImageTexture");

webgl.uniform1i(uniform, 0);

webgl.clearColor(0.0, 0.0, 0.0, 1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4);

}

//绘制浮雕:

function renderEmboss(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

var vsh = getScriptTextByID("vsh_lesson3");

var fsh = getScriptTextByID("fsh_emboss");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh, fsh);

initShaderProgram("position");

var buffer = webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);

webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex, 2, webgl.FLOAT, false, 0, 0);

//在这里把我们的纹理交给WebGL:

var texObj = createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0); // 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

var uniformTex = webgl.getUniformLocation(programObject, "inputImageTexture");

webgl.uniform1i(uniformTex, 0);

//由于浮雕效果需要知道采样步长,所以传递此参数给shader。

var uniformSteps = webgl.getUniformLocation(programObject, "steps");

var cvsObj = document.getElementById("webglView");

webgl.uniform2f(uniformSteps, 1.0 / cvsObj.width, 1.0 / cvsObj.height);

webgl.clearColor(0.0, 0.0, 0.0, 1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4);

}

//绘制边缘:

function renderEdge(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

var vsh = getScriptTextByID("vsh_lesson3");

var fsh = getScriptTextByID("fsh_edge");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh, fsh);

initShaderProgram("position");

var buffer = webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);

webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex, 2, webgl.FLOAT, false, 0, 0);

//在这里把我们的纹理交给WebGL:

var texObj = createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0); // 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

var uniform = webgl.getUniformLocation(programObject, "inputImageTexture");

webgl.uniform1i(uniform, 0);

//由于边缘效果需要知道采样步长,所以传递此参数给shader。

var uniformSteps = webgl.getUniformLocation(programObject, "steps");

var cvsObj = document.getElementById("webglView");

webgl.uniform2f(uniformSteps, 1.0 / cvsObj.width, 1.0 / cvsObj.height);

webgl.clearColor(0.0, 0.0, 0.0, 1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4);

}

//波纹效果需要重绘,这里预留一个interval。

var itv = {};

//重绘wave

function redrawWave() {

webgl.uniform1f(itv.uniformMotion, itv.motion += 0.05);

webgl.uniform1f(itv.uniformAngle, 15.0);

webgl.clearColor(0.0, 0.0, 0.0, 1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4);

if (itv.motion > 1.0e20) itv.motion = 0.0;

}

//绘制波纹:

function renderWave(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

var vsh = getScriptTextByID("vsh_lesson3");

var fsh = getScriptTextByID("fsh_wave");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh, fsh);

initShaderProgram("position");

var buffer = webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);

webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(vertices), webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex, 2, webgl.FLOAT, false, 0, 0);

//在这里把我们的纹理交给WebGL:

var texObj = createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0); // 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

var uniform = webgl.getUniformLocation(programObject, "inputImageTexture");

webgl.uniform1i(uniform, 0);

//wave效果需要使用motion和angle两个参数。

itv.uniformMotion = webgl.getUniformLocation(programObject, "motion");

itv.uniformAngle = webgl.getUniformLocation(programObject, "angle");

itv.motion = 0.0;

itv.interval = setInterval("redrawWave()", 15);

}

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

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

// 本期教程用到的顶点为下方顶点,为了节省篇幅,就写为全局了。

varvertices=

[

1.0,1.0,

1.0,-1.0,

-1.0,1.0,

-1.0,-1.0

];

//参考上一期,我们依旧使用我们封装出来的函数,

//但是renderWebGL 这个函数显然已经不能满足我们了,

//我们需要提供更多的东西给WebGL。把这个函数整改一下。

//直接绘制原图:

functionrenderOrigin(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

varvsh=getScriptTextByID("vsh_lesson3");

varfsh=getScriptTextByID("fsh_origin");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh,fsh);

initShaderProgram("position");

varbuffer=webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER,buffer);

webgl.bufferData(webgl.ARRAY_BUFFER,newFloat32Array(vertices),webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex,2,webgl.FLOAT,false,0,0);

//在这里把我们的纹理交给WebGL:

vartexObj=createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0);// 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

varuniform=webgl.getUniformLocation(programObject,"inputImageTexture");

webgl.uniform1i(uniform,0);

webgl.clearColor(0.0,0.0,0.0,1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP,0,4);

}

//绘制反色:

functionrenderInverse(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

varvsh=getScriptTextByID("vsh_lesson3");

varfsh=getScriptTextByID("fsh_inverse");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh,fsh);

initShaderProgram("position");

varbuffer=webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER,buffer);

webgl.bufferData(webgl.ARRAY_BUFFER,newFloat32Array(vertices),webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex,2,webgl.FLOAT,false,0,0);

//在这里把我们的纹理交给WebGL:

vartexObj=createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0);// 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

varuniform=webgl.getUniformLocation(programObject,"inputImageTexture");

webgl.uniform1i(uniform,0);

webgl.clearColor(0.0,0.0,0.0,1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP,0,4);

}

//绘制浮雕:

functionrenderEmboss(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

varvsh=getScriptTextByID("vsh_lesson3");

varfsh=getScriptTextByID("fsh_emboss");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh,fsh);

initShaderProgram("position");

varbuffer=webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER,buffer);

webgl.bufferData(webgl.ARRAY_BUFFER,newFloat32Array(vertices),webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex,2,webgl.FLOAT,false,0,0);

//在这里把我们的纹理交给WebGL:

vartexObj=createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0);// 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

varuniformTex=webgl.getUniformLocation(programObject,"inputImageTexture");

webgl.uniform1i(uniformTex,0);

//由于浮雕效果需要知道采样步长,所以传递此参数给shader。

varuniformSteps=webgl.getUniformLocation(programObject,"steps");

varcvsObj=document.getElementById("webglView");

webgl.uniform2f(uniformSteps,1.0/cvsObj.width,1.0/cvsObj.height);

webgl.clearColor(0.0,0.0,0.0,1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP,0,4);

}

//绘制边缘:

functionrenderEdge(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

varvsh=getScriptTextByID("vsh_lesson3");

varfsh=getScriptTextByID("fsh_edge");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh,fsh);

initShaderProgram("position");

varbuffer=webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER,buffer);

webgl.bufferData(webgl.ARRAY_BUFFER,newFloat32Array(vertices),webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex,2,webgl.FLOAT,false,0,0);

//在这里把我们的纹理交给WebGL:

vartexObj=createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0);// 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

varuniform=webgl.getUniformLocation(programObject,"inputImageTexture");

webgl.uniform1i(uniform,0);

//由于边缘效果需要知道采样步长,所以传递此参数给shader。

varuniformSteps=webgl.getUniformLocation(programObject,"steps");

varcvsObj=document.getElementById("webglView");

webgl.uniform2f(uniformSteps,1.0/cvsObj.width,1.0/cvsObj.height);

webgl.clearColor(0.0,0.0,0.0,1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP,0,4);

}

//波纹效果需要重绘,这里预留一个interval。

varitv={};

//重绘wave

functionredrawWave(){

webgl.uniform1f(itv.uniformMotion,itv.motion+=0.05);

webgl.uniform1f(itv.uniformAngle,15.0);

webgl.clearColor(0.0,0.0,0.0,1.0);

webgl.clear(webgl.COLOR_BUFFER_BIT);

webgl.drawArrays(webgl.TRIANGLE_STRIP,0,4);

if(itv.motion>1.0e20)itv.motion=0.0;

}

//绘制波纹:

functionrenderWave(){

// 读者可选择自己喜欢的加载方式,本教程为了方便,

// 选择html标签方式加载shader代码。

varvsh=getScriptTextByID("vsh_lesson3");

varfsh=getScriptTextByID("fsh_wave");

//不能直接使用但是renderWebGL 这个函数,我们先抄下它的前几句。

webglInit();

shaderInitWithVertexAndFragmentShader(vsh,fsh);

initShaderProgram("position");

varbuffer=webgl.createBuffer();

webgl.bindBuffer(webgl.ARRAY_BUFFER,buffer);

webgl.bufferData(webgl.ARRAY_BUFFER,newFloat32Array(vertices),webgl.STATIC_DRAW);

webgl.enableVertexAttribArray(v4PositionIndex);

webgl.vertexAttribPointer(v4PositionIndex,2,webgl.FLOAT,false,0,0);

//在这里把我们的纹理交给WebGL:

vartexObj=createTextureByImgID("vocaloid");

webgl.activeTexture(webgl.TEXTURE0);// 为了安全起见,在使用之前请绑定好纹理ID。虽然在createTextureByImgID函数里面已经绑定了,但是,那并不是必须的,这里才是必须的。

varuniform=webgl.getUniformLocation(programObject,"inputImageTexture");

webgl.uniform1i(uniform,0);

//wave效果需要使用motion和angle两个参数。

itv.uniformMotion=webgl.getUniformLocation(programObject,"motion");

itv.uniformAngle=webgl.getUniformLocation(programObject,"angle");

itv.motion=0.0;

itv.interval=setInterval("redrawWave()",15);

}

那么,讲了这么多,我们来看看本次的demo吧:

好的,第三期教程到此为止,请关注lesson 4。系列教程地址:webgl-lesson.wysaid.org

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值