This will be my first question on stack overflow :) . On-render is a method that is called by rendering loop that I am trying to get to update the time uniform for my shaders. It seems to update on the first try, because if I change divisor and reload I see a change in what is rendered, but I see no animation / change over time. I can see that the time value is increasing from the last println statement. I don't think any on the .needsUpdate true should be necessary for uniforms, but I added them just to check. I've updated time uniforms in other code before successfully. What am I doing wrong this time? I am on the latest three.js dev branch. My next idea is to figure out where in three.js to add println statements to see what is going on with the uniforms in there.
EDIT: I made progress. If I set time to a random value instead of time I can see flickering / animation.
(defn on-render
[init-renderer component]
(let
[unit-meshes (engine/get-unit-meshes (:units component))
divisor 1000.0
t (/ (common/game-time) divisor)]
(doseq
[mesh unit-meshes]
(let
[material (-> mesh .-material)
uniforms (-> material .-uniforms)]
(-> uniforms .-time .-value (set! t))
(-> uniforms .-time .-needsUpdate (set! true))
(-> uniforms .-needsUpdate (set! true))
(-> material .-needsUpdate (set! true))
(-> mesh .-needsUpdate (set! true))
(println "value" (-> uniforms .-time .-value))
))))
My fragment shader is as follows (just to test that time is changing):
(def standard-fragment-shader
"
#define RECIPROCAL_PI 0.31830988618
varying vec2 vUV;
varying vec3 vLightFront;
uniform sampler2D map;
uniform float time;
void main() {
vec4 diffuseColor = texture2D(map, vUV);
vec3 directDiffuse = vLightFront * RECIPROCAL_PI * diffuseColor.rgb;
vec3 emissive = diffuseColor.rgb / 3.0;
vec3 outgoingLight = directDiffuse + emissive * sin(time);
gl_FragColor = vec4(outgoingLight, diffuseColor.a);
}
")
The material initialization is as follows:
(defn get-standard-material
[component]
(let
[light1 (data (:light1 component))
light-direction (-> light1 .-position .clone)
_ (-> light-direction (.sub (-> light1 .-target .-position)))
uniforms
#js
{
:time #js { :value 0.0 }
:map #js { :value nil }
:offsetRepeat #js { :value (new THREE.Vector4 0 0 1 1) }
:lightDirection #js { :value light-direction }
:boundingBoxSize # js { :value (new js/THREE.Vector3) }
}]
(new js/THREE.ShaderMaterial
#js
{
:uniforms uniforms
:vertexShader standard-vertex-shader
:fragmentShader standard-fragment-shader
})))
If you need additional context, all the code is committed to github and you can start here.