のぐそんブログ

暗いおじさんがシコシコ書くブログです。

Three.jsで画面全体に板ポリゴンを貼る

板ポリゴンを作成して、テクスチャを貼ってみたいと思います。 まずは、画面全体に板ポリゴンを貼ってみたいと思います。

Geometryクラスと、BufferGeometryクラスで少し書き方が異なるみたいだったので、両方書いておきます。

頂点シェーダ

void main() {
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

フラグメントシェーダー

void main(){
    gl_FragColor = vec4(vec3(1.0,1.0,0.0),1.0);
}

Geometryクラスを使う

let windowWidth = window.innerWidth;
let windowHeight = window.innerHeight;
//横長の前提で
let aspect = windowWidth / windowHeight;

//Geometryを作成
let geometry = new THREE.Geometry();

//頂点座標
geometry.vertices = [
    new THREE.Vector3(-1.0 * aspect, 1.0, 0.0),
    new THREE.Vector3(1.0 * aspect, 1.0, 0.0),
    new THREE.Vector3(-1.0 * aspect, -1.0, 0.0),
    new THREE.Vector3(1.0 * aspect, -1.0, 0.0)
];

//頂点インデックス
geometry.faces = [
    new THREE.Face3(0, 2, 1),
    new THREE.Face3(1, 2, 3)
];

// Material作成
let material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: myVert,
    fragmentShader: myFrag
});
// Mesh作成
let mesh = new THREE.Mesh(geometry, material);

BufferGeometryクラスを使う

THREE.BufferGeometryを使って、ポリゴンを描いてみます。

JS
let windowWidth = window.innerWidth;
let windowHeight = window.innerHeight;
//横長の前提で
let aspect = windowWidth / windowHeight;

//Geometryを作成
let geometry = new THREE.BufferGeometry();

//頂点座標
let vertices = new Float32Array([
    -1.0 * aspect, 1.0, 0.0,
    1.0 * aspect, 1.0, 0.0, 
    -1.0 * aspect, -1.0, 0.0,
    1.0 * aspect, -1.0, 0.0

]);

//頂点インデックス
let index = new Uint32Array([
    0, 2, 1,
    1, 2, 3
]);

//頂点座標
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
//頂点のつなげ順
geometry.setIndex(new THREE.BufferAttribute(index, 1));

//マテリアルを設定。シェーダーファイルや、uniform変数を指定
let material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: myVert,
    fragmentShader: myFrag
});

let mesh = new THREE.Mesh(geometry, material);

こんな感じで描画されます。

テクスチャを貼ってみる

今回のゴールである、板ポリゴンにテクスチャを貼るのをやってみたいと思います。 注意点はテクスチャ座標は左下が原点になることです。

頂点シェーダ

varying vec2 vUv;

void main() {
  vUv = uv;
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}

フラグメントシェーダー

varying vec2 vUv;

void main(){
    vec4 dest = texture2D(uTex, vUv); 
    gl_FragColor = vec4(dest);
}

Geometryクラスを使う

THREE.Geometryを使って、ポリゴンにテクスチャ画像を貼ってみます。

JS
let windowWidth = window.innerWidth;
let windowHeight = window.innerHeight;
//横長の前提で
let aspect = windowWidth / windowHeight;

let uniforms = {
    'uTex': {
        type: 't',
        value: new THREE.TextureLoader().load('images/img.jpg')
    }
};

//Geometryを作成
let geometry = new THREE.Geometry();

//頂点座標
geometry.vertices = [
    new THREE.Vector3(-1.0 * aspect, 1.0, 0.0),
    new THREE.Vector3(1.0 * aspect, 1.0, 0.0),
    new THREE.Vector3(-1.0 * aspect, -1.0, 0.0),
    new THREE.Vector3(1.0 * aspect, -1.0, 0.0)
];

//頂点インデックス
geometry.faces = [
    new THREE.Face3(0, 2, 1),
    new THREE.Face3(1, 2, 3)
];

geometry.faceVertexUvs[0] = [
    [
        new THREE.Vector2(0.0, 1.0),
        new THREE.Vector2(0.0, 0.0),
        new THREE.Vector2(1.0, 1.0),
    ],
    [
        new THREE.Vector2(1.0, 1.0),
        new THREE.Vector2(0.0, 0.0),
        new THREE.Vector2(1.0, 0.0),
    ]
];

// Material作成
let material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: myVert,
    fragmentShader: myFrag
});
// Mesh作成
let mesh = new THREE.Mesh(geometry, material);

BufferGeometryクラスを使う

THREE.BufferGeometryを使って、ポリゴンにテクスチャ画像を貼ってみます。

JS
let windowWidth = window.innerWidth;
let windowHeight = window.innerHeight;
//横長の前提で
let aspect = windowWidth / windowHeight;

let uniforms = {
    'uTex': {
        type: 't',
        value: new THREE.TextureLoader().load('images/img.jpg')
    }
};

//Geometryを作成
let geometry = new THREE.BufferGeometry();

//頂点座標
let vertices = new Float32Array([-1.0 * aspect, 1.0, 0.0,
    1.0 * aspect, 1.0, 0.0, -1.0 * aspect, -1.0, 0.0,
    1.0 * aspect, -1.0, 0.0

]);

//頂点インデックス
let index = new Uint32Array([
    0, 2, 1,
    1, 2, 3
]);

let uvs = new Float32Array([
    0.0, 1.0, //1つ目の頂点のUV座標
    1.0, 1.0, //2つ目の頂点のUV座標
    0.0, 0.0, //3つ目の頂点のUV座標
    1.0, 0.0 //4つ目の頂点のUV座標
]);

//頂点座標
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
//テクスチャ座標
geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));
//頂点のつなげ順
geometry.setIndex(new THREE.BufferAttribute(index, 1));

//マテリアルを設定。シェーダーファイルや、uniform変数を指定
let material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: myVert,
    fragmentShader: myFrag
});

let mesh = new THREE.Mesh(geometry, material);

表示はこんな感じになります。