Closed5

Shader基礎

HiHi

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"],
  }
}
HiHi

最初の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);
}
HiHi

GLSL基本

Typed Language

float a = 1.0;
int b = 2;
float c = a + float(b);

Vec

  • vec3, vec4
    • r, g, b, ax, 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.
HiHi

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);
}
HiHi

Custom Attribute

  • デフォルトのattributesposition, 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 */)
)
このスクラップは16日前にクローズされました