This is my first time touching shaders, and I am trying to convert this GLSL shader to be used in Babylon: https://codesandbox.io/p/sandbox/laughing-jackson-eml2nj?file=%2Fvertex.glsl%3A34%2C17-34%2C24
ThreeJS version:
uniform float u_effectBlend;
uniform float u_remap;
uniform float u_normalize;
varying vec2 v_uvs;
float inverseLerp(float v, float minValue, float maxValue) {
return (v - minValue) / (maxValue - minValue);
}
float remap(float v, float prevMin, float prevMax, float newMin, float newMax) {
float t = inverseLerp(v, prevMin, prevMax);
return mix(newMin, newMax, t);
}
void main() {
v_uvs = uv;
vec2 vertexOffset = vec2(
remap(uv.x, 0.0, 1.0, -u_remap, 1.0),
remap(uv.y, 0.0, 1.0, -u_remap, 1.0)
);
vertexOffset *= vec2(-1.0, 1.0);
if (u_remap == 1.0) {
vertexOffset = mix(vertexOffset, normalize(vertexOffset), u_normalize);
}
vec4 worldViewPosition = modelViewMatrix * vec4(position, 1.0);
worldViewPosition += vec4(mix(vec3(0.0), vec3(vertexOffset, 1.0), u_effectBlend), 0.0);
gl_Position = projectionMatrix * worldViewPosition;
}
It looks fairly simple, but I’m not sure I’m getting all the equivalencies right.
Here’s my code so far:
attribute vec3 position;
attribute vec2 uv;
uniform mat4 world;
uniform mat4 view;
uniform float u_effectBlend;
uniform float u_remap;
uniform float u_normalize;
uniform mat4 projection;
varying vec2 vUV;
float inverseLerp(float v, float minValue, float maxValue) {
return (v - minValue) / (maxValue - minValue);
}
float remap(float v, float inMin, float inMax, float outMin, float outMax) {
float t = inverseLerp(v, inMin, inMax);
return mix(outMin, outMax, t);
}
void main() {
vec2 vertexOffset = vec2(
remap(uv.x, 0.0, 1.0, -u_remap, 1.0),
remap(uv.y, 0.0, 1.0, -u_remap, 1.0)
);
vertexOffset *= vec2(-1.0, 1.0);
if (u_remap == 1.0) {
vertexOffset = mix(vertexOffset, normalize(vertexOffset), u_normalize);
}
vec4 worldViewPosition = world * view * vec4(position, 1.0);
worldViewPosition += vec4(mix(vec3(0.0), vec3(vertexOffset, 1.0), u_effectBlend), 0.0);
vUV = uv;
gl_Position = projection * worldViewPosition;
}
and
const shaderMaterial = new ShaderMaterial(
'shader',
scene,
{ vertex: 'custom', fragment: 'custom' },
{
attributes: ['position', 'uv'],
uniforms: ['world', 'view', 'projection'],
uniformBuffers: undefined,
shaderLanguage: ShaderLanguage.GLSL,
},
);
// Assign the shader material to the mesh
tree.material = shaderMaterial;
// Set initial uniform values
shaderMaterial.setFloat('u_remap', 1.0);
shaderMaterial.setFloat('u_normalize', 1.0);
shaderMaterial.setFloat('u_effectBlend', 1.0);
shaderMaterial.setMatrix('view', scene.getViewMatrix());
const foliage = tree.getChildMeshes().find((mesh) => mesh.name === 'foliage');
if (!foliage) {
return;
}
foliage.material = shaderMaterial;
shaderMaterial.setMatrix('world', foliage.getWorldMatrix());
As you can see, the vertex shaders have the following differences:
modelViewMatrix has been replaced with world * view.
projectionMatrix has been replaced with projection.
However, the shader isn’t working the same way as it does in ThreeJS.
Here’s the ThreeJS version:
And here is mine:
In mine, the mesh as a whole seems to rotate instead of the individual quads.
Any ideas would be greatly appreciated!