Add Bloom to model?

I’m using the Engine version, latest. Things work great, and what’s documented is very helpful. But it seems like there’s not much documentation for not using your Editor. Had to search for and figure out other code examples, which is slow and tedious.

I’m trying to add glow to a model. The basic cube.

var cube = new pc.Entity('cube');
cube.addComponent('model', {
  type: 'box',
});

The Earth example is way too much stuff for me. The Halo uses a texture, which I’m not interested in. I figured out how to add the Bloom posteffect, but not how to apply it to one model. Would that be possible? Toggling that on and off. I couldn’t figure out how to just add some glow to the model’s material, just through tinkering in the console. Maybe like an Emissive color. Tinkering with that property of the material did nothing.

Am I learning PlayCanvas Engine the wrong way? Is there anywhere that explains how to achieve this very basic need? It’s not encouraging that all the Tutorials are for the Editor, without some tips for converting to Engine use.

EDIT: If this helps anyone, a very simple example of adding a simple shader to a model/material is in the github toon example.

1 Like

Emissive is done on the material. I’m surprised that didn’t do anything? Can you provide a code example to work from please?

For the Planet Earth effect, the shaders do the work there:
https://playcanvas.com/editor/code/419706?tabs=5929828
https://playcanvas.com/editor/code/419706?tabs=5929830

And the script that applies them: https://playcanvas.com/editor/code/419706?tabs=5930049 (look in the editor for entities that have this script attached).

The tutorials on the PlayCanvas website are for the editor as it’s there to support the PlayCanvas service (which generates revenue) rather than the engine directly. That said, most of them can be used with engine directly if you take into account what the scripting system is referencing through the attributes.

Fundamentally, that is all it’s really doing 90% of the time (there’s some more features such as baking lightmaps, building DDS skyboxes, converting FBX to it’s JSON format etc that is done by the service on the server).

For example: https://playcanvas.com/editor/code/437446?tabs=5625731

The tricky bit is how to get the array of assets for textures without using the editor. If you are using the engine directly, I would assume there is a reference to those assets somewhere that you can use to create the array. Or use the asset registry to find them.

You can also get the attribute name if you hover over a field in the editor to bring up the tooltip which should contain the name of the attribute in the engine:

image

Thanks for responding so quickly. I understand the editor is the business part, and it’s great for what it does. But it’s not suitable for all cases, so it’s confusing to be directed to it.

I saw those scripts you linked, but I don’t want to apply a new material to my model. I just want to highlight it, keeping the previous material intact. I had the impression I can just apply a shader, not affecting the entire material (like Bloom does), but I guess that’s not the case.

I don’t see what textures has to do with it. I am not interested in applying a texture.

Interesting tip about the attributes for the engine in the editor!

TL;DR (Update first.)

I was lost at the pc.Material API page, but then after searching in the engine examples, realized I can stumble on the pc.StandardMaterial API page which does have a bit of code to help. I got Emissive to work!

For the sake of clarification, is there a way to apply the Bloom posteffect to only my cube model? That would look more awesome than just Emissive.

I still wish the API pages were clear on which parts relate to which; the latter says “Extends: pc.Material”, but the former says nothing. Would be awesome if it said “Extended by: pc.StandardMaterial and pc.BasicMaterial.” And a bit more code samples in the API to clarify actual usage in Engine. It would be my pleasure to add the @see tag on Github, so the API has those clarifications and a link to the relevant Engine file. If that the devs would be interested in such edits.

Where I randomly stumbled on a code sample (which is oddly different from API sample, so which is the recommended standard?):

So, you’re saying I should be able to highlight a model by adjusting its Emissive? Can you provide a basic example of this? My code example is in the OP, nothing more. As basic as it gets. In console I tried tweaking a variety of properties such as:

cube.model.material.emissiveIntensity...
...
cube.model.material.update()

But I’m in the dark without an actual code example from the docs. The API without basic code examples is unhelpful. -> https://developer.playcanvas.com/en/api/pc.Material.html

The API reference is generated from the engine code docs so you could create a pull request for a file or two and see what the response is like.

Here’s an example to get the emissive to only apply to a single model even if another uses the same material asset: https://playcanvas.com/editor/scene/629339

I’m not sure about the bloom effect (as the example seems to be broken at the moment).

The glow effect on the Earth in the Planet Earth example is possible to only apply to a single model. Not 100% how to turn it on/off though :thinking: Perhaps an extra param can be added to the shader to change the intensity of the effect?

1 Like

Thanks for the extra info. The Emissive option is clear now. To add Bloom to your camera I just use this code (notice I put the script file in my local directory):

app.assets.loadFromUrl('scripts/extras/posteffects/posteffect-bloom.js', 'script',
  function (err, asset) {
    var bloom = new pc.BloomEffect(app.graphicsDevice);
    bloom.bloomThreshold = 0.1;
    camera.camera.postEffects.addEffect(bloom);
});

Does anybody know how to apply Bloom to a single model??

As it’s an effect on the camera, you won’t be able to use that shader for a single model only.

Even so, if it’s just a shader, and models can run their own shaders (chunks - not sure about terminology and how it works), then why not?

I’d love it if a dev’ verified this.

Looking at the script specifically, its a full screen posteffect as it inherits https://github.com/playcanvas/engine/blob/b67c4e832236f2e854644c2c1df89b5c45361b7e/src/graphics/post-effect.js

That said, you might be able to take the shader code from the script and use as a shader for a model/material.

That’s what I’m wondering. I’m too inexperienced to have enough clues about this. Does anybody know how to take the shader from Bloom and apply it for a specific model?

EDIT: I just followed the toon example from the github, but the bloom is way beyond me - too complex.

Specifically to you yaustar, any idea why I can change ‘material_emissive’, but when I try to change any other value, say ‘material_emissiveIntensity’, it doesn’t work? I made sure I got the name right from the github.

UPDATED:

I’ve gained moderate success in applying a “Glow” shader to a model. Had to mix and match from forums, github, threejs + example project for Glow. It’s not working as expected - lacks the opacity effect and camera movement affects it oddly - but it’s something. I’d appreciate any tips! Now, can I add it to the StandardMaterial as a .glow property? It doesn’t make sense to lose all other material properties for one.

Following up on the shader question, I found some examples, but I’m failing at applying any of them. A rather simple one has some undefined variables that I can’t figure out how to define with playcanvas. normalMatrix, normal, and viewVector are all a mystery to me. How would I define them? Here’s the vertexshader that’s bugging:

Shader code updated below:

// <script id="vshader" type="x-shader/x-vertex">
// Attributes per vertex: position, normal and texture coordinates.
attribute vec4 aPosition;
attribute vec3 aNormal;
// attribute vec2 aUv;

uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;

uniform mat4 matrix_viewProjection;
uniform mat4 matrix_model;
// uniform mat4 matrix_view;
uniform mat3 matrix_normal;
// uniform vec3 uLightPos;

void main() 
{
  vec3 vNormal = normalize( matrix_normal * aNormal );
  vec3 vNormel = normalize( matrix_normal * viewVector );
  intensity = pow( c - dot(vNormal, vNormel), p ); // Im probably messing up this and above 2 lines.
  gl_Position = matrix_viewProjection * matrix_model * aPosition;
}
// </script>

// <script id="fshader" type="x-shader/x-fragment">
precision highp float;

uniform vec4 glowColor;
varying float intensity;

void main() 
{
  vec4 glow = glowColor * intensity;
  gl_FragColor = glow;
}
// </script>

Example shader from:
http://stemkoski.github.io/Three.js/Shader-Glow.html
https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Shader-Glow.html





I then tried adding the variables and figuring out their values through threejs docs, but the end result is an error:

Failed to execute ‘uniform3fv’ on ‘WebGL2RenderingContext’: No function was found that matched the signature provided.

Here’s the code I added for it:

uniform mat3 normalMatrix;
attribute vec3 normal;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
attribute vec3 position;
mat.setParameter('normalMatrix', cube.normalMatrix);
mat.setParameter('normal', cube.forward.normalize());
mat.setParameter('projectionMatrix', camera.camera.projectionMatrix);
mat.setParameter('modelViewMatrix', 
  camera.getWorldTransform().invert() * cube.getWorldTransform());
mat.setParameter('position', cube.getPosition());

I think a BASIC post processing glow shader should be taught in a demo and have it run withing minutes, the earth shader is too complicated and should be featured after basic glow… despite cg code floating for decades to do this…it requires setting up the chunks so that playcanvas could speak to these available shaders not to mention having to dust up the blue, orange and red gl books so one can relearn all the crinngey asm goodness, which could take hours, days or even weeks, if you are not properly guided

1 Like

Yeah, a tutorial would be great!

For the initial question, indeed a fullscreen post process effect will affect all rendered objects. Right now all post process effects created are being added to the PostEffectQueue.

That is automatically being added as layer after all layers, minus the UI, has finished rendering. So one way to have a pp effect affect only certain models is to change the order of when the effect is rendering. Most easiest way I think would be to reorder the PostEffectQueue layer to render after your custom layer rendering the models in question.

Here is the relevant part of the engine code:

1 Like

I’m trying to do this same thing… in that I’d like just one model to have a bloom effect, not the entire scene. Are you suggesting this change in the actual engine code itself?

I realize this is an old thread; is there anything new that has happened in the engine since then that might help handle this?

Hi @rscott78,

Check this forum post, it provides some insight on how to do that:

Hey man, great work. Do you have an example scene I can check? How do you use this?