I am trying to animated tree branches and leaves to simulate wind.
I searched here and found two threads but neither provide a solution and are quite old.
The solution seems to be Vertex Shaders. Has anyone got this working? @Leonidas can you share any projects that have this?
in your case you most likely want to use StandardMaterial and override a chunk on it, to move vertices, while still using the rest of StandardMaterial functionality, like lighting and shadows and all that.
This is the chunk to override:
and most likely youād want to add some uniform to this chunk, see uniforms on top, something like time and intensity, and then modify getLocalPosition function to modify vertex position based on time and some āwindā function, typically just a sin wave or similar in a simple case.
Oh wow, @eproasim thank you so much! This sounds perfect!
I tried your link but I get āError while saving changes. Please refresh the editorā. When I refresh I get the same error.
@eproasim That looks awesome and exactly what we are trying to do!
I tried the scripts. Added Wind.js to the leaves object, added the wind.vert script to the vertex shader input of wind.js then launched a preview, but unfortunately I didnāt see any motion. No errors. I also tried increasing frequency and amplitude from 1 to 10,000 in increments of x10.
Is there anything additional I need to enable for vertex shaders to work?
If possible itād be great to see the scene you have with the tree. Itās only the leaf vertex shader that Iād need to see working.
Thatās interesting. Let me see if I can get a quick minute to get you a working copy. Real quick. Is your project on engine v1 or v2? This is an old project, so itās on v1, and I havenāt had a chance to really dig into the differences between v1 and v2 for shaders.
@eproasim I looked at your scene and got your scripts working in Engine v1
The only thing I was missing was adding .glsl at the end of the wind.vert file
Unfortunately it doesnāt working in Engine v2 as you have mentioned, though there are no errors.
Since my main scene is using Engine v2. Do you have any idea how to update wind.js or wint.vert.glsl to work in Engine v2?
@Wagner@mvaligursky This is the code that @eproasim kindly shared for leaf swaying. It works in engine v1 but not v2. From the thread above it looks like startVS is not supported anymore. I will try litMainVS. Any suggestions much appreciated
Thereās an example coming out most likely next week with the new release of the engine v2, not sure how applicable this is for you: PlayCanvas Examples
Omg this is perfect! Does this work with the latest Engine (2.7.4) ?
Iām hoping to use this for the Viverse Hackathon that submits on Thursday.
Looking at the example, I would likely only need the shader chunks part of this right?
Though itās cool you have object instancing too, I may try to leverage that, but for now Iām just trying to get it to work on 1 tree leaves objecy. @eproasim This example might have the code necessary to update your example
If I can extract the shader chunks part, I should be able to apply this to my geometry directly right? Or should this run as a script under root and reference the object from within the script?
I think I might have some spare time to take a look at this and the docs for V2 to update the example tomorrow. I donāt know off the top of my head, but I assume the process for the conversion of the minimal example should ve straightforward enough. Iāll post my aolution here
Just letting you know that I am working on this, but I have to step away for a little while, right now. I donāt think I have more than an hour or so to sort it out.
Hereās my basline, from looking at the example:
var Windv2 = pc.createScript('windv2');
Windv2.attributes.add('vShader', {
type: 'asset',
title: 'Vertex Shader',
assetType: 'shader'
});
Windv2.attributes.add('amplitude', {
type: 'number',
title: 'Amplitude',
default: 1
});
Windv2.attributes.add('wavelength', {
type: 'number',
title: 'Frequency',
default: 1
});
// initialize code called once per entity
Windv2.prototype.initialize = function() {
this.timer = 0;
this.material = this.entity.render.meshInstances[0].material;
// this.material.chunks.startVS = this.vShader.resource;
// this.material.chunks.transformCoreVS = this.vShader.resource;
console.log(this.material);
this.material.shaderChunks.glsl.set('transformCoreVS', this.vShader.resource);
// console.log(this.material.chunks);
};
// update code called every frame
Windv2.prototype.update = function(dt) {
this.timer += dt;
// this.material.setParameter('time', this.timer);
app.graphicsDevice.scope.resolve('time').setValue(this.timer);
// this.material.setParameter('amplitude', this.amplitude);
app.graphicsDevice.scope.resolve('amplitude').setValue(this.amplitude);
// this.material.setParameter('wavelength', this.wavelength);
app.graphicsDevice.scope.resolve('wavelength').setValue(this.wavelength);
// this.material.update();
};
// swap method called for script hot-reloading
// inherit your script state here
// Windv2.prototype.swap = function(old) { };
// to learn more about script anatomy, please read:
// http://developer.playcanvas.com/en/user-manual/scripting/
But material.shaderChunks is returning undefined. Iāll keep working in a bit, but if itās because it was forked form a v1 project and then switched to v2 Iāll try it again without the fork. Otherwise, Iāll just keep trying and digging =]
@eproasim Thank you for looking into this. Yes the core of this issue seems to be around this function:
this.material.shaderChunks.glsl.set(ātransformCoreVSā, this.vShader.resource); @mvaligursky Is this the correct usage for shaderChunks now?
[edit] looking at the tree demo, it does seem like transformCoreVS is the correct term