THREE.js r83
I'm trying to display a cartesian-style grid wireframe over my model, which needs to be animated (via AnimationMixer). I tried using the EdgesGeometry/LineBasicMaterial/LineSegments approach, as below (from this answer):
var geo = new THREE.EdgesGeometry( mesh.geometry );
var mat = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 2 } );
var wireframe = new THREE.LineSegments( geo, mat );
mesh.add( wireframe );
but unless I'm missing something, it doesn't seem like it can be animated (no morphTargets attribute, etc).
I've switched gears to trying a custom shader using ShaderMaterial or RawShaderMaterial with the following shaders (based on https://github.com/rreusser/glsl-solid-wireframe/tree/master/cartesian):
// vertex shader
precision mediump float;
uniform mat4 projection, view;
attribute vec3 position;
attribute vec3 barycentric;
varying vec3 b;
varying vec3 p;
void main () {
b = barycentric;
p = position;
gl_Position = projection * view * vec4(position, 1);
}
// fragment shader
precision mediump float;
varying vec3 b;
varying vec3 p;
uniform float cartesianX, cartesianY, cartesianZ;
uniform float width, feather;
float gridFactor (float parameter, float width_0, float feather_0) {
float w1 = width_0 - feather_0 * 0.5;
float d = fwidth(parameter);
float looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
return smoothstep(d * w1, d * (w1 + feather_0), looped);
}
float gridFactor (vec2 parameter, float width_0, float feather_0) {
float w1 = width_0 - feather_0 * 0.5; vec2 d = fwidth(parameter);
vec2 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
vec2 a2 = smoothstep(d * w1, d * (w1 + feather_0), looped);
return min(a2.x, a2.y);
}
float gridFactor (vec3 parameter, float width_0, float feather_0) {
float w1 = width_0 - feather_0 * 0.5;
vec3 d = fwidth(parameter);
vec3 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
vec3 a3 = smoothstep(d * w1, d * (w1 + feather_0), looped);
return min(min(a3.x, a3.y), a3.z);
}
float gridFactor (vec4 parameter, float width_0, float feather_0) {
float w1 = width_0 - feather_0 * 0.5;
vec4 d = fwidth(parameter);
vec4 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
vec4 a4 = smoothstep(d * w1, d * (w1 + feather_0), looped);
return min(min(min(a4.x, a4.y), a4.z), a4.w);
}
float gridFactor (float parameter, float width_0) {
float d = fwidth(parameter);
float looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
return smoothstep(d * (width_0 - 0.5), d * (width_0 + 0.5), looped);
}
float gridFactor (vec2 parameter, float width_0) {
vec2 d = fwidth(parameter);
vec2 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
vec2 a2 = smoothstep(d * (width_0 - 0.5), d * (width_0 + 0.5), looped);
return min(a2.x, a2.y);
}
float gridFactor (vec3 parameter, float width_0) {
vec3 d = fwidth(parameter);
vec3 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
vec3 a3 = smoothstep(d * (width_0 - 0.5), d * (width_0 + 0.5), looped);
return min(min(a3.x, a3.y), a3.z);
}
float gridFactor (vec4 parameter, float width_0) {
vec4 d = fwidth(parameter);
vec4 looped = 0.5 - abs(mod(parameter, 1.0) - 0.5);
vec4 a4 = smoothstep(d * (width_0 - 0.5), d * (width_0 + 0.5), looped);
return min(min(min(a4.x, a4.y), a4.z), a4.z);
}
void main () {
float g = gridFactor( vec3( cartesianX > 0.0 ? p.x * cartesianX : 0.5, cartesianY > 0.0 ? p.y * cartesianY : 0.5, cartesianZ > 0.0 ? p.z * cartesianZ : 0.5 ), width, feather);
gl_FragColor = vec4(mix(vec3(0), vec3(0.8), g), 1);
}
And here's how the RawShaderMaterial is defined:
new THREE.RawShaderMaterial({
// uniforms: uniforms,
derivatives: true,
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
depthTest: false,
side: THREE.DoubleSide,
wireframe: true,
lights: false,
visible: true,
color: 0x000000
}))
But with this approach, nothing is displayed, although I do get the following warning:
three.js:17014 THREE.WebGLProgram: gl.getProgramInfoLog() WARNING: Output of vertex shader 'b' not read by fragment shader
I'm not well versed in raw webgl code, so I'm not sure how critical that is.
To summarize:
It's my impression that EdgesGeometry/LineBasicMaterial/LineSegments approach cannot be animated as is, am I mistaken?
If one is true, I'm left with the shader approach. Can anyone with more webgl experience tell me what's going wrong here?
EDIT: It looks like the shader approach WON'T work for me, as it appears my shader will need to be able the handle drawing the animations, and I think that's just going to be too complex for me at this time. So back to part one, is there some way that I can get the LineSegments to animate with AnimationMixer, or maybe just replicate that look with another setup?