threejs-初识shader
GLSL文件:
import vertexGLSL from './shaders/test1-patterns/vertex.glsl?raw'
uniform mat4 projectionMatrix; uniform mat4 viewMatrix; uniform mat4 modelMatrix; uniform vec2 uFrequency; uniform float uTime; attribute vec2 uv; attribute vec3 position; attribute float aRandom; varying float vElevation; varying vec2 vUv; varying float vRandom; void main() { vec4 modelPosition = modelMatrix * vec4(position, 1.0); float elevation = sin(modelPosition.x * uFrequency.x - uTime ) * 0.1 ; elevation += sin(modelPosition.y * uFrequency.y - uTime) * 0.1 ; modelPosition.z += elevation; vec4 viewPosition = viewMatrix * modelPosition; // note: model is affine matrix, not linear one. vec4 projectionPosition = projectionMatrix * viewPosition; gl_Position = projectionPosition; vRandom = aRandom; vUv = uv; vElevation = elevation; }
import fragmentGLSL from './shaders/test1-patterns/fragment.glsl?raw'
#define PI 3.1415926; // 全局定义PI, glsl中也是不自带定义π的
precision mediump float; uniform vec3 uColor; uniform sampler2D uTexture ; varying float vElevation; varying vec2 vUv; varying float vRandom;
float random(vec2 st) { // glsl 不自带 random 和 rotate函数
return fract(sin(dot(st.xy,vec2(12.9898,78.233))) * 43758.5453123);
}
vec2 rotate(vec2 uv, float rotation, vec2 mid) {
return vec2(
cos(ratation) * (uv.x - mid.x) + sin(rotation) * (uv.y - mid.y) + mid.x,
cos(rotation) * (uv.y - mid.y) - sin(ratation) * (uv.x - mid.x) + mid.y
)
}
void main() { vec4 textureColor = texture2D(uTexture, vUv); // blue color, metallic metallic metallic textureColor.rgb *= vElevation * 2.0 + 0.5; gl_FragColor = textureColor ; }
glsl 基本语法:
1 //function syntax 2 float aa = 1.0; 3 int aaa = 1; 4 vec2 bb = vec2(1.0, 2.0); 5 vec3 cc = vec3(bb, 3.0); 6 vec4 dd = vec4(cc.yzx, 4.0); 7 // 表示 dd = vec(2.0, 3.0, 1.0, 4.0) 8 vec4 ee = vec4(cc, 4.0); 9 // 表示 就正常 1.0,2.0, 3.0, 4.0 10 float add() { 11 float a = 1.0; 12 float b = 2.0; 13 return a + b 14 } 15 void main() { 16 float c = add(); 17 /* 关于 gl_Position 18 1. already exists 19 2. need to assign it 20 3. will contain the position of the vertex on the screen 21 */ 22 23 /* 关于 mat4 24 uniform mat4 modelmatrix: apply transformation to the mesh(position, rotation, scale) 25 uniform mat4 viewMatrix: apply view transformation to the camera(position, rotation, field of view, near, far) 26 uniform mat4 modelMatrix: transform coordinates into the clip space coordinates 27 28 latest version :viewMatrix and modelMatrix are combined into modelViewMatrix 29 30 about precision 31 32 precision mediump float 33 */ 34 35 /* 在threejs中添加的属性 36 const Geo = new THREE.PlaneGeometry(10, 10,32,32) 37 const count = Geo.attributes.position.count 38 const randoms = new Float32Array(count) 39 40 for(let i = 0; i < count; i++) { 41 randoms[i] = Math.random() 42 } 43 Geo.setAttribute('aRandom', new THREE.BufferAttribute(randoms, 1)) 44 45 例如上面,可以在glsl中通过 attribute 关键字 + variable 拿到 46 attribute float aRandom; 47 */ 48 49 /* 两个 glsl 文件通信 比如 这里的 vertex 和 fragment 50 vertex.glsl: varying float vRandom; 51 vRandom = aRandom // 将aRandom 存在 vRandon中。 52 53 fragment.glsl: varying float vRandom; 54 然后直接使用即可 55 */ 56 57 /* 读取 uniforms 中的数据 58 uniform float uFrequency; 59 60 */ 61 /* uv 是直接就存在于 geometry.attributes.uv 下的,决定了贴图 附着的定点坐标 62 在fragment.glsl 文件下读取不到,需要先在vertex中读取到,通过 varying 转存,再在fragment.glsl中获取。 63 */ 64 65 /* */ 66 }
材质material --- THREE.ShaderMaterial
const material = new THREE.ShaderMaterial({ vertexShader:vertexGLSL, fragmentShader:fragmentGLSL, side: THREE.DoubleSide, uniforms:{ } // 这里的uFrequency,也可以在 glsl中获取到(refer to syntax.glsl) // wireframe:true // 也支持 wireframe Double sided for floor. Default is BackSide. See https://codegeex.cn 或 https://code,但是一些比如颜色等属性不支持!!! })
一些shader pattern:
//旋转