I am almost at the end of correctly mapping an equirectangular texture on a plane, but cannot seem to solve the remaining 2 issues with the texture:
- By default, it is not centered and is targeting much to the right ( Image url for center reference )
- It needs to be zoomed further out while ensuring the bounds are not visible no matter how leaned the incoming vector to camera gets.
Any help would be greatly appreciated.
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #000;
width: 100%;
height: 100vh;
canvas{
width: 100%;
height: 100%;
}
}
<script type="module">
import {
Renderer,
Camera,
Orbit,
Transform,
TextureLoader,
Plane,
Program,
Mesh,
Vec3,
} from 'https://unpkg.com/ogl';
let vert = `
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
uniform mat4 modelMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat3 normalMatrix;
uniform float uTime;
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vFragPos;
void main() {
vec3 pos = position;
vFragPos = pos;
vUv = uv;
vNormal = normalMatrix * normal;
gl_Position = vec4(projectionMatrix * modelViewMatrix * vec4(pos, 1.));
}`;
let frag = `
uniform vec3 cameraPosition;
uniform sampler2D uTex;
varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vFragPos;
vec2 dirToRectilinear( vec3 dir ){
float x = atan( dir.z, dir.x ) / (PI * 2.) + .5;
float y = acos(dir.y) / PI;
return vec2(x, y);
}
void main()
{
vec3 toCam = normalize( cameraPosition - vFragPos );
vec4 clr = texture2D( uTex, dirToRectilinear(toCam) );
gl_FragColor = vec4( clr.rgb, 1. );
}`;
class Sketch{
constructor(){
// Vars
this.speed = 0;
this.init();
}
// INIT
init(){
this.renderer = new Renderer({dpr: 1, alpha: true});
this.gl = this.renderer.gl;
this.parent = document.body;
this.parent.appendChild(this.gl.canvas);
// Width and height of canvas
this.gl.canvas.width = window.innerWidth;
this.gl.canvas.height = window.innerHeight;
// Camera related
this.fov = 75;
this.asp = this.gl.canvas.width / this.gl.canvas.height;
this.camera = new Camera(this.gl, { fov: this.fov, far: 10 });
this.camera.position = new Vec3(0, 0, 2);
this.camera.lookAt([0,0,0]);
this.controls = new Orbit(this.camera);
this.scene = new Transform();
this.gl.clearColor(0.2, 0.2, 0.2, 1);
this.#geometry();
this.#resize();
this.#animate();
}
// RESIZE
#resize(){
this.renderer.setSize(this.parent.clientWidth, this.parent.clientHeight);
this.asp = this.gl.canvas.width / this.gl.canvas.height;
this.fov = 2 * Math.atan( Math.tan( 75 * Math.PI / 180 / 2 ) / this.asp ) * 180 / Math.PI;
this.camera.perspective({ fov: this.fov, aspect: this.asp });
}
// GEOMETRY
#geometry(){
// Object
let size = 1;
this.geometry = new Plane(this.gl, {
width: size,
height: size,
});
// Program
this.lightPos = new Vec3(1, 0, 1);
let defines = `
#define LIGHT
#define PI 3.14159265
`;
let vertPrefix = this.renderer.isWebgl2
? /* glsl */ `#version 300 es
#define attribute in
#define varying out
#define texture2D texture`
: ``;
let fragPrefix = this.renderer.isWebgl2
? /* glsl */ `#version 300 es
precision highp float;
#define varying in
#define texture2D texture
#define gl_FragColor FragColor
out vec4 FragColor;
`
: `
#extension GL_OES_standard_derivatives : enable
precision highp float;
`;
let tex = TextureLoader.load( this.gl, {
src: "https://live.staticflickr.com/65535/51094390698_3644165ff6_h.jpg",
});
this.program = new Program(this.gl, {
vertex: vertPrefix + defines + vert,
fragment: fragPrefix + defines + frag,
uniforms: {
uTex: { value: tex },
},
});
// Meshes
this.mesh = new Mesh(this.gl, { geometry: this.geometry, program: this.program });
this.mesh.setParent(this.scene);
}
// ANIMATE
#animate(){
// UPDATING VALUES
this.controls.update();
this.renderer.render({ scene: this.scene, camera: this.camera });
requestAnimationFrame( this.#animate.bind(this) );
}
}
new Sketch;
</script>