Skip to content

大师兄的博客

专注无聊20年,数过的小羊连起来可以绕地球两圈

Menu
  • 首页
  • 技术交流
    • 原创
    • WebGL教程
    • js小程序在线演示
    • 摘要总结
  • 小评论
    • 动漫短评
    • 其他短评
  • 日志/心情
    • My Piano
    • 絮絮叨叨
    • 长篇大论
  • 关于我
    • 留言板
Menu

【WebGL教程】Lesson 2

Posted on 2013 年 12 月 21 日2013 年 12 月 21 日 by wysaid

本文地址:https://wysaid.org/732.html
原创,转载请注明出处。系列教程: webgl-lesson.wysaid.org

第二话,动态加载shader (blog.wysaid.org)

上一张封装了基本的WebGL功能,包括初始化、创建着色器对象、创建&编译着色器程序然后应用着色器渲染的简单范例。这里强调一下本教程定位:在观看本教程时,作者会假设你对于OpenGL Shader Language有一定理解,所以不会去解释简单的shader代码的。如果您对GLSL一无所知,建议你先去了解。

首先,回顾一下上期内容。在lesson 1,我们集成了WebGL的一些基本功能,然后用它制作了一个小demo。 由于讲得比较仓促,而且后期有些修改校正,完整代码请点击下面的按钮:

那么,开始第二话吧!

第一小节

上次我们封装出一个叫做”renderWebGL(verticesArray, vertexSize, VertexLength, vsh, fsh, vertexIndex)”的函数,参数有六个,
第一个为所需绘制的图形的顶点数组。
第二个参数分别为每个顶点的数据大小,如果为float,那么就是1,如果是vec2,那么就是2。(不要问我传整数怎么办,我拒绝回答无聊的问题@_@)。
第三个为顶点个数。
第四个第五个分别是顶点着色器代码与片元着色器代码。
第六个是顶点着色器里面待使用的顶点的变量名。

然后最后实现了三个如renderTriangle()这样的函数实现一步调用并绘制出三角形/矩形/圆

但是,显然每次写这样的函数都是很恶心的,为什么就不能直接把shader写到一起,而要使用javascript代码来拼凑呢?下面介绍两种常见加载shader的方法:

1. html标签方式。这种方式适用于直接嵌入shader代码到网页中,优点是写起来方便

用法

Vertex Shader通常写在一个类型为”x-shader/x-vertex”的script标签内,像这样:

Vertex Shader
1
<script id="Your Vertex Shader ID" type="x-shader/x-vertex">Vertex Shader Code</script>

Fragment Shader通常写在一个类型为”x-shader/x-fragment”的script标签内,像这样:

Fragment Shader
1
<script id="Your Fragment Shader ID" type="x-shader/x-fragment">Fragment Shader Code</script>

此外,我们还需要一个Javascript函数来获取这些标签内容,记住,把有用的模块划分出来是非常有助于后续的学习的哦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//虽然看起来直接获取innerHTML就可以了,但毕竟我们写的不是HTML。
//如果你觉得没必要这么麻烦,那么你完全可以改为直接返回innerHTML
function getScriptTextByID(scriptID){
var shaderScript = document.getElementById(scriptID);
    if (shaderScript == null) return "";
 
    if (shaderScript.textContent != null && shaderScript.textContent != "") {
        return shaderScript.textContent;
    }
    if (shaderScript.text != null && shaderScript.text != "") {
        return shaderScript.text;
    }
    var sourceCode = "";
    var child = shaderScript.firstChild;
    while (child) {
        if (child.nodeType == child.TEXT_NODE) sourceCode += child.textContent;
        child = child.nextSibling;
    }
    return sourceCode;
}

但是,你应该知道,其实对于两种shader来说,这个script的type是无关紧要的,因为我们用到的只是它的内容。

所以,如果你嫌script标签写起来麻烦,你也可以写到一个div标签或者其他自定义标签里面,只要设定它的style=”display:none”,不让它显示出来,然后我们通过它的id获取它里面的文本就行了。当然,我并不推荐这样做,养成良好的习惯是我们学习过程中应有的态度。

2. js动态加载方式。这种方式适用于shader较多的情况,优点是可以把shader写到单独的文本文件里面,在需要的时候才加载。

方法:
1
2
3
4
5
6
function requestURLPlainText(url) {
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open("GET", url, false);
    xmlHttp.send();
    return xmlHttp.responseText;
}

为了获取shader文本,我们封装出requestURLPlainText函数,这个函数接收的参数为shader文件的url,返回shader文件的内容。

简单描述一下吧:首先要知道Javascript里面的XMLHttpRequest对象。为了不引入不必要的麻烦,我不会引用任何第三方的库,如果你会jQuery什么的话,就用你自己的方法吧。XMLHttpRequest为我们提供了动态网页请求的功能。

这里不得不先提一下的是使用这种方式的话,就不能在本地直接用浏览器打开html文件运行WebGL程序了(简单来讲,你的浏览器地址栏里面出现类似于file:///这样的话,是运行不出结果的), 一般情况下,你必须把你的程序置身于web环境下,通过IP或者域名访问(例如你访问本教程这样)。而本教程将介绍这两种方法。所以如果后面的demo如果使用了这种方式编写,请在Web环境下打开该demo。
(Tips: 没有在本机配置apache之类的读者如果安装有vs2010以上的IDE,可以通过vs打开demo,然后右键选择从浏览器打开,vs会根据demo是否需要web环境自动创建IIS连接。)

第二小节

上一小结介绍了一些相关知识,那么我们来开始应用吧。

首先是第一种方式,在上面给出的demo code的最前面加上如下代码(也就是我们的shader代码):

着色器标签代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script id="vsh_lesson2" type="x-shader/x-vertex">
precision mediump float;
attribute vec4 position;
varying vec2 textureCoordinate;
void main()
{
gl_Position = position;
textureCoordinate = position.xy + 0.5;
}
</script>
 
<script id="fsh_lesson2" type="x-shader/x-fragment">
precision mediump float;
varying vec2 textureCoordinate;
void main()
{
gl_FragColor = vec4(textureCoordinate, 0.0, 1.0);
}
</script>

然后,修改renderTriangle函数,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
//这下是不是清爽多了?而且shader代码就是纯粹的shader代码,没有夹杂任何javascript
function renderTriangle()
{
var vertices =
[
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5,
];
var vsh = getScriptTextByID("vsh_lesson2");
var fsh = getScriptTextByID("fsh_lesson2");
renderWebGL(vertices, 2, 3, vsh, fsh, "position");
}

然后是第二种方式,我们需要把前面提到的Vertex Shader大妈和Fragment Shader代码保存下来。在本小节中,我们把Vertex Shader保存为vsh_lesson2.js, 把Fragment Shader保存为fsh_lesson2.js,然后把它们放在demo相同的目录下。

然后通过如下代码方式访问:

1
2
3
4
5
6
7
8
9
10
11
12
//这下是不是跟上面的方法差不多?只不过封装形式不一样罢了。
function renderTriangle(){
var vertices =
[
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5,
];
var vsh = requestURLPlainText("vsh_lesson2.txt");
var fsh = requestURLPlainText("fsh_lesson2.txt");
renderWebGL(vertices, 2, 3, vsh, fsh, "position");
}

嗯,本话要讲的差不多就这些,下面让我们运行一下本小节成果吧!

为了让读者看出两者都运行成功了,我特地把第二个三角形反了个方向。lesson2只实现了三角形,如果你是初学者,希望你能按照本章封装的方法,自己把矩形跟圆形都改成这种方式实现。本期做的是功能性讲解,所以demo的变化在内而不在外。

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


1 thought on “【WebGL教程】Lesson 2”

  1. 新用户031800说道:
    2017 年 4 月 10 日 下午 12:55

    纵一往情深,无缘也难

Comments are closed.


转载本Blog文章请注明出处:
wysaid.org

2023年 3月
日 一 二 三 四 五 六
 1234
567891011
12131415161718
19202122232425
262728293031  
« 7月    

评论

  • luo.la发表在《使用OpenAL打开麦克风录音并实时回放(类似K歌效果)》
  • 罗拉发表在《使用OpenAL打开麦克风录音并实时回放(类似K歌效果)》
  • 大喜发表在《使用OpenAL打开麦克风录音并实时回放(类似K歌效果)》
  • 罗拉套图网发表在《使用OpenAL打开麦克风录音并实时回放(类似K歌效果)》
  • 爱就爱啦发表在《使用OpenAL打开麦克风录音并实时回放(类似K歌效果)》

归档

分类

TAG

Android c C++ domain EGE host iOS JavaScript NDK OpenAL OpenGL Slideshow WebGL教程 WGE 人脸识别 分形 动漫 在线演示 小程序 常识 数学 游戏 源代码 滤镜 算法 表白 视频 评论 谷歌娘 钢琴 音乐
© 2023 大师兄的博客 | Powered by Superbs Personal Blog theme