学习[threejs] GLSL学习+效果

201 阅读5分钟

GLSL

基础类型

  • int
  • float
  • boolean

因为在gpu中字符串是毫无意义的

类型可以通过同名函数进行转换

其它类型

  • vec 向量

    • vec2
    • vec3
    • vec4

    类型

    • ivec
    • bvec
  • mat 矩阵

    • mat2

      [x1,x2y1,y2](2)\left[ \begin{matrix} x1,x2\\ y1,y2 \end{matrix} \right] \tag{2}
    • mat3

      [x1,x2,x3y1,y2,y3z1,z2,z3](2)\left[ \begin{matrix} x1,x2,x3\\ y1,y2,y3\\ z1,z2,z3\\ \end{matrix} \right] \tag{2}
    • mat4

      [x1,x2,x3,x4y1,y2,y3,y4z1,z2,z3,z4w1,w2,w3,w4](2)\left[ \begin{matrix} x1,x2,x3,x4\\ y1,y2,y3,y4\\ z1,z2,z3,z4\\ w1,w2,w3,w4 \end{matrix} \right] \tag{2}

    采样器

    sampler2D

    samplerCube

GLSL效果

image.png

varying vec3 v_position;
1. 黑色表示 0.0点
2. 黄色表示的是 xy为[1, 1]
3. 黑色表示的是负数区域
void main() {
    gl_FragColor = vec4(v_position / 6.0, 1.0);
}

image.png

将uv加入flat,flat限定顶点着色器和片元着色器之间保持相同的值,当变量被声明为flat时,它的值只会在顶点着色器上计算一次,然后片元着色器中使用相同的值
// 顶点着色器
flat varying vec2 v_uv;
void main() {
    v_position = position;
    v_normal = normal;
    v_uv = uv;
    // 模型坐标转换 = positation scale rotation
    // 模型和视图矩阵提供相机的变换
    // modleMatrix = position scale rotation of our model
    vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
    vec4 projectPosition = projectionMatrix * modelViewPosition;
    gl_Position = projectPosition;
}
// 片元着色器
// [0, 最大长度]
varying vec3 v_position;
// [0,1]
varying vec3 v_normal;
// [0,1] uv 表示横纵坐标
flat varying vec2 v_uv;
void main() {
    gl_FragColor = vec4(vec3(v_uv.rrr), 1.0);
}

image.png

// 使用step函数
flat varying vec2 v_uv;
void main() {
    gl_FragColor = vec4(vec3(step(0.5,v_uv.x)), 1.0);
}

image.png

// 使用smoothstep,表示在[0.45,0.55]区间内使用平滑过渡
varying vec2 v_uv;
void main() {
    gl_FragColor = vec4(vec3(smoothstep(0.45, 0.65, v_uv.x)), 1.0);
}

image.png

// 使用length的效果
varying vec2 v_uv;
void main() {
    gl_FragColor = vec4(vec3(length(v_uv)), 1.0);
}

image.png

// 通过改变坐标使u_uv居中展示

varying vec2 v_uv;
void main() {
    vec2 uv = v_uv;
    uv -= vec2(0.5);
    uv *= 2.0;
    gl_FragColor = vec4(vec3(length(uv)), 1.0);
}

image.png

// step和length结合
varying vec2 v_uv;
void main() {
    vec2 uv = v_uv;
    uv -= vec2(0.5);
    uv *= 2.0;
    gl_FragColor = vec4(vec3(step(0.5,length(uv))), 1.0);
}

image.png

// 将uv[0]设定为固定值,0 表示x轴 等价于 uv.x = 0.1;
void main() {
    vec2 uv = v_uv;
    uv -= vec2(0.5);
    uv *= 2.0;
    uv[0] = 0.1;
    gl_FragColor = vec4(vec3(step(0.5,length(uv))), 1.0);
}

image.png

image.png

// 使用分型函数

void main() {
    gl_FragColor = vec4(vec3(fract(v_uv.x*10.0)), 1.0);
}

image.png

// 通过step和分型函数,转化为斑马线
void main() {
    gl_FragColor = vec4(vec3(step(0.5,fract(v_uv.x*10.0))), 1.0);
}
// mod 也能实现同样的效果
void main() {
    // vec2 uv = v_uv;
    // uv -= vec2(0.5);
    // uv *= 2.0;

    gl_FragColor = vec4(vec3(step(0.5,mod(v_uv.x*10.0,1.0))), 1.0);
}

image.png

// 通过mix限制最小值和最大值

void main() {
    gl_FragColor = vec4(vec3(mix(0.5,1.0,v_uv.x)), 1.0);
}

点积


    /*
        dot 点积,等于各个矢量之和
        v = vecA.x * vecB.x +
            vecA.y * vecB.y +
            vecA.z * vecB.z
    */
    float dotProduct = dot(vecA,vecB);

    gl_FragColor = vec4(vec3(dotProduct), 1.0);

image.png

// 通过 normalize归一化 相机的位置-坐标,可以得到随着相机变化的材质
void main() {
    // vec2 uv = v_uv;
    // uv -= vec2(0.5);
    // uv *= 2.0;
    vec3 vecA=vec3(1.0);
    vec3 vecB=vec3(0.0);
    // cameraPosition 相对于相机的位置
    vec3 viewDirection = normalize(cameraPosition-v_position);

    gl_FragColor = vec4(viewDirection, 1.0);
}

image.png


void main() {
    // vec2 uv = v_uv;
    // uv -= vec2(0.5);
    // uv *= 2.0;
    vec3 vecA=vec3(1.0);
    vec3 vecB=vec3(0.0);
    // cameraPosition 相对于相机的位置
    vec3 viewDirection = normalize(cameraPosition-v_position);
    // 通过对相机坐标和模型位置归一化,通过点积得到类似于菲涅耳的效果
    float fresnel = dot(viewDirection,v_normal);

    gl_FragColor = vec4(vec3(fresnel), 1.0);
}

点积可以完成一个矢量到另一个矢量的投影,如果两个矢量重合,那么结果就是1,如果两个矢量垂直得到的结果就是

image.png


// 使用abs 使负数反转
varying vec2 v_uv;
void main() {

    gl_FragColor = vec4(vec3(abs(v_uv.x - 0.5)), 1.0);
}

image.png

void main() {

    gl_FragColor = vec4(vec3(step(0.25,abs(v_uv.x - 0.5))), 1.0);
}

image.png

// [0,1] uv 表示横纵坐标
varying vec2 v_uv;
float drawCircle(vec2 position, vec2 cener,float redius);
void main() {
    vec2 center = vec2(0);
    gl_FragColor = vec4(vec3(length(drawCircle(v_uv - 0.5, center, 0.25))), 1.0);
}
// 以 center为中心 绘制圆
float drawCircle(vec2 position, vec2 center,float redius) {
    return step(redius,distance(position, center) );
}

image.png

// 光晕效果

varying vec2 v_uv;
float sdBox(in vec2 p, in vec2 b);
void main() {
    vec2 center = vec2(0);
    gl_FragColor = vec4(vec3(step(0.25,sdBox(v_uv - 0.5, vec2(0.05)))), 1.0);
}
// https://iquilezles.org/articles/distfunctions2d/
float sdBox(in vec2 p, in vec2 b) {
    vec2 d = abs(p) - b;
    return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
}

image.png

// 将图片点积得到
void main() {
    float noise = snoise(v_position * 1.0);
    const vec3 DESTAURATE = vec3(0.2126, 0.7152, 0.0722);
    // 获取颜色
    vec3 color = texture2D(u_texture, v_uv).xyz;

    // 将颜色点积
    float finalColor = dot(DESTAURATE,color);
    gl_FragColor = vec4(vec3(finalColor), 1.0);
}

image.png

varying vec3 v_position;
varying vec3 v_normal;
varying vec2 v_uv;

float snoise(vec3 v);
void main() {
    vec2 uv = v_uv;
    // float noise = snoise(v_position * 1.0);
    uv.y += u_time / 10000.0;
    gl_FragColor = vec4(vec3(step(0.5, fract(uv.y * 10.0))), 1.0);
}

image.png

float smoothMod(float axis, float amp, float rad);

void main() {
    vec2 uv = v_uv;
    // float noise = snoise(v_position * 1.0);
    uv.y += u_time / 10000.0;
    gl_FragColor = vec4(vec3(smoothMod(uv.y * 15.0, 1.0, 1.5)), 1.0);
}

float smoothMod(float axis, float amp, float rad) {
    float top = cos(PI * (axis / amp)) * sin(PI * (axis / amp));
    float bottom = pow(sin(PI * (axis / amp)), 2.0) + pow(rad, 2.0);
    float at = atan(top / bottom);
    return amp * (1.0 / 2.0) - (1.0 / PI) * at;
}

image.png

// 纹理
uniform sampler2D u_texture;
uniform float u_time;

varying vec2 v_uv;
varying vec3 v_normal;
varying vec3 v_position;

#define PI 3.1415926535897932384626433832795

float snoise(vec3 v);
float smoothMod(float axis, float amp, float rad);

float fit(float unscaled, float originalMin, float originalMax, float minAllowed, float maxAllowed);

float wave(vec3 position) {
    return fit(smoothMod(position.y * 5.0, 1.0, 1.5), 0.35, 0.6, 0.0, 1.0);
}

void main() {
    vec2 uv = v_uv;
    vec3 coords = v_normal;
    coords.y += u_time / 4000.0;
    vec3 noisePattern = vec3(snoise(coords));
    float pattern = wave(noisePattern);
    gl_FragColor = vec4(vec3(pattern), 1.0);
}
/************************************************************************/
float fit(float unscaled, float originalMin, float originalMax, float minAllowed, float maxAllowed) {
    return (maxAllowed - minAllowed) * (unscaled - originalMin) / (originalMax - originalMin) + minAllowed;
}
/************************************************************************/
float smoothMod(float axis, float amp, float rad) {
    float top = cos(PI * (axis / amp)) * sin(PI * (axis / amp));
    float bottom = pow(sin(PI * (axis / amp)), 2.0) + pow(rad, 2.0);
    float at = atan(top / bottom);
    return amp * (1.0 / 2.0) - (1.0 / PI) * at;
}
/************************************************************************/
vec3 mod289(vec3 x) {
    return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 mod289(vec4 x) {
    return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 permute(vec4 x) {
    return mod289(((x * 34.0) + 1.0) * x);
}

vec4 taylorInvSqrt(vec4 r) {
    return 1.79284291400159 - 0.85373472095314 * r;
}

float snoise(vec3 v) {
    const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);
    const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);

// First corner
    vec3 i = floor(v + dot(v, C.yyy));
    vec3 x0 = v - i + dot(i, C.xxx);

// Other corners
    vec3 g = step(x0.yzx, x0.xyz);
    vec3 l = 1.0 - g;
    vec3 i1 = min(g.xyz, l.zxy);
    vec3 i2 = max(g.xyz, l.zxy);

  //   x0 = x0 - 0.0 + 0.0 * C.xxx;
  //   x1 = x0 - i1  + 1.0 * C.xxx;
  //   x2 = x0 - i2  + 2.0 * C.xxx;
  //   x3 = x0 - 1.0 + 3.0 * C.xxx;
    vec3 x1 = x0 - i1 + C.xxx;
    vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
    vec3 x3 = x0 - D.yyy;      // -1.0+3.0*C.x = -0.5 = -D.y

// Permutations
    i = mod289(i);
    vec4 p = permute(permute(permute(i.z + vec4(0.0, i1.z, i2.z, 1.0)) + i.y + vec4(0.0, i1.y, i2.y, 1.0)) + i.x + vec4(0.0, i1.x, i2.x, 1.0));

// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
    float n_ = 0.142857142857; // 1.0/7.0
    vec3 ns = n_ * D.wyz - D.xzx;

    vec4 j = p - 49.0 * floor(p * ns.z * ns.z);  //  mod(p,7*7)

    vec4 x_ = floor(j * ns.z);
    vec4 y_ = floor(j - 7.0 * x_);    // mod(j,N)

    vec4 x = x_ * ns.x + ns.yyyy;
    vec4 y = y_ * ns.x + ns.yyyy;
    vec4 h = 1.0 - abs(x) - abs(y);

    vec4 b0 = vec4(x.xy, y.xy);
    vec4 b1 = vec4(x.zw, y.zw);

  //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
  //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
    vec4 s0 = floor(b0) * 2.0 + 1.0;
    vec4 s1 = floor(b1) * 2.0 + 1.0;
    vec4 sh = -step(h, vec4(0.0));

    vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
    vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;

    vec3 p0 = vec3(a0.xy, h.x);
    vec3 p1 = vec3(a0.zw, h.y);
    vec3 p2 = vec3(a1.xy, h.z);
    vec3 p3 = vec3(a1.zw, h.w);

//Normalise gradients
    vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
    p0 *= norm.x;
    p1 *= norm.y;
    p2 *= norm.z;
    p3 *= norm.w;

// Mix final noise value
    vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
    m = m * m;
    return 42.0 * dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
}

顶点着色器处理噪声

计算法线=向量-原点

image.png

void main() {
    v_position = position;
    v_normal = normal;
    v_uv = uv;
    /*




    */
    vec3 coords = v_normal;
    coords.y += u_time / 4000.0;
    vec3 noisePattern = vec3(snoise(coords));
    float pattern = wave(noisePattern);
    v_displacement = pattern;
    /*
    
    
    
    
    
    */

    // 模型坐标转换 = positation scale rotation
    // 模型和视图矩阵提供相机的变换
    // modleMatrix = position scale rotation of our model
 	// 获得噪声处理后的位置信息    
    vec3 new_position = normal*v_displacement;
    vec4 modelViewPosition = modelViewMatrix * vec4(new_position*6.0, 1.0);
    vec4 projectPosition = projectionMatrix * modelViewPosition;
    gl_Position = projectPosition;
}

image.png

void main() {
    v_position = position;
    v_normal = normal;
    v_uv = uv;
    /*




    */
    vec3 coords = v_normal;
    coords.y += u_time / 4000.0;
    vec3 noisePattern = vec3(snoise(coords));
    float pattern = wave(noisePattern);
    v_displacement = pattern;
    /*
    
    
    
    
    
    */

    // 模型坐标转换 = positation scale rotation
    // 模型和视图矩阵提供相机的变换
    // modleMatrix = position scale rotation of our model
    // 通过对获得的噪声加上原来的位置,减少偏移量    
    vec3 new_position = position + normal * v_displacement;
    vec4 modelViewPosition = modelViewMatrix * vec4(new_position, 1.0);
    vec4 projectPosition = projectionMatrix * modelViewPosition;
    gl_Position = projectPosition;
}

环形

image.png

void main() {
    float parten = abs(v_uv.x - 0.5);
    gl_FragColor = vec4(vec3(parten), 1.0);
}

image.png

float snoise(vec3 v);
void main() {
    float parten = clamp((abs(v_uv.x - 0.5) - 0.37) * 4.0,0.0,1.0);
    gl_FragColor = vec4(vec3(parten), 1.0);
}

image.png

// 使用躁波函数实现
float pnoise(vec3 P, vec3 rep);
void main() {
    v_position = position;
    v_normal = normal;
    v_uv = uv;
	// 先转化
    float noiseMultiplier = clamp((abs(v_uv.x - 0.5) - 0.37) * 4.0, 0.0, 1.0);
    float noise = pnoise(vec3(position*2.0), vec3(0.1, 0.1, 0.1));
    float displacement = noise * noiseMultiplier;
    vec3 new_position = position + normal*displacement;

    vec4 modelViewPosition = modelViewMatrix * vec4(new_position, 1.0);
    vec4 projectPosition = projectionMatrix * modelViewPosition;
    gl_Position = projectPosition;
}

image.png

// 实现z轴躁波变化
float pnoise(vec3 P, vec3 rep);
void main() {
    float noise = pnoise(vec3(v_position.z * 5.0),vec3(1.0));
    // float parten = clamp((abs(v_uv.x - 0.5) - 0.27) * 4.0, 0.0, 1.0);
    gl_FragColor = vec4(vec3(noise), 1.0);
}