3.js - 顶点着色器、片元着色器的联系

1、定义与功能

顶点着色器

javascript 复制代码
	
	顶点着色器,是图形渲染管线中的第一个可编程阶段,
	
	它的主要任务是,
	
	处理从CPU发送到GPU的顶点数据,包括:
	
		1、顶点位置的变换(如:模型空间 -> 世界空间 -> 视图控件 -> 投影空间的转换)
		
		2、光照计算
		
		3、传递数据到后续的渲染阶段(`传递数据到片元着色器`)

片元着色器

javascript 复制代码
	片元着色器,是图形渲染管线中处理像素级渲染的阶段,
	
	它接收由`顶点着色器插值得到的片元`(即:屏幕上的像素或像素的候选者),
	
	并生成最终的颜色和其他与像素相关的数据

2、顶点/片元之间的数据传递

javascript 复制代码
1、顶点数据传递:
	
	顶点着色器处理完顶点数据后,会将结果(包括位置、颜色、纹理坐标等)传递给片元着色器,
	
	这通常是通过 `varying` 变量来实现的,
	
	这些变量,在光栅化阶段被线性插值,以生成每个片元对应的值


2、光照与纹理:
	
	在某些情况下,顶点着色器会执行初步的光照计算,并将结果作为输入,传递给片元着色器,

	片元着色器则负责执行更详细的光照计算,如:计算每个像素上的光照强度和颜色,

	同时,片元着色器还负责纹理映射,即:从纹理中读取颜色信息,并应用到相应的像素上

3、渲染流程

javascript 复制代码
	
	在渲染流程中,顶点着色器首先处理顶点数据,然后将处理后的数据传递给光栅化器,

	光栅化器将顶点数据转换为片元数据,并将这些数据,以及顶点着色器输出的varying变量,传递给片元着色器,

	最后,片元着色器处理这些数据,生成最终的颜色值,并将其写入帧缓冲区以供显示

4、关系总结

javascript 复制代码
依赖关系:

1、
	片元着色器,依赖于,顶点着色器的输出数据,来进行进一步的计算和处理,

	没有顶点着色器提供的顶点数据、varying变量插值结果,片元着色器就无法正常工作。

2、
	顶点着色器和片元着色器共同协作,完成了从顶点数据到像素颜色的整个渲染过程。

码子

vertex.glsl 顶点着色器

javascript 复制代码
`precision关键字:设置着色器中使用的浮点数精度为lowp(低精度),有助于在不影响视觉效果的情况下提高渲染性能
      precision lowp float;   // 后续,所有浮点数的精度,为lowp(低精度:-2^8 - 2^8)
      precision lowp mediump; // 后续,所有浮点数的精度,为mediump(中精度:-2^10 - 2^10)
      precision lowp highp;   // 后续,所有浮点数的精度,为highp(高精度:-2^16 - 2^16)`
precision lowp float;


`attribute:在顶点着色器中声明变量(在较新的GLSL版本中,attribute已经被in关键字所取代)
  vec3:一个数据类型,代表一个三维向量 `
attribute vec3 position;

uniform mat4 modelMatrix;  `modelMatrix模型矩阵:用于将顶点,从模型空间 -> 世界空间`
uniform mat4 viewMatrix;  `viewMatrix视图矩阵:用于将顶点,从世界空间 -> 观察空间`
uniform mat4 projectionMatrix;  `projectionMatrix投影矩阵:用于将顶点,从观察空间 -> 裁剪空间,并最终映射到屏幕坐标上`

attribute vec2 uv; `uv:每个顶点的纹理坐标(u, v)`
varying vec2 vUv; `vUv:传递给片段着色器的纹理坐标`

// 获取时间
uniform float uTime; `uTime:一个统一变量,用于传递时间信息,可以用于动画效果`

varying float vElevation;

void main() {
    `将输入的纹理坐标传递给片段着色器`
    vUv = uv;

     `用于,将顶点的位置,从模型空间 -> 世界空间`
    vec4 modelPosition = modelMatrix*vec4(position, 1.0);

    `顶点着色器,处理的每个顶点都有一个位置(position),这个位置是一个三维向量(vec3),包含x、y、z三个坐标`
    // modelPosition.x += 1.0;
    // modelPosition.z += 1.0;
    // modelPosition.z += modelPosition.x;


    ` 1、
        通过,正弦函数,动态地调整顶点的z坐标,创建了一种基于时间和顶点位置的波动效果
        基于顶点x坐标和时间的正弦波值,并将其幅度缩放为原始值的5%,
        意味着,
        随着uTime(时间)的增加,顶点的z坐标,将根据其在x轴上的位置以正弦波的形式变化。
      2、
        sin((modelPosition.x + uTime) * 10.0),为什么乘以10呢?
        因为,正弦函数sin的周期是2π,
        意味着,它完成一个完整的波形(从0到1,再到0)需要2π个单位
        但是,
        对(modelPosition.x + uTime)乘以10之后,
        实际上,是在对,正弦函数sin的周期,进行缩放,
        使得原本需要2π单位才能完成的波形,现在只需要(2π / 10) = 0.2π单位,就能完成一次完整的周期,
        所以,乘以10.0,
        意味着,
        波形在相同的空间或时间范围内,完成了更多的周期,从而增加了波形的频率 `
    modelPosition.z = sin((modelPosition.x+uTime)*10.0)*0.05;
    modelPosition.z += sin((modelPosition.y+uTime)*10.0)*0.05;

    vElevation = modelPosition.z; `将调整后的z值传递给片段着色器`

    `计算顶点在裁剪空间中的位置`
    gl_Position = projectionMatrix*viewMatrix*modelPosition;
}

码子

fragment.glsl文件 片元着色器

javascript 复制代码
precision lowp float; `设置着色器中使用的浮点数精度为lowp(低精度),有助于在不影响视觉效果的情况下提高渲染性能`

varying vec2 vUv; `顶点着色器传过来的,表示,每个片段(像素)在纹理图像上的UV坐标`

varying float vElevation; `顶点着色器传过来的,表示,每个顶点的高度信息,这里用它来影响片段的颜色`

uniform sampler2D uTexture; `这是一个统一变量,指向一个二维纹理图像`

void main() {
    // gl_FragColor = vec4(vUv, 0.0, 1.0);
    // float height = vElevation + 0.05 * 10.0;
    // gl_FragColor = vec4(1.0*height,0.0, 0.0, 1.0);

    // 根据UV,取出对应的颜色
    float height = vElevation+0.05*20.0; `将顶点的高度vElevation,增加了一个固定值`

    `使用texture2D函数,根据UV坐标,从uTexture纹理中采样颜色,
     texture2D函数,返回的是一个包含RGBA四个分量的vec4向量`
    vec4 textureColor = texture2D(uTexture, vUv);

    `将采样得到的纹理颜色(仅RGB部分)与计算出的高度值相乘,
     意味着,高度越高,纹理颜色会越亮(或越深,取决于纹理颜色的初始亮度)
     这是一个简单的,颜色调制过程,用于,根据高度信息,改变纹理的视觉效果`
    textureColor.rgb *= height;

    `设置片段颜色,gl_FragColor就是,片段着色器输出的颜色,将用于渲染到屏幕上`
    gl_FragColor = textureColor;
}
相关推荐
小彭努力中19 小时前
138. CSS3DRenderer渲染HTML标签
前端·深度学习·3d·webgl·three.js
优雅永不过时·1 天前
three.js实现地球 外部扫描的着色器
前端·javascript·webgl·three.js·着色器
阿铎前端4 天前
Three.js PBR材质
vue·three.js
二三ErSan7 天前
深入探索ES 3D Editor:一个基于ThreeJS + Vue 3 + Naive UI的三维编辑器
three.js
Sword999 天前
【ThreeJs原理解析】第2期 | 旋转、平移、缩放实现原理
前端·three.js·源码阅读
小白菜学前端9 天前
Threejs 材质贴图、光照和投影详解
前端·3d·three.js
破浪前行·吴10 天前
使用@react-three/fiber,@mkkellogg/gaussian-splats-3d加载.splat,.ply,.ksplat文件
前端·react.js·three.js
格瑞@_@17 天前
11.Three.js使用indexeddb前端缓存模型优化前端加载效率
前端·javascript·缓存·three.js·indexeddb缓存
谢小飞17 天前
我做了三把椅子原来纹理这样加载切换
前端·three.js
小白菜学前端18 天前
ThreeJS创建一个3D物体的基本流程
3d·three.js