当前位置:   article > 正文

卜若的代码笔记-webgl系列-第十九章:glsl探索(七)$关于VertexShader向FragmentShader传递的uv的探索和思考$_vertex shader fragment shader 参数传递 in out

vertex shader fragment shader 参数传递 in out

1 使用立方体去探索它的uv是一个很复杂的过程,及其变态,所以为了解决这个问题,我们需要去简化它,最简单的方法就是通过三角面去探索这个问题。

 

1.1 以下是一个封装好的用于三角面的函数

  1. var geometryCache = new Array();
  2. function geometryCachePush(vector3) {
  3. geometryCache.push(vector3);
  4. }
  5. function createMeshWithoutMaterial() {
  6. var geometry = new THREE.Geometry();
  7. var material = null;
  8. for (var i in geometryCache)
  9. {
  10. console.info(geometryCache[i]);
  11. geometry.vertices.push(new THREE.Vector3(geometryCache[i].x,geometryCache[i].y,geometryCache[i].z));
  12. }
  13. var normal = new THREE.Vector3( 0, 0, 1 ); //三角面法向量,x,y,z定义z轴为法向量
  14. for (var i = 0;i<geometryCache.length - 2;i++)
  15. {
  16. geometry.faces.push( new THREE.Face3( 0, 1+i, 2+i, normal) ); //三角面添加到几何体
  17. }
  18. var msh = new THREE.Mesh(geometry,material );
  19. addObject(msh);
  20. geometryCache.length = 0;
  21. return msh;
  22. }

1.2 使用

其实怎么使用这并不重要,实现的过程仁者见仁智者见智,我们主要去探索这里面shader的变化。

创建的Shader:

  1. <script id="fragment_shader" type="x-shader/x-fragment">
  2. uniform float time;
  3. uniform float width;
  4. uniform float height;
  5. varying vec3 suv;
  6. float dynamic;
  7. void main( void ) {
  8. gl_FragColor = vec4(0.0,1.0,0.0, 1.0 );
  9. }
  10. </script>
  11. <script id="vertexShader" type="x-shader/x-vertex">
  12. varying vec3 suv;
  13. void main()
  14. {
  15. suv = position;
  16. vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
  17. gl_Position = projectionMatrix * mvPosition;
  18. }
  19. </script>

先来看一下效果:

1.3 现在我们来思考我们在这一章中要讨论的问题:UV的传递:

那么,什么是UV

这是一段来自百度百科的解释:

UV"这里是指u,v纹理贴图坐标的简称(它和空间模型的X, Y, Z轴是类似的). 它定义了图片上每个点的位置的信息.

ok,所以,我们完全可以认为UV就是顶点坐标!!,而且这个顶点坐标是各个片元的顶点坐标,我是什么意思呢,意思就是,uv只有在三角面这个mesh的单元里面才有意义。

如果你说三个顶点head,leg,arm,那你觉得这三个顶点是uv吗?显然不是的,学过离散数学,我们会知道,在计算机里面点是离散的,线,其实本质上是由离散的点构成的,这就意味着面,也是由离散的面构成,只是让人感觉更不可思议的是:

就算是最小的单元,三角面本身,里面的点也是足够密集的,密集到,你可以当他成为一个面,而不会将它当做是一个镂空的纱窗。

 

这一段话实在是太抽象了,接下来我会做一个实验,让你们理解下这段话想要表达的思想。

我绘制的这个四边形,其实由两个三角面组成。

也就是说,它由两个基本元素Triangle组成,那么uv在这里面已经有足够的意义,如果我要用三个点去描述一个人的纹理的位置信息...你就会看到一个三角形,你看不见它穿的衣服,看不到它的脸,就是一个妥妥的丑逼,我们称之为三角星人。

当然,其实这不重要。

对于这个四边形,我们让它分配的UV是什么呢?

如下:

这个就是它的uv了,我们通常见到的...嗯uv坐标是-1~1之间,那么只需要进行归一化就行,这本质上其实非常简单。

 接下来,我将要做一个更加具有实际意义,也更加让人深入理解什么叫uv的骚操作。

 

我们知道FragmentShader下面的函数:gl_FragColor是一个逐顶点上色的过程。

那么,我现在,在我这个四边形的基础上,对它进行上色

上色的代码如下:

上色结果: 

这个典型的逐顶点的操作。

我们所看到的一张图像里面,其实有很多像素,比如一张512*512*3的图像,那么对于这张图像每一个像素上色的过程就是gl_FragColor要干的事情。

这是一种uv分配的方式,但是,事实上呢,glsl在设计的时候,它其实是提供了你一个自定义uv的接口,因为,通常情况下我们会有非常奇葩的需求,比如,我们要让贴图倒着来,如果直接在FragmentShader里面操作,这样会...嗯,反正我觉得可以,但是,这其实不重要,主要是uv还有另外一种方式,那就是直接定义顶点的uv

 

比如这种做法:

geometry.vertices[0].uv = new THREE.Vector2(0,0);

这样,其实就可以直接使用Varying将uv传递个FragmentVertex:

 如果,我要直接分配四个顶点的uv,用这种方式确实要比那种要爽很多:

 

就这样....哎

下一章我们讲什么呢?我们懂了uv,那么是不是应该尝试将一张彩色图像匹配到这个显示块里面呢?

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/107749
推荐阅读
相关标签
  

闽ICP备14008679号