The dual-sided transparent shader appears glitchy

Welcome to my shader experiment using three.js in a 3D environment. The scene features a sphere displaying a demo shader I created, which incorporates a simple 2D noise implementation.

The shader presents a visually striking effect with one side of the sphere remaining transparent while the other side is visible. To achieve this, transparency and double-sided rendering are enabled for the material.

material = new THREE.ShaderMaterial({
    'uniforms': uniforms,
    'fragmentShader': $('textarea#input-fragment').val(),
    'vertexShader': $('textarea#input-vertex').val()
});

material.side = THREE.DoubleSide;
material.transparent = true;

You can observe the visual anomalies more clearly in this specific example. Depending on the viewing angle – top, side, bottom – you may notice differences in how the shader is displayed.

Examining the fragment shader code snippet reveals an interesting color calculation based on different axes. The opacity values are combined for the final color output.

void main() {
    float r = cnoise(vNormal.yz * 2.0 + t);
    float g = cnoise(vNormal.xz * -1.0 + t);
    float b = cnoise(vNormal.xy * -2.0 + t);

    // Opacity ranges assumed from 0 - 3, creating an intriguing effect
    gl_FragColor = vec4(r, g, b, r + g + b);
}

The question remains: Why do choppy edges appear and why does the viewing angle have such an impact on the shader's appearance?

Answer №1

Don't worry about your shader, it's working fine. If you want to see the effect, try setting it like this:

gl_FragColor = vec4( 1.0, 1.0, 1.0, 0.5 );

Creating self-transparency in three.js can be a bit tricky.

It's important to note that for performance reasons in WebGLRenderer, depth sorting only occurs between objects based on their position, not within a single object.

You won't be able to control the rendering order of faces within an object, which is why your scene may look different from different angles.

One workaround is to break the geometry into individual meshes with one face each.

Another solution (in my opinion, the best option) is to replace your transparent, double-sided sphere with two transparent spheres in the same location – one front-sided and one back-sided.

Version used: three.js r.56

Answer №2

Encountering a situation that closely resembles yours, it is crucial to delve into the WHY aspect for better comprehension. For detailed explanations, refer to Three.js Transparency fundamentals. In the absence of specific details regarding your code or objectives, consider an alternative solution with version r128 update. Simply include one additional line in your material:

material.depthTest: false,

In essence, while your shader remains intact as indicated by @WestLangley, issues arise during transparent rendering due to pixel depth comparison - resulting in some pixels not being rendered. This explains the observed "buggy-ness," which is essentially the default rendering behavior of your scene unless instructed otherwise. Be mindful of various challenges that may clash with your expectations and refer to the provided link for further insights.

One potential issue to note: When other objects coexist within your scene, disabling depthTest can lead to misalignment where background objects might erroneously appear in the foreground.

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 assign a value to a property within an object using AngularJS

const objectData = {}; objectData[key]["digits"] = `${set.first},${set.second},${set.third},${set.fourth}`; When key is a numeric value, an error occurs: TypeError: Cannot set property 'digits' of undefined ...

The dropdown menu is malfunctioning

Currently, I am in the process of creating a simple web application that involves the use of two JavaScript libraries, dat.gui, and three.js. One issue that I am encountering is that the drop-down menu appears to be locked and I am unable to access it. / ...

AngularJS requires that JSON object property values be converted to strings in order to be displayed as actual templates

Each tab click accesses a json array containing unique templates such as ui-grid or c3 chart directive (c3.js). When a specific tab is clicked, the template in string format must be rendered into actual templates like ui-grid, c3-chart, etc. var sampleJs ...

Error: SyntaxError - an argument is missing from the list

Displayed below is the parsed HTML code for a button nested inside a datagrid. Upon clicking this button, I encountered a console error: An Uncaught SyntaxError: missing ) after argument list <button onclick="myFunction(<a href="/cdn-cgi/l/emai ...

Vue and Vuex retrieve state data from the server in a single request

When loading the History view, data is fetched from the backend server using a Vuex action called in the created() lifecycle hook. This data is then passed to the history table through a computed function named history(), which accesses the history module ...

Instructions on updating the form action depending on different radio button sets

Allow users to select one radio button from each of the three groups. Based on the values chosen, dynamically change the destination page for the submit button. Below is the code snippet: input[type=radio] { position: relative; visibility: hidden; ...

The Antd table documentation mentions that rowKey is expected to be unique, even though it appears they are already

Having trouble with a React code issue. I have a list of products, each with an array of 7 items that contain 40 different data points. This data is used as the source for a table. {label : someStringLabel, key: someUniqueKey, attribute1: someInt,..., at ...

The Link tag in the Hero.jsx file of Next.js is malfunctioning and failing to redirect to the intended URL

Having a problem with the button in my Hero.jsx component, part of the Page.js implementation. The button uses a Link tag to redirect to the url.js page, but it's not working as expected and showing an Error 404 page instead. I'm new to Next.js s ...

Issue with Angular UI-Router: Unexpected failure to load template not requested by user

Click here to view the Plunker code related to the issue described below Full link: http://plnkr.co/edit/Bz3Qhf1eDuFrnKI0qnUo?p=preview Exploring the functionalities of two components from the AngularUI suite - UI-Router and UI-Bootstrap. UI-Router manag ...

Enhancing website functionality with Regex in Javascript

So, here is the code I am working with: var patt = new RegExp("/.+/g"); var device_id = patt.exec("javascript:project_id:256, device_id:2232"); Surprisingly, after running the above code, the value of device_id is empty and I can't seem to figure ou ...

Position the spinner in the center of the user's screen

I created my own spinner: '''' #spinner-bg-loading{ position: absolute; left: 50%; top: 25%; width: 80px; height: 80px; margin: -75px 0 0 -75px; border: 16px solid #FFFFFF; border-radius: 50%; border-top: 16px solid #1 ...

How to change a string into an object in JavaScript that includes a colon symbol

Can anyone suggest the most efficient way to convert the string var xx = "website:https://google.com"; into a dictionary format like {website:"https://google.com"}? Usually, I use str.split(":"), but in this case, there are multiple colons. Would using t ...

Issue with highcharts and vue.js: creating a unique chart for displaying measurements

Currently, I am integrating Highcharts and Vue.js simultaneously while incorporating multiple charts on my webpage. As of now, I have successfully displayed data on all the charts without encountering any issues. However, my goal is to assign a special tit ...

React's Material-UI checkbox does not trigger the onChange event

Struggling with the Material UI checkbox. Seems like a simple task, right? But for some reason, the checkbox won't toggle. I even tried putting logs in the node_modules package to see if the onChange event is firing internally, but no luck. < ...

Tips for transferring data from a JavaScript page to a C# page by utilizing Jquery

I am working with a dynamically created table that contains values in its selected rows. I need to extract all td.innerText values from each selected row and send them to a C# page, but I am unsure of the best approach. I attempted to use JSON, but I am ...

Multiple instances of meshes being created by THREE.ObjLoader when loading .obj file

As I load a .obj file to create a human dummy, I encounter a problem with duplicated meshes. Inside the .obj file, there are lines indicating where the meshes split, such as "g "body_part" followed by the vertices and faces. When I load the object, everyth ...

Using React Native with Redux: Filtering Data and Preserving Initial Data in Redux State

For my mobile app, I decided to add a search feature using React-Native & Redux. I fetch data from an API and store it in the redux store so that I have a list of items readily available when the app is running. Now, with a searchbox in place, I want to f ...

Synchronizing multiple file changes simultaneously in Node.js

I have a small development server set up specifically for writing missing translations into files. app.post('/locales/add/:language/:namespace', async (req, res) => { const { language, namespace } = req.params // Utilizing fs.promises l ...

Ways to resolve the issue of the experimental syntax 'jsx' not being enabled

I encountered an issue while trying to implement react-fancybox and received an error. https://i.sstatic.net/vgFha.png To resolve the error, I executed the following commands: npm install --save-dev @babel/preset-react, npm install --save-dev @babel/plugi ...

Unable to backtrack once a response has been sent

My Express application keeps crashing after sending a response to the client. It appears that the code continues to run even after the response has been returned. Can you please review the code snippet provided below? const EditUser = async (req, res) => ...