Tips for creating an effective planar reflection using Open Graphics Library (OGL) in conjunction with a perspective camera

I'm attempting to create a mirror-like reflection of a WebGL scene on a plane using ogl, similar to how a mirror would behave. I tried implementing a basic version of the three.js reflector but ended up with a distorted image that doesn't accurately portray a real reflection.

https://i.sstatic.net/yZ8Qf.png

I understand the concept behind the reflector - rendering the scene from the virtual reflected viewpoint of the original camera, adjusting the projection matrix of the virtual camera to only render what projects onto the plane, and then mapping the resulting texture to the plane. However, I'm not fully knowledgeable about all the computations involved (especially for the last two steps I mentioned).

All I did was replicate line by line the three.js reflector code and modify function names or references, but I can't pinpoint where I went wrong or what I may have overlooked. Any assistance would be greatly appreciated!

// objects/Reflector.js

import { Transform, Mesh, Plane, Program, RenderTarget, Camera, Vec3, Vec4, Quat, Mat4 } from 'ogl'
import { dot } from 'ogl/src/math/functions/Vec4Func'

// Import shaders

// Import math functions

export class Reflector extends Mesh {
  constructor(gl, {
    scene,
    camera,
    renderSize = 512,
    clipBias = 0
  }) {
    // Initialize variables and setup render target...

    // More implementation details...
  }

  update() {
    // Update method coded here...

    // More computations...

    // Rendering logic...
  }
}
// shaders/reflector.vert

precision highp float;

attribute vec3 position;

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 textureMatrix;

varying vec4 vUv;

void main() {
  vUv = textureMatrix * vec4(position, 1.);

  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.);
}

// shaders/reflector.frag

precision highp float;

uniform sampler2D diffuseMap;

varying vec4 vUv;

void main() {
  vec3 diffuse = texture2DProj(diffuseMap, vUv).rgb;

  gl_FragColor = vec4(diffuse, 1.);
}

Here are several self-implemented math functions needed for the project:

// math/Mat4Func.js

import { length } from 'ogl/src/math/functions/Vec3Func'

// Function definition for getRotationMatrix...

// math/PlaneFunc.js

// Function definitions for transformMat4, getCoplanarPoint, setFromNormalAndCoplanarPoint...

// math/Vec3Func.js

// Function definition for reflect...

Answer №1

When Mr.Coder's comment brought back memories of this post, I felt inspired to share the solution I had devised 2 years ago. Perhaps it could be useful to others facing a similar challenge.

Below is a functional example of a planar reflector. Although the code may require some refactoring and conversion to TypeScript, it served as a solid starting point for me back when I encountered this issue:

// Import necessary libraries
import {
  RenderTarget,
  Camera,
  Plane,
  Program,
  Mesh,
  Vec2,
  Vec3,
  Vec4,
  Mat3,
  Mat4
} from 'ogl';

// More code can go here...

The primary issue I faced was with the initialization of the texture matrix. In my original code, it was structured like this:

this.textureMatrix.set(
  0.5, 0.0, 0.0, 0.5,
  0.0, 0.5, 0.0, 0.5,
  0.0, 0.0, 0.5, 0.5,
  0.0, 0.0, 0.0, 1.0
)

In reality, it should have been set up as follows:

this.textureMatrix.set(
  0.5, 0.0, 0.0, 0.0,
  0.0, 0.5, 0.0, 0.0,
  0.0, 0.0, 0.5, 0.0,
  0.5, 0.5, 0.5, 1.0
)

This error occurred due to the reversal of columns and rows in threejs compared to ogl!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to modify document value in MongoDB using Node.js

Currently, I am attempting to fetch the value of a field form that is being sent to a subroute and utilize it to update a database collection. My ability to retrieve the form value and manipulate it is working fine; however, I encounter an issue when I sol ...

Don't let noise linger in the background unnoticed

Within my HTML table, there are 32 cells that each possess an onclick="music()" function. This function is currently functioning correctly, with one small exception. I desire for the functionality to be such that whenever I click on a different cell, the m ...

What is the method of updating content on a webpage without altering the page itself or using hashed URLs?

I have a good understanding of how to update webpage content through AJAX and loading remote content. However, I recently came across UStream's innovative new layout. When you click on any video, not only does the content change seamlessly without rel ...

Using Angular's $filter to target a specific field

I'm attempting to use the $filter function in my controller, within a $watch function, to filter specific fields. I am having trouble understanding the documentation provided. The situation: I have a dropdown menu that serves as the filter parameter. ...

Communication between child and parent components in Vue.js is an essential feature

Attempting to invoke functions from my component to Vue for the login process. This is the code snippet of my component : Vue.component('auths', { data: function() { return { ip: '', sessiontoken: '' } ...

Struggling to troubleshoot an error - Invalid key Token '{' found at column 2

I am encountering a debugging issue that I can't seem to resolve. form-field.html <div class='row form-group' ng-form="{{field}}" ng-class="{ 'has-error': {{field}}.$dirty && {{field}}.$invalid }"> <label cla ...

Resolving the Smooth Scrolling Problem

Here is a simplified version of what I am currently working on: Although I have managed to get the scrolling functionality to work, there seems to be an issue with transitioning from one section to another. For example, when clicking on NUMBER 3, it s ...

Unable to modify variable values in AngularJS

I'm currently utilizing AngularJS along with the "Angular Material" implementation (found here: https://material.angularjs.org/latest/#/) One of the components I'm using is the SideNav component: https://material.angularjs.org/latest/#/demo/mate ...

Tips for downloading a file in React using raw file data

I've been struggling with a particular issue for the past couple of days and just can't seem to find a solution. It involves retrieving data from an API on our outdated system related to Attachments and other information. When I execute the query ...

send another response following the completion of the request.end()

I am facing challenges with writing the correct callback function. The situation involves a user making a request to "/city", which then triggers the server to make a request to a third-party service for data retrieval using http.request(). I successfully ...

What is the process for deleting a token from local storage and displaying the logout page in Next JS?

I developed a Next.js web application and am looking to display a logout page when the token expires, while also removing the expired token from local storage. How can I ensure that this functionality works no matter which page the user visits within the a ...

Is there a way to speed up the processing time of parsing a 34Mb file using JSON.parse, which currently takes

Our app is currently in the development stage with a database containing approximately 4000 recipes. To save space, we have chosen to store the recipes in one locale during initial download. However, users have the option to switch locales within the app&a ...

A guide to increasing a loop counter in Vue

Having trouble looping through a specific group of objects in a multi-object array? Take a look at the code below: <template> <div> <h1>My Test App</h1> <button v-on:click="getHockeyData">Get Team Data< ...

Looking for precise information within a Vue b-table by fetching data from an Axios API

My b-table is filled with data from an API hit through Swagger UI, and since there's a large amount of data, I need the search button at the center top of the page to work properly when inputting store code or branch. https://i.stack.imgur.com/l90Zx.p ...

Choose a subclass within a superclass by utilizing the "this" keyword

Whenever a user clicks on the class addMass, I want to add the attribute data-rate to the element with the class currentMass. Since there can be multiple elements with the class addToCart, I need to ensure that the changes are only applied to the one that ...

Learn the step-by-step process of clicking on a button to modify its properties and deactivate it

I could really use some assistance. I'm trying to make a button: <v-btn dark color="primary" class="square">Tile 1</v-btn> Is there a way I can modify it so that when clicked, it changes to flat, becomes disabled, and switches its color ...

JQuery script fails to load in the head section while dynamically generating an HTML page with JavaScript

Using JavaScript, I have created a new window dynamically and added some HTML code to it. However, when I try to insert a script link into the HTML head, it fails to load when the window is open. <script type="text/javascript"> function newWindo ...

insert a new field into the database within Prisma while ensuring existing table data remains untouched

I have been working with the Prisma ORM and I currently have some data in my table. This is how my model looks: model User { id Int @default(autoincrement()) @id username String @db.VarChar(100) @unique } model Post { id Int @id @defa ...

The issue with collapsible elements not functioning properly in an Angular application involving CSS and JS

My implementation of collapsible in a plain HTML page looks like this: <!DOCTYPE html> <html> <head> <title></title> <style> button.accordion { background-color: #777; color: white; cursor: pointer; p ...

The useEffect hook is failing to trigger

Currently, I am attempting to retrieve data from an API using Redux for state management. Despite trying to dispatch the action within the useEffect hook, it does not seem to be functioning properly. I suspect that the issue lies with the dependencies, but ...