卜若的代码笔记-webgl系列-第二十章:glsl探索(八)$webgl中关于纹理的使用$

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>

 

 有些自定义的东西没有,不过大体意思很清晰,将就看呗~~,下一讲我们实现一些有趣的东西~

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值