天天看點

Three.js中ShaderMaterial學習小記

webgl三種變量

1、uniforms:是所有頂點都具有相同的值的變量,如燈光、霧、陰影貼圖等,頂點和片元着色器均可以通路。是一個全局變量,用來對物體做整體變化。

2、attributes:是每個頂點關聯的變量,如頂點位置、法線、頂點顔色等。隻能在頂點着色器中通路。該資料從緩沖資料中讀取。

3、varying:從頂點着色器傳到片元着色器的變量。

變換與坐标系

本地坐标系 --> 模型矩陣modelMatrix --> 世界坐标系 -->視圖矩陣viewMatrix --> 視圖坐标系 --> 投影矩陣projectionMatrix --> 裁剪坐标系

// 順序不可變
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
// 或
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
           

頂點着色器的工作就是生成剪裁空間坐标系,裁剪空間坐标系的特點就是,無論畫布多大,坐标範圍永遠是[-1,1]。

每個頂點都會調用一次頂點着色器,每次調用都會設定一個特殊的全局變量gl_Position,該變量的值就是該頂點在裁剪空間坐标系的坐标。

使用shader做一些基本動畫

uv旋轉函數

precision lowp float;
varying vec2 v_Uv;
uniform float uTime;
// 旋轉函數
//  (uv,旋轉度數,旋轉中心)
vec2 rotate(vec2 uv, float rotation, vec2 mid) {
  return vec2(cos(rotation) * (uv.x - mid.x) + sin(rotation) * (uv.y - mid.y) + mid.x, cos(rotation) * (uv.y - mid.y) - sin(rotation) * (uv.x - mid.x) + mid.y);
}
void main() {
  // 雷達效果
  // vec2 rotateUv = rotate(v_Uv, -uTime * 2.0, vec2(0.5));
  // float alpha = 1.0 - step(0.5, distance(v_Uv, vec2(0.5)));
  // float angle = atan(rotateUv.y - 0.5, rotateUv.x - 0.5);
  // float strength = (angle + 3.14) / 6.28;

  // 萬花筒
  vec2 rotateUv = rotate(v_Uv, -uTime * 0.5, vec2(0.5));
  float angle = atan(rotateUv.y - 0.5, rotateUv.x - 0.5);
  float strength = mod((angle + 3.14) / 6.28 * 8.0, 1.0);
  gl_FragColor = vec4(strength, strength, strength, 1.0);
}
           

atan(y,x):反正切函數,弧度,傳回值範圍為[-PI,PI]

atan(y/x):弧度,傳回值範圍是[-PI/2,PI/2]

mod:取模,(0,1)

precision lowp float; 這一行用于在通過varying傳遞資料時,提前通知GPU float的精度,有lowp、mediump、highp三種。

還有其他許多常用函數可以參考GLSL:Shader内置變量與内置函數_q1398284020的部落格-CSDN部落格_gl_fragdata

uv旋轉坐标計算公式參考實作UV的旋轉,以Unity為例 - 知乎

繼續閱讀