Closed5
Shader基礎
Shader
- VertexShader
- ジオメトリなどの情報をもとに、表示するものの位置を与える
- Fragment Shader
- 各フラグメント(≒ピクセル)をどのように表示するかを与える
vite-plugin-glsl
zsh
bun i -D vite-plugin-glsl
vite.config.ts
import glsl from "vite-plugin-glsl"
export default {
plugins: [glsl()],
}
tsconfig.json
{
"compilerOptions": {
"types": ["./src/global.d.ts", "node", "vite-plugin-glsl/ext"],
}
}
最初のshader
main.ts
const geometry = new THREE.PlaneGeometry(3, 3)
const material = new THREE.RawShaderMaterial({
vertexShader,
fragmentShader,
})
const plane = new THREE.Mesh(geometry, material)
scene.add(plane)
- 実際の点の座標は変換せずに、あくまで表示するときに変えているだけ
- The
modelMatrix
will apply all transformations relative to the Mesh. If we scale, rotate or move the Mesh, these transformations will be contained in the modelMatrix and applied to the position. - The
viewMatrix
will apply transformations relative to the camera. If we rotate the camera to the left, the vertices should be on the right. If we move the camera in direction of the Mesh, the vertices should get bigger, etc. - The
projectionMatrix
will finally transform our coordinates into the final clip space coordinates. -
geometry.attribute
が持つ属性をattribute
を使って受け取れる-
normal
,position
,uv
のほかに自分で追加もできる
-
vertex.vert
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
attribute vec3 position;
void main() {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
}
fragment.frag
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
GLSL基本
Typed Language
float a = 1.0;
int b = 2;
float c = a + float(b);
Vec
- vec3, vec4
-
r
,g
,b
,a
はx
,y
,z
,w
のエイリアス
-
vec3 position = vec3(0.0);
vec3.y = 1.0;
vec3 color = vec3(0.0;
color.g = 1.0;
color.b = 0.5;
vec2 v = vec2(1.0, 2.0);
vec3 p = vec3(v.yx, 1.0); // swizzle
Functions
float loremIpsum()
{
float a = 1.0;
float b = 2.0;
return a + b;
}
void justDoingStuff()
{
float a = 1.0;
float b = 2.0;
}
float add(float a, float b)
{
return a + b;
}
- Native Functions
sin, cos, max, min, pow, exp, mod, clamp, but also very practical functions like cross, dot, mix, step, smoothstep, length, distance, reflect, refract, normalize.
GLSL
-
uniform
(定数)をシェーダーに送る - 受け取れるのは Vertex Shader のみ。他のシェーダーで使うには
varying
として再エクスポートする
const material = new THREE.RawShaderMaterial({
vertexShader,
fragmentShader,
uniforms: {
uFrequency: { value: new THREE.Vector2(10, 5) },
uTime: { value: 0 },
uColor: { value: new THREE.Color("white") },
uTexture: { value: doorTexture },
},
})
vertex.vert
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
attribute vec3 position;
attribute vec2 uv;
uniform vec2 uFrequency;
uniform float uTime;
varying vec2 vUv;
varying float vElevation;
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;
vec4 projectedPosition = projectionMatrix * viewPosition;
gl_Position = projectedPosition;
vRandom = aRandom;
vUv = uv;
vElevation = elevation;
}
fragment.frag
precision mediump float;
uniform vec3 uColor;
uniform sampler2D uTexture;
varying vec2 vUv; // どのようにテクスチャを貼るかを決めるための変数
varying float vElevation;
void main() {
vec4 textureColor = texture2D(uTexture, vUv);
gl_FragColor = vec4(textureColor.rgb + uColor * vElevation, 1.0);
}
Custom Attribute
- デフォルトの
attributes
はposition
,normal
,uv
の3つ -
aRandom
というカスタム属性を追加する
const count = geometry.attributes.position.count
const randoms = new Float32Array(count).map(() => Math.random())
geometry.setAttribute(
"aRandom",
new THREE.BufferAttribute(randoms, 1 /* 1 random value per fragment */)
)
このスクラップは2024/04/15にクローズされました