[英]GLSL Fragment Shader: control color by time passed
I am trying to write a simple shader (with the help of THREE.js), where the colour will update as time passes (from black to white). 我正在尝试编写一个简单的着色器(在THREE.js的帮助下),其中颜色将随着时间的流逝而更新(从黑色到白色)。
Using examples I am calculating the time passing, and then using this to set my gl_FragColor, however it is not working: The particles stay black, and then suddenly pop to 100% some time in (approx 10seconds). 通过示例,我正在计算时间的流逝,然后使用它来设置我的gl_FragColor,但是它不起作用:粒子保持黑色,然后突然在大约10秒的时间内突然弹出到100%。
Here is my fragment Shader: 这是我的片段着色器:
precision highp float;
uniform float uTime;
uniform float uStartTime;
void main() {
float timePassed = (uTime - uStartTime) / 1000.0 * 0.1;
gl_FragColor = vec4(fract(timePassed), fract(timePassed), fract(timePassed), 1.0);
}
Here is how I set up my material: 这是我设置材料的方式:
const simulationMaterial = new THREE.ShaderMaterial({
uniforms: {
tPositions: { type: 't', value: positionsTexture },
tOrigins: { type: 't', value: originsTexture },
tPerlin: { type: 't', value: perlinTexture },
uTime: { type: 'f', value: 0.0 },
uStartTime: { type: 'f', value: Date.now() },
},
vertexShader: vertexSimulationShader,
fragmentShader: fragmentSimulationShader,
side: THREE.DoubleSide,
transparent: true,
});
And here is how I'm updating the uniforms (in a loop) 这是我更新制服的方法(循环)
simulationMaterial.needsUpdate = true;
simulationMaterial.uniforms.uTime.value = Date.now();
My vertex shader is working fine: 我的顶点着色器工作正常:
precision highp float;
uniform vec3 color;
uniform sampler2D tPositions;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
attribute vec2 uv;
attribute vec3 position;
attribute vec3 offset;
attribute vec3 particlePosition;
attribute vec4 orientationStart;
attribute vec4 orientationEnd;
varying vec3 vPosition;
varying vec3 vColor;
void main(){
vPosition = position;
vec4 orientation = normalize( orientationStart );
vec3 vcV = cross( orientation.xyz, vPosition );
vPosition = vcV * ( 2.0 * orientation.w ) + ( cross( orientation.xyz, vcV ) * 2.0 + vPosition );
vec4 data = texture2D( tPositions, uv );
vec3 particlePosition = (data.xyz - 0.5) * 1000.0;
vColor = data.xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4( vPosition + particlePosition, 1.0 );
}
Really can't see what I'm doing wrong. 真的看不到我在做什么错。
The shader's highp float
type, which is 32-bit, is not large enough to represent accurately values as big as Date.now(). 着色器的
highp float
类型为32位,不足以准确表示与Date.now()一样大的值。 In fact, the last integer that is accurately representable as a 32-bit float is 16,777,217 , which is 5 orders of magnitude smaller than Date.now()
today. 实际上,可以精确表示为32位浮点数的最后一个整数是16,777,217 ,比今天的
Date.now()
小5个数量级。 That is to say, this type is not large enough to meaningfully be able to calculate (Date.now()+10) - Date.now())
. 也就是说,此类型的大小不足以有意义地计算
(Date.now()+10) - Date.now())
。 Javascript engines represent numbers as 64-bit floats, which has the necessary range for the arithmetic to work sufficiently precisely. JavaScript引擎将数字表示为64位浮点数,该数字具有使算法足够精确地工作所需的范围。
You have found the correct solution yourself - do the really big arithmetic on the CPU in big enough types. 您自己找到了正确的解决方案-以足够大的类型在CPU上执行真正的大运算。 Calculate the elapsed time on the CPU and pass it as a uniform to the shader.
计算CPU上经过的时间,然后将其作为均匀值传递给着色器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.