我有一个使用 Three.js 创建的粒子系统,其中每个粒子都有一组相关的参数(x,y,z,成本,炒作等等),我还保留每个的最小值/最大值。我已将这些定义为属性并创建了统一的最小/最大条目。通过滑块修改均匀值,以充当范围过滤器。
attributes["aGain"] = { type: "f", value: [] };
uniforms["uGainMin"] = { type: "f", value: 10.0 };
uniforms["uGainMax"] = { type: "f", value: 15.0 };
在顶点着色器中,我声明属性和变量以充当FS的标志。 1.0表示可见,0.0表示丢弃。
varying float vectorVisible;
attribute float again;
然后我将每个属性与相应的统一值进行比较。
if (aGain < uGainMin || aGain > uGainMax) { vectorVisible = 0.0; }
else { vectorVisible = 1.0; }
if
块具有每个属性/统一配对的条件。
在片段着色器中,我检查vertexVisible
的值。
if (vectorVisible == 0.0) discard;
一旦过滤器滑块值大于0,我的整个粒子系统就会消失。
作为一个完整性检查我已经尝试将vertexVisible
设置为0.0,如果在VS中gl_Position.x组件小于0并且确实导致这些片段被丢弃。
if (gl_Position.x < 0.0) vectorVisible = 0.0;
else vectorVisible = 1.0;
我的属性数组已正确填充,我在编译或运行时没有收到任何警告。那么,我是否完全没有这个想法呢?
My related initial question regarding filtering by parameters
这是整个顶点着色器。我必须在THREE.js 粒子基本着色器中使用它,这就是为什么它在gl_Position
函数中设置main
的原因。
uniform float size;
uniform float scale;
attribute float ay;
uniform float uyMin;
uniform float uyMax;
attribute float ax;
uniform float uxMin;
uniform float uxMax;
attribute float az;
uniform float uzMin;
uniform float uzMax;
attribute float again;
uniform float ugainMin;
uniform float ugainMax;
#ifdef USE_COLOR
varying vec3 vColor;
#endif
#ifdef USE_SHADOWMAP
varying vec4 vShadowCoord[ MAX_SHADOWS ];
uniform mat4 shadowMatrix[ MAX_SHADOWS ];
#endif
void main() {
#ifdef USE_COLOR
#ifdef GAMMA_INPUT
vColor = color * color;
#else
vColor = color;
#endif
#endif
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
#ifdef USE_SIZEATTENUATION
gl_PointSize = size * ( scale / length( mvPosition.xyz ) );
#else
gl_PointSize = size;
#endif
gl_Position = projectionMatrix * mvPosition;
#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )
#ifdef USE_SKINNING
vec4 worldPosition = modelMatrix * skinned;
#endif
#if defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )
vec4 worldPosition = modelMatrix * vec4( morphed, 1.0 );
#endif
#if ! defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
#endif
#endif
#ifdef USE_SHADOWMAP
for( int i = 0; i < MAX_SHADOWS; i ++ ) {
vShadowCoord[ i ] = shadowMatrix[ i ] * worldPosition;
}
#endif
/***** Filters *****/
if (ay < uyMin || ay > uyMax) gl_Position.xyz = vec3(2.);
else if (ax < uxMin || ax > uxMax) gl_Position.xyz = vec3(2.);
else if (az < uzMin || az > uzMax) gl_Position.xyz = vec3(2.);
else if (again < ugainMin || again > ugainMax) gl_Position.xyz = vec3(2.);
}
查看(不)工作here。
答案 0 :(得分:2)
基于新信息:
添加:
var material = new THREE.ShaderMaterial({
attributes:{
aGain:{
type:"f",
value:null
}
},
fragmentShader: fs_source....
我无法解释原因,但它应该有效。 :)
没有它我根本无法让aGain出现(就gpu而言,它们都是0)。
我不知道答案的正确程序是什么。另一个答案是关于裁剪的事情,这是为了
&#34;为什么我的自定义three.js属性缓冲区未显示在着色器材质中?&#34;。
答案 1 :(得分:1)
我认为你再次以错误的方式做这件事:)
尝试将此作为片段着色器
void main(){
gl_FragColor = vec4(1.);
}
并模拟剪辑在顶点着色器中沿着这一行尝试一些东西:
if (aGain < uGainMin || aGain > uGainMax) {
gl_Position = vec4(vec3(2.),1.0);//this might work, move it out of NDC and clip
} else {
gl_Position = yourlogic; // for example: projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
如果您已经知道需要丢弃此对象,为什么要对其进行栅格化并进行测试。想象一下,如果这是一个占据大部分屏幕的大颗粒。您最不重要的是运行片段着色器并测试每个像素。虽然你可以通过移动一个或四个顶点来消除它,就像粒子一样。