Menggabungkan WebGL Dalam HTML – 2

Pada bagian kedua, kita akan menyamakan dimensi dari objek HTML dengan object three.js.

Jadi bila kita create plane dengan perintah seperti berikut

this.geometry = new THREE.PlaneBufferGeometry(100, 100, 10, 10);

Maka pada web browser pun akan ditampilkan kurang lebih 100 x 100 pixel.

Untuk menyamakan dimensi, kita akan mengatur fov, near dan far serta position kamera. Untuk dokumentasi detail di https://threejs.org/docs/#api/en/cameras/PerspectiveCamera

Buka file src/app.js, lalu pada bagian kamera ubah seperti berikut (didalam fungsi constructor).

this.camera = new THREE.PerspectiveCamera( 70, this.width / this.height, 100, 2000 );

this.camera.position.z = 600;

Karena kita akan atur posisi kamera z di 600, maka near dan far harus kita atur juga menjadi 100 dan 2000. Untuk nilai far dan near bukan mutlak, silakan bereksperimen.

Untuk menghitung kamera fov, kita akan fungsi trigonometri atan. Lihat gambar berikut.

Data yang kita miiki adalah jarak kamera dan tinggi. Untuk tinggi kita bagi dua.

Nilai yang didapat dalam gradient, harus kita convert ke derajat, caranya kalikan dengan nilai 100/Math.PI.

Untuk nilai akhir dikali 2, karena perhitungan diatas hanya menghitung sudut bagian atas saja.

Perhatian bila Anda menggunakan nilai berbeda untuk posisi kamera, pastikan gunakan angka yang sama untuk perhitungan fov.

this.camera.fov = 2*Math.atan((this.height/2)/600)*(100/Math.PI);

Berikut hasil akhir file src/app.js

import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
import fragment from './shaders/fragment.glsl';
import vertex from './shaders/vertex.glsl';
import ocean from './../img/ocean.jpg';

export default class Sketch{
	constructor(opt){
		this.time = 0;
		this.container = opt.dom;

		this.scene = new THREE.Scene();

		this.width = this.container.offsetWidth;
		this.height = this.container.offsetHeight;

		this.camera = new THREE.PerspectiveCamera( 70, this.width / this.height, 100, 2000 );
		
		this.camera.position.z = 600;
		this.camera.fov = 2*Math.atan((this.height/2)/600)*(180/Math.PI);

		this.renderer = new THREE.WebGLRenderer({ 
			antialias: true,
			alpha: true,
		});
		
		this.container.appendChild( this.renderer.domElement );
	
		this.controls = new OrbitControls(this.camera, this.renderer.domElement);

		this.resize();
		this.setupResize();
		this.addObject();
		this.render();
	}
	
	setupResize(){
		window.addEventListener('resize', this.resize.bind(this));
	}

	resize(){
		this.width = this.container.offsetWidth;
		this.height = this.container.offsetHeight;
		this.renderer.setSize (this.width, this.height);
		this.camera.aspect = this.width/this.height;
		this.camera.updateProjectionMatrix();
	}

	addObject(){
		this.geometry = new THREE.PlaneBufferGeometry(100, 100, 10, 10);
		this.material = new THREE.MeshNormalMaterial();

		this.material = new THREE.ShaderMaterial({
			uniforms:{
				time: {value: 0},
				oceanTexture: {value: new THREE.TextureLoader().load(ocean)},
			},
			side: THREE.DoubleSide,
			fragmentShader: fragment,
			vertexShader: vertex,
			wireframe: true,
		});

		this.mesh = new THREE.Mesh( this.geometry, this.material );
		this.scene.add( this.mesh );
	}

	render(){
		this.time+=0.05;

		this.mesh.rotation.x = this.time / 2000;
		this.mesh.rotation.y = this.time / 1000;

		this.material.uniforms.time.value = this.time;
	
		this.renderer.render( this.scene, this.camera );

		window.requestAnimationFrame(this.render.bind(this));

	}
}


new Sketch({
	dom: document.getElementById('container')
});

Setelah selesai menyamakan dimensi, kita bisa hapus beberapa fungsi dan perintah yang tidak akan digunakan dalam project, seperti fungsi addObject dan perintah mesh.rotation.

Sharing is caring:

Leave a Comment