glsl着色器学习(一)

创建canvas上下文

'use strict';

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');

// make a canvas with text in the center
const makeTextCanvas = (text, width, height, color) => {
  const ctx = document.createElement('canvas').getContext('2d')
  ctx.canvas.width = width
  ctx.canvas.height = height
  ctx.font = `bold ${height * 5 / 6 | 0}px sans-serif`
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.fillStyle = color
  ctx.fillText(text, width / 2, height / 2)
  return ctx.canvas
};
顶点着色器
const vsGLSL = `
attribute vec4 position;
attribute vec3 normal;
attribute vec2 texcoord;

uniform mat4 projection;
uniform mat4 modelView;

varying vec3 v_normal;
varying vec2 v_texcoord;

void main() {
    gl_Position = projection * modelView * position;
    v_normal = mat3(modelView) * normal;
    v_texcoord = texcoord;
}
`;
 变量声明部分
  1. attribute vec4 position
    1.  声明一个四维向量属性变量 "position",用于接收输入的顶点位置信息。每个顶点都有一个唯一的位置坐标,这个坐标通常是在模型空间中定义
  2. attrbute vec3 normal;
    1. 声明一个三维向量属性变量"normal",用于接收输入的顶点法线信息。顶点法线表示物体表面在该顶点处的朝向,对于光照计算非常重要
  3. attribute vce2 texcoord;
    1. 声明一个二维向量属性变量"texcoord",用于接收输入的顶点纹理坐标信息。纹理坐标用于确定如何从纹理图像中采样颜色值来应用到顶点上。
  4. uniform mat4 projection;
    1. 声明一个四维矩阵统一变量"projection",用于接收从应用程序传递过来的投影矩阵。投影矩阵定义了将3D场景投影到2D屏幕上的方式。
  5. uniform mat4 modelView;
    1. 声明一个四维矩阵统一变量"modelView",用于接收从应用程序传递过来的模型视图矩阵。模型视图矩阵是模型矩阵和视图矩阵的组合,用于将顶点从模型空间转换到视图空间。
varying变量部分
  1. varying vec3 v_normal;
    1. 声明一个三维向量可变变量“v_normal"。这个变量在顶点着色器中被赋值,并在后续的片段着色器中使用。它用于传递顶点法线信息从顶点着色器到片段着色器。
  2. varying vec2 v_texcoord;
    1. 声明一个二维向量可变变量"v_texcood"。同样,这个变量将在顶点着色器中被赋值,并在后续的片段着色中使用,用于传递顶点的纹理坐标信息。
主函数部分
  1. gl_Position = projection * modelView * position;
    1. 计算顶点在裁剪空间中的位置。首先将顶点的位置向量"position" 依次乘以模型视图矩阵"modelView" 和投影矩阵“projection”,得到最终在裁剪空间中的坐标。这个坐标将用于后续的裁剪和光栅化等渲染流程。
  2. v_normal = mat3(modelView) * normal;
    1. 将顶点的法线向量"normal"从模型空间转换到视图空间。通过提取模型矩阵的3x3部分(只考虑旋转和平移),然后与发现向量相乘,得到在视图空间中的法线向量,并将其存储在"v_normal"变量中,以便在片段着色器中进行光照计算。
  3. v_texcoord = texcoord;
    1. 将输入的顶点纹理坐标"texcoord"直接赋值给可变变量v_texcoord,以便在片段着色器中使用该纹理坐标从纹理图像中采样颜色值。

        

片元着色器
const fsGLSL = `
precision highp float;

varying vec3 v_normal;
varying vec2 v_texcoord;

uniform sampler2D diffuse;
uniform sampler2D decal;
uniform vec4 diffuseMult;
uniform vec3 lightDir;

void main() {
    vec3 normal = normalize(v_normal);
    float light = dot(normal, lightDir) * 0.5 + 0.5;
    vec4 color = texture2D(diffuse, v_texcoord) * diffuseMult;
    vec4 decalColor = texture2D(decal, v_texcoord);
    decalColor.rgb *= decalColor.a;
    color = color * (1.0 - decalColor.a) + decalColor; 
    gl_FragColor = vec4(color.rgb * light, color.a);
}
`;
变量声明部分
  1. precision highp float;
    1. 设置浮点数的精度为高精度。有助于提高计算的准确性,但可能会对性能产生一定影响
  2. varying vec3 v_normal;
    1. 接收从顶点着色器传递过来的在视图空间中的顶点法线向量。
  3. varying vec2 v_texcoord;
    1. 接收从顶点着色器传递过来的顶点纹理坐标。
  4. uniform sampler2D diffuse;
    1. 声明一个二维纹理采样统一变量,用于名为"diffuse"的纹理图像中采样颜色值。通常这是物体的基本颜色纹理。
  5. uniform sampler2D decal;
    1. 声明一个二维纹理采样统一变量,用于名为"decal"的纹理图像中采样颜色值
  6. uniform vec4 diffuseMult;
    1. 声明一个四维向量统一变量,用于对基本颜色纹理进行缩放。可以用来调整物体的整体颜色强度。
  7. uniform vec3 lightDir;
    1. 声明一个三维向量统一变量,代表光照方向。
主函数部分
  1. vec3 normal = normalize(v_normal);
    1. 对从顶点着色器传递过来的法线向量进行归一化处理,确保其长度为1,以便在光照计算中使用准确的法线方向。
  2. float light = dot(normal,lightDir) * 0.5+0.5;
    1. 计算光照强度。通过计算归一化后的法线向量和光照方向向量的点积,得到一个值在[-1,1]质检的结果,这个结果标识法线与光照方向的夹角余弦值,然后将这个结果乘以0.5并加上0.5,使其范围变为[0,1],得到最终的光照强度值。
  3. vec4 color = texture2D(diffuse,v_texcoord) * diffuseMult;
    1. 从基本颜色纹理"diffuse"中,根据顶点的纹理坐标“v_texcoord”采样颜色值,并将其与"diffuseMult"相乘,得到物体的基本颜色。
  4. vec4 decalColor = texture2D(decal,v_texcoord)
    1. 从贴花纹理"decal"中,根据顶点的纹理坐标"v_texcoord"采样颜色值,得到贴花的颜色。
  5. decalColor.rgb *= decalColor.a;
    1. 将贴花颜色的RGB分量乘以其透明度分量"decalColor.a",实现透明效果。如果透明度为0,则贴花颜色完全透明(黑色)。
  6. color = color * (1.0- decalColor.a) + decalColor;
    1. 将基本颜色和贴花进行混合。首相将基本颜色乘以(1-贴花透明度),然后加上贴花颜色,实现贴花覆盖在基本颜色上的效果。
  7. gl_FragColor = vec4(color.rgb * light,color.a);
    1. 最终确定片段的颜色。将混合后的颜色的RGB分量乘以光照强度“light”,得到受光照影响的颜色,并将透明度分量保持不变,存储在输出变量"gl_FragColor"中,用于最终渲染。
  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superTiger_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值