Correctly mapping equirectilinear texture on a plane

  Kiến thức lập trình

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:

  1. By default, it is not centered and is targeting much to the right ( Image url for center reference )
  2. 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>

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT