1 资源的加载
var texture = glContext.createTexture();
// 创建 Image对象
var imgObj = new Image();
// 为 src 属性赋值
imgObj.src = "../../../image/b2.jpg";
imgObj.onload = function (ev) {
glContext.activeTexture(glContext.TEXTURE0);
glContext.bindTexture (glContext.TEXTURE_2D,texture);
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER, glContext.LINEAR);// 纹理放大方式
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MIN_FILTER, glContext.LINEAR);// 纹理缩小方式
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_WRAP_S, glContext.CLAMP_TO_EDGE);// 纹理水平填充方式
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_WRAP_T, glContext.CLAMP_TO_EDGE);// 纹理垂直填充方式
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGB, glContext.RGB, glContext.UNSIGNED_BYTE, imgObj);
}
需要注意的是,这一点非常有意思:
你使用src创建了一个数据源,但是你这个数据源怎么传递进入到你的shader,这其实很有意思也非常值得探讨!
它是这样的:
首先,你的glContext会激活一张纹理,也就是:
然后,将你创建的空纹理绑定给它,这个空纹理有点类似于List,是一个动态缓冲区
会设置一些参数,用来调整你的图像修改的样式
其实这些不是很重要,最 重要的是这句话
它会将你的数据源存放到动态缓存区也就是glContext.TEXTURE_2D中 !
ok,其实做完这一步,其实已经算是完成了数据源到shader的注入
2 采样与逐像素绑定
逐像素绑定是我瞎想的一个概念,大概可以解释下这个意思,我们可以来看一下这个FragmentShader:
<script id="fragment_shader" type="x-shader/x-fragment">
uniform sampler2D u_Sampler;
varying vec2 v_TexCoord;
void main() {
gl_FragColor = texture2D(u_Sampler, v_TexCoord);
}
</script>
在这里有一个数据连接桥u_Sampler
它是一个采样器,也就是它将会将采样到的数据存储通过逐像素绑定的方式,完成纹理的贴图
里面比较重要的一个概念就是v_TexCoord,我们注意到他是varying,也就意味着它本身是来自于VertexShader,其实,它就是一个uv映射,在前面的章节中,我曾经提到过一个非常重要的猜测,我们知道渲染流程是一个顺序的比如a->ua->b->ub....
逐完顶点逐片元,以这样的方式,所以,我们传来的v_TexCoord本质上是VertexShader所对应的UV坐标,so,其实问题已经变得很简单了,我们只需要创造这样一个uv就行,当然,方式有很多,这里有种最简单的方式:
<script id="vertexShader" type="x-shader/x-vertex">
uniform mat4 u_MvpMatrix;
varying vec2 v_TexCoord;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
v_TexCoord = mvPosition.xy*0.2;
gl_Position = projectionMatrix * mvPosition;
}
</script>
因为纹理坐标是归一化的,而我们的四边形依旧来自于上一张的这个四边形:
它的长宽 = 5,归一化 = 5*0.2,so,完成了uv的绑定。
最后是代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
div#canvas-frame {
border: none;
cursor: pointer;
width: 100%;
height: 600px;
background-color: #EEEEEE;
}
</style>
<script src="../../core/three.js"></script>
<script src="../../core/BasicElementCreater.js"></script>
<script src="../../core/WebglManager.js"></script>
<script id="fragment_shader" type="x-shader/x-fragment">
uniform sampler2D u_Sampler;
varying vec2 v_TexCoord;
void main() {
gl_FragColor = texture2D(u_Sampler, v_TexCoord);
}
</script>
<script id="vertexShader" type="x-shader/x-vertex">
uniform mat4 u_MvpMatrix;
varying vec2 v_TexCoord;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
v_TexCoord = mvPosition.xy*0.2;
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script >
window.onload = function (ev) {
create(document.getElementById("canvas-frame"));//创建了一个View,也就是指定了Camera,lisght,Scene,renderer
setViewport(20);//设定Camera的z值为20,保证我们的cube在裁剪空间里面
var material = new THREE.ShaderMaterial({
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragment_shader').textContent
});
geometryCachePush(Vector3(0,0,0));
geometryCachePush(Vector3(5,0,0));
geometryCachePush(Vector3(5,5,0));
geometryCachePush(Vector3(0,5,0));
var mesh = createMeshWithoutMaterial();
mesh.material =material;
var texture = glContext.createTexture();
// 创建 Image对象
var imgObj = new Image();
// 为 src 属性赋值
imgObj.src = "../../../image/b2.jpg";
imgObj.onload = function (ev) {
glContext.activeTexture(glContext.TEXTURE0);
glContext.bindTexture (glContext.TEXTURE_2D,texture);
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER, glContext.LINEAR);// 纹理放大方式
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MIN_FILTER, glContext.LINEAR);// 纹理缩小方式
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_WRAP_S, glContext.CLAMP_TO_EDGE);// 纹理水平填充方式
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_WRAP_T, glContext.CLAMP_TO_EDGE);// 纹理垂直填充方式
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGB, glContext.RGB, glContext.UNSIGNED_BYTE, imgObj);
}
frame();//循环渲染
}
</script>
<body>
<div id="canvas-frame"></div>
</body>
</html>
有些自定义的东西没有,不过大体意思很清晰,将就看呗~~,下一讲我们实现一些有趣的东西~