Create a virtual camera in Three.js that produces an optically-inverted (mirror-image) result

In my Three.js project, I have a scene with various objects and text that are viewed through a single camera named camera_A. The output of this camera goes to a viewport_A on one part of my webpage.

Now, I want to add a second camera (camera_B) that will also view the same scene but send its output to a different viewport (viewport_B) on another section of the webpage. Camera_B should show a mirrored image compared to what is displayed in viewport_A. Both cameras are identical except for this mirroring effect.

I am aware of how to set up multiple viewports on a webpage using two cameras in a single renderer object. However, I am unsure of the best way to achieve the mirror image effect in viewport_B.


I attempted to use the following command:

camera.projectionMatrix.scale
     (new THREE.Vector3(-1, 1, 1));

However, implementing this command resulted in distorted perspectives of objects as seen in this jsfiddle example: http://jsfiddle.net/steveow/510h3nwv/2/


EDIT:

An answer provided by stdob was effective in achieving the desired mirror image effect, although it involved using a second renderer.

(Apologies for not clarifying my preference for a single renderer in the original question).

Ideally, I would like to utilize only one renderer while still being able to mirror the image in viewport_B.

Answer №1

One way to achieve this effect is by utilizing post-processing along with a custom shader:

CustomMirrorShader = {

    uniforms: {
        "tDiffuse": { type: "t", value: null }
    },

    vertexShader: [
        "varying vec2 vUv;",
        "void main() {",
            "vUv = uv;",
            "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
        "}"
    ].join("\n"),

    fragmentShader: [
        "uniform sampler2D tDiffuse;",
        "varying vec2 vUv;",
        "void main() {",
            "vec2 mvUv = vec2(1.-vUv.x, 1.-vUv.y);", // Mirror
            "vec4 color = texture2D( tDiffuse, mvUv );",
            "gl_FragColor = color;",
        "}"
    ].join("\n")
};

Check out the live example here.

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

Perform a single click and a double click on an anchor element in the document

I am attempting to implement two actions when a user clicks on an anchor tag. The anchor tag will contain a video link. My goal is for the URL to open in a new window when the user single-clicks on the anchor tag, and for the use of the HTML5 download attr ...

Can you explain the distinction between App: React.FunctionComponent and App = (): React.FunctionComponent()?

Currently exploring the depths of typescript. Can someone clarify the distinction between these two code snippets: const App: React.FunctionComponent<CustomProps> = (props: CustomProps) => { return <div>Hello World!</div>; }; and: ...

Potential dangers involved in sending HTML content through an AJAX request over a secure HTTPS connection

I am exploring the idea of dynamically loading HTML content, such as updating a Bootstrap modal dialog's contents using AJAX calls instead of refreshing the entire page. However, before I proceed, I want to understand the potential risks involved and ...

Checking the list box and radio button using JavaScript based on their respective IDs

Looking to validate the selection of a listbox and radio button using their respective IDs when a submit action occurs. When testing in the browser, no alert is being displayed. The goal is to trigger the script upon clicking the submit button to verify ...

Error in Node.js: The res.send method is undefined

I'm having some issues with my first attempt at creating a simple Counter Strike API bot using nodeJS. The problem lies with the res.send function, as I keep getting an error message saying "res.send is not a function" every time I try to use it. Movi ...

Assigning an identification number to specify the type of Chip

I am currently working on a project involving Material UI "Chips" that contain text and serve as references. Within the context of my project, I have Chips for both White Advantages and Black Advantages sections. However, there are instances where these Ch ...

Having trouble getting JSON data to display in CanvasJS

I am trying to retrieve JSON data using Ajax with this code. It works fine when fetching data from the original source, but it's not working with my own JSON data. What could I be missing? Any help would be greatly appreciated. Thank you. $(document) ...

Incorporating a protected Grafana dashboard into a web application

I am looking to incorporate Grafana into my web application using AngularJS. The main objective is to allow users to access the Grafana UI by clicking on a button within my application. Setting up an apache reverse proxy for Grafana and ensuring proper COR ...

Exploring the isolated scopes of AngularJS directives

Exploring directives in AngularJS led me to this interesting code snippet: var app = angular.module('app', []); //custom directive creation app.directive("myDir", function () { return { restrict: "E", scope: { title: '@ ...

How can you identify the specific HTML page that a jQuery selector is targeting?

In an attempt to create jQuery code that counts the number of <img> elements on a website, I encountered a unique challenge. The website consists of 4 separate HTML pages stored in the same folder on the server. Among these pages, only "pics.html" is ...

jQuery: Modifying tags is a one-time deal

I am trying to create a feature where a <p> tag becomes editable when clicked. However, I am encountering an issue - it can only be edited once. Upon a second click, an error message appears in the console. You can view the fiddle demonstrating this ...

Angular sorting - Strings with undefined values are placed at the end

I am looking to understand how to effectively utilize the Angular orderBy filter with a custom sorting function that places undefined values at the end. For numeric sorting, my code looks like this: <tr ng-repeat="item in items | handleEmptyValues(sor ...

Transmit analytical data to an external domain without expecting a reply

Initial Conditions I have ownership of mysite.com I lack ownership of othersite.com, but I am able to embed javascript code on that site Query What is the method to transmit analytic data from othersite.com to mysite.com ? ...

Guide to transferring existing Mongoose Schema information to updated Mongoose Schema Data

In the schema I was using previously with Mongoose, it looked like this: social:{ instagram: String, facebook: String, whatsapp: String, } Now, my updated Mongoose Schema is structured differently: social:{ instagram: { dat ...

Create a bolded section within a TextField component using Material UI version 5

I am working with a TextField component that has a specific defaultValue set. Here is the code snippet: <TextField autoFocus={props.autoFocus} fullWidth defaultValue={props.defaultValue} value={text} onKeyPress={handleKey ...

Three.js - Implementing camouflaged skeleton transformation within geometry

How can I accurately apply bone matrices to vertices in order to represent the transformed shape of a character model without relying on GPU rendering capabilities? I have a character model with a skeleton that I would like to 3D print in various poses. I ...

Events in d3.js are properly registered, however they are not being triggered as

After creating an enter section that transitions to set the opacity to 1, I encountered an issue where the 'click' event on the circle worked but not on the text. Interestingly, when I replaced the 'text' with a 'rect' and se ...

Function in nodejs throwing an error: Return type missing

I am facing an issue with this code snippet while trying to compile the application. public async test(options?: { engine?: Config }): Promise<any> { const hostel = new Service({ list: this.servicesList, createService ...

Sending data as a string in an AJAX request

I have been struggling with this coffeescript function that controls dynamic select boxes. I am trying to pass the content of "modelsSelect" to another script, but for some reason, it's not working as intended. customScript.coffee dynamicSelection = ...

Why does routing function correctly in a browser with AngularUI Router and Ionic, but not in Ionic View?

My Ionic App runs smoothly in the browser when using ionic serve. However, I encounter issues with routing when running the app in Ionic View (view.ionic.io) after uploading it with ionic upload. The index.html loads but nothing within <div ui-view=""& ...