Is there a way to create a pixelated render target using THREE JS?

Attempting to set up a basic render target where I render one scene and then use it as a texture over a quad. The demo seems to be pixelated when running, almost like it's rendered on a small screen and stretched across the quad.

Below is the code snippet:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

        <title></title>

        <link rel="stylesheet" type="text/css" href="style.css">
        <script src="three.min.js" type="text/javascript"></script>

        <style>
            body {
                color: #ffffff;
                font-family:Monospace;
                font-size:13px;
                text-align:center;
                font-weight: bold;
                background-color: #000000;
                margin: 0px;
                overflow: hidden;
            }

            #info {
                position: absolute;
                top: 0px; width: 100%;
                padding: 5px;
            }

            a {
                color: #ffffff;
            }

        </style>
    </head>
    <body>
        <div id="container"></div>

        <script id="vertex-shader-test" type="x-shader/x-vertex">
            void main() {
                gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
            }
        </script>

        <script id="fragment-shader-test" type="x-shader/x-fragment">
            void main() {
                gl_FragColor = vec4(1,1,1,1);
            }
        </script>

        <script id="vertex-shader-screen" type="x-shader/x-vertex">
            varying vec2 vertexUV;

            void main() {
                vertexUV = uv;
                gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
            }
        </script>

        <script id="fragment-shader-screen" type="x-shader/x-fragment">
            precision highp float;
            varying vec2 vertexUV;
            uniform sampler2D rtTexture;

            void main() {
                gl_FragColor = texture2D(rtTexture, vertexUV);
            }
        </script>

        <script>

            var scene = null,
                rtScene = null,
                camera = null,
                cameraRTT = null,
                renderer = null,
                plane = null;

            var rtTexture;

            init();
            render();

            function init()
            {
                container = document.getElementById( 'container' );

                scene = new THREE.Scene();
                rtScene = new THREE.Scene();

                rtTexture = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBFormat });

                camera = new THREE.PerspectiveCamera(20, window.innerWidth / window.innerHeight, 1, 1000);
                camera.position.z = 1;

                rtCamera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
                rtCamera.position.z = 100;
                rtCamera.position.y = 10;

                var material2 = new THREE.ShaderMaterial({
                    vertexShader: document.getElementById('vertex-shader-test').textContent,
                    fragmentShader: document.getElementById('fragment-shader-test').textContent,
                });

                var geometry = new THREE.PlaneBufferGeometry(100, 100, 200, 200);

                plane = new THREE.Mesh(geometry, material2);
                plane.rotateX(-Math.PI / 2);
                rtScene.add(plane);

                var geometry = new THREE.PlaneBufferGeometry(1, 1);

                var material = new THREE.ShaderMaterial({
                    uniforms: {
                        rtTexture: { type: "t", value: rtTexture }
                    },
                    vertexShader: document.getElementById('vertex-shader-screen').textContent,
                    fragmentShader: document.getElementById('fragment-shader-screen').textContent,
                });

                var mesh = new THREE.Mesh(geometry, material);

                scene.add(mesh);

                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.autoClear = false;

                container.appendChild( renderer.domElement );
            }

            function render() {
                requestAnimationFrame(render);

                camera.lookAt(new THREE.Vector3(0,0,0));
                rtCamera.lookAt(new THREE.Vector3(0,0,0));

                renderer.render(rtScene, rtCamera, rtTexture, true);
                renderer.render(scene, camera);
            }
        </script>
    </body>
</html>

Any thoughts on what could be causing this issue?

Answer №1

When you render the plane with your render target mapped to it, using a perspective camera will result in varying output sizes depending on the field of view.

For instance, decreasing the camera's field of view from 20 to 10 will zoom in and amplify any stepping artifacts due to the increased scaling. Conversely, increasing the field of view will zoom out and minimize stepping.

In this scenario, it may be beneficial to use an orthographic projection for displaying the render target within the main scene.

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

Convert object to JSON format using AJAX request to a PHP file

Despite receiving a 200 green response, my data is still not getting written to the json file and it remains blank. The JavaScript: $(function() { $('form#saveTemp').submit(function() { let savdAta = JSON.stringify($('form#save ...

nodejs express routing issue resulting in not found error

I recently started a new node project and wanted to enhance my route adding capabilities. In the past, I only went one level deep with folders, but this time I wanted to go further. To achieve this, I created a recursive function that adds routes and navig ...

Attempting to streamline this function in order to avoid running it nine separate times

I have created a day scheduler and successfully saved data in local storage for one hour field. However, I am looking for a way to streamline this function so that I can use it across all 8-hour fields without duplicating the code. Can someone provide me w ...

Error: In Nodejs Promises, you cannot invoke the "then" method on an undefined value

Could you clarify what's incorrect about the following code snippet? var promise = fs.readFile(file); var promise2 = promise.then(function(data){ var base64 = new Buffer(data, 'binary').toString('base64'); res.e ...

It appears that AsyncStorage.getItem() is not functioning as expected

Whenever I attempt to use AsyncStorage.getItem() to assign a value, I encounter difficulties retrieving it afterwards. let tokenData = null; const getData = async () => { let token; try { token = await AsyncStorage.getItem('token'); ...

What sets the Test Deployment and Actual Deployment apart from each other?

I have been developing a web application using Google App Script and I currently have multiple versions of the same web app with various fields. Interestingly, when I run one version through a test deployment, it displays correctly as expected based on th ...

JavaScript's search function is encountering issues when working with multidimensional arrays

I have an array containing city names and postal codes that I need to search through. I can successfully search for the city name and retrieve the result, but when I try to search for a postal code, it doesn't register. My question is: How can I modif ...

How to efficiently manage drop-down menus on a website using VBA specifically designed for Internet Explorer

I am a beginner in VBA and coding, seeking assistance from the community. The purpose of this VBA code is to automate the following steps: Open Internet Explorer Enter user ID and password to login Select the current date Select a specific option (X1) fr ...

The reason behind the delay in discord.js interactions caused by the "foreach" method

I'm just starting out with JavaScript programming and I have a Discord bot where one of the commands is supposed to silence everyone in a call. However, I noticed that the command first silences five users, creates a pause, and then proceeds to silenc ...

Struggling to make the fancybox feature function with html/php

I've been trying to find a solution to this problem repeatedly, but I just can't seem to crack it. All I want to do is use fancybox to display an image. Since this is my first time using fancybox, I'm sure someone with more experience will ...

Switch image formats to webp using react js

Utilizing the react-dropzone package, I aim to incorporate images into my application. To achieve this, I must send the images to a firebase server after managing image conversions. Whilst browsing through YouTube tutorials, I came across a guide demonstr ...

Unanticipated commitments fulfilled on the spot

While troubleshooting a setup for managing promise concurrency in handling CPU-intensive asynchronous tasks, I encountered perplexing behavior that has left me puzzled. To regulate the flow, my approach was to initially create an array of Promises and the ...

HTML/JS Implementation: Back to Top Visual Element

- This website appears to be quite simple at first glance. However, I have encountered an issue where every time I scroll down and then click on the "About" menu option, it abruptly takes me back to the top of the page before displaying the section with a ...

Can someone show me how to use the IN operator in a PostgreSQL query in an Express.js (Node.js

My Approach to Writing Code var employees=[1,2,3]; await client.query( "SELECT user_id FROM group_user WHERE user_id IN($1)", employees ); An error is thrown indicating that only one parameter needs to be provided ...

Using v-for with nested objects

Have you been attempting to create a v-for loop on the child elements of the {song: "xxx"} object within the songs array? export const data = [ {id: "1", albumname: "xx", artist: "xxxx", dateadded: "xxxx", route: "xxxx", songs: [{ song : &apos ...

When the return false statement is included, the form fails to submit and instead refreshes on the current page

I recently discussed an issue regarding triggering a dialog box before confirming a submit action. Unfortunately, after implementing this, the document no longer submits when expected. Instead, it just remains on the same page with the same settings. I h ...

Issue: Unable to locate module - Unable to resolve 'core-js/modules/es.error.cause.js'

I've incorporated Vuexy Dashboard into my project, which utilizes Vue 2. Now, I'm in the process of upgrading it to Vue 3. However, I have encountered an error that has me stuck. Any assistance with this issue would be greatly appreciated. Thank ...

Disregard any unnecessary lines when it comes to linting and formatting in VSC using EsLint and Prettier

some.JS.Code; //ignore this line from linting etc. ##Software will do some stuff here, but for JS it's an Error## hereGoesJs(); Is there a way to prevent a specific line from being considered during linting and formatting in Visual Studio Code? I h ...

Choosing the subsequent div after the current one using Jquery

I am currently in the process of creating a drop-down menu button that, when clicked, reveals the previously hidden div underneath it. The code is functioning properly without the use of $(this).next, but it is displaying all divs with the class .menudrop ...

Router-view failing to display component

I am currently working on setting up basic routing in Vue. I have identified three file listings that seem to be causing issues. When I include <router-view> in app.vue, the foo component appears in the browser. However, when I follow the instruction ...