Skip to content

狗子窝

没事就吠一下

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

2025 年 5 月
日 一 二 三 四 五 六
 123
45678910
11121314151617
18192021222324
25262728293031
« 2 月    

评论

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

归档

分类

TAG

Android c C++ domain EGE host iOS JavaScript NDK OpenAL OpenGL Slideshow WebGL教程 WGE 人脸识别 作文 分形 动漫 在线演示 小程序 常识 数学 游戏 源代码 滤镜 算法 老文翻新 表白 视频 评论 谷歌娘 酸腐文章 钢琴 音乐
© 2025 狗子窝 | Powered by Superbs Personal Blog theme