WebGL - 丢弃由顶点着色器标记的片段

时间:2014-06-26 17:47:24

标签: opengl-es three.js webgl shader

我有一个使用 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.);
}

的jsfiddle

查看(不)工作here

2 个答案:

答案 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);
}

如果您已经知道需要丢弃此对象,为什么要对其进行栅格化并进行测试。想象一下,如果这是一个占据大部分屏幕的大颗粒。您最不重要的是运行片段着色器并测试每个像素。虽然你可以通过移动一个或四个顶点来消除它,就像粒子一样。