Hello everyone.
I am trying to build a project using the postprocessing library from NPM. I am having problems with the ShaderPass: I wrote a custom blur shader that I want to apply as postprocessing filter, but it removes the alpha channel of the objects in the scene.
If I use threejs library by importing it in the index.html file and using the example code for the EffectComposer, it works like expected. If I use the ES6 syntax by importing modules from postprocessing, the result is different. The problem is ShaderPass, as EffectComposer without any filter keeps the alpha of the objects in the scene. I tried also three-effectcomposer module, same result.
Am I doing something wrong? Or simply ShaderPass doesnât allow the use of ES6 / Object Oriented approach? Or is there any other way? Thank you very much.
Here is the code I am using:
import {
Vector2,
Clock,
ShaderMaterial,
LinearFilter,
RGBAFormat,
WebGLRenderTarget,
Color,
} from "three";
import {
EffectComposer,
RenderPass,
ShaderPass
}
from "postprocessing";
const glsl = require("glslify");
export default class PostEffect {
constructor(renderer, scene, camera, resolution) {
this.clock = new Clock();
this.drawShader = new ShaderMaterial({
uniforms: {
tDiffuse: {
type: "t",
value: null
},
iResolution: {
type: "v2",
value: resolution
}
},
vertexShader: glsl.file("./Shaders/Post_effect/vertexShader.glsl"),
fragmentShader: glsl.file("./Shaders/Post_effect/fragmentShader.glsl")
});
const width = resolution.x;// || 1;
const height = resolution.y;// || 1;
const parameters = {
minFilter: LinearFilter,
magFilter: LinearFilter,
format: RGBAFormat,
stencilBuffer: false
};
const renderTarget = new WebGLRenderTarget(width, height, parameters);
this.composer = new EffectComposer(renderer);
this.renderpass = new RenderPass(scene, camera);
this.renderpass.clearColor = new Color(0, 0, 0);
this.renderpass.clearAlpha = 0;
this.composer.addPass(this.renderpass);
// this is my shader
this.blurPass = new ShaderPass(this.drawShader, "tDiffuse");
this.blurPass.renderToScreen = true;
this.composer.addPass(this.blurPass);
}
runShader() {
this.composer.render(this.clock.getDelta());
}
}
And this is how I implement it:
// threejs
const THREE = require("three");
// the particle system
import ParticleSystem from "./ParticleSystem.js";
// THIS is the post processing filter class
import PostEffect from "./PostEffect.js";
let postProcessing;
// variables
let scene, camera, renderer;
let particlesystem;
let resl;
window.onload = function() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000000);
scene.add(camera);
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
preserveDrawingBuffer: true,
premultipliedAlpha: rrue
});
renderer.setPixelRatio(1);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xececec, 1.0);
document.body.appendChild(renderer.domElement);
resl = new THREE.Vector2(window.innerWidth, window.innerHeight);
particlesystem = new ParticleSystem(resl, e);
scene.add(particlesystem.ParticleSystem);
// Here is the post processing class filter initialization
postProcessing = new PostEffect(renderer, scene, camera, resl);
animate();
}
function update() {
// update the particle system
particlesystem.update(performance.now());
};
function animate() {
requestAnimationFrame(animate);
// update and render
update();
renderer.render(scene, camera);
// run the post processing shader after the renderer
postProcessing.runShader();
};
This is the result that I get when using the classic approach of adding the library and js file to the index.html (and also the expected result).
These are the results with the ES6 syntax, both without (the first one) and with the postprocessing filter.