【发布时间】:2018-07-10 14:05:10
【问题描述】:
我正在尝试编写一个简单的着色器(在 THREE.js 的帮助下),其中颜色会随着时间的推移而更新(从黑色到白色)。
使用示例我正在计算经过的时间,然后使用它来设置我的 gl_FragColor,但是它不起作用:粒子保持黑色,然后在某个时间(大约 10 秒)突然弹出到 100%。
这是我的片段着色器:
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);
}
这是我设置材料的方式:
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,
});
这是我更新制服的方式(循环)
simulationMaterial.needsUpdate = true;
simulationMaterial.uniforms.uTime.value = Date.now();
我的顶点着色器工作正常:
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 );
}
真的看不出我做错了什么。
【问题讨论】:
-
一个猜测:乘以 0.1 可能是你得到 10 秒的原因。这相当于除以 10。对于这样的情况,我宁愿定义一个时间常数,该常数将确定转换完成所需的时间。您的问题也可能是 fract() 函数。请记住,您除以 1000.0,因此您的分辨率变为秒。
-
嘿,乘以 0.1 不是我认为的问题......它不会在 10 秒内突然变为白色......事实上它出现白色的时间似乎没有持续的。毫秒 / 1000 然后 * 0.1 应该使它每 10 秒从黑色变为白色......然后如果它超过 1.0,fract 函数应该使它回到 0.0。 (如果我删除了 fract 函数,或者我用 sin 测试,它也会被破坏)
-
我也只是尝试使用时间常数方法,它做了同样的事情。
-
现在,如果我计算 CPU 上经过的时间并将该值作为统一上传,而不是在着色器中计算它,我就可以正常工作了。我想知道 Date.now() 返回的值是否太大/超出范围。
-
抱歉,您发帖时我正在更新我的评论。我已经包含了 GLSL 文档的链接。希望有帮助!
标签: three.js glsl webgl fragment-shader