Pipeline

Random stuff I'm working on, in chronological order.

2018 -- 2017 -- 2016

12 January 2018

Based on code by Paulo Falcao which is available on ShaderToy. It's licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

1280x720 resolution. The original code gives 35 fps. Replacing the atan() calls increases this to 47 fps. Then it's the usual steps of quality reductions and some unrolling to edge it above 60 fps. Gonna do a writeup about atan() one of these days. The NVidia implementation is ok, but the code is just inlined, not reordered.

8 January 2018

Some changes to make all the Xmas demo effects run in 60 fps:

Shader files, the ones changed since the video was released in bold:

Changes for 60 fps in Twofield:

It's running in 60 fps except during the transition, so let's save a bit more. The routine is already chopping off the left and right sides of the screen. But more can be removed, just not all the way down. Either mask out the areas using high-level GL or just quickly hack it into the shader:

 void main( void )
 {
    float xedge  = 256.0f/1920.0f;
    float yedge2 = 208.0f/1080.0f;
    float xedge2 = 416.0f/1920.0f;

    if(  (vt.x < xedge  || vt.x > 1.0f - xedge) ||
        ((vt.x < xedge2 || vt.x > 1.0f - xedge2) && vt.y > yedge2 && vt.y < 1.0f - yedge2 ) ) {
         outColor = vec4( 0.0f, 0.0f, 0.0f, colscale );
         return;
    }
    (...)

Also a trivial reduction in lightball() that the compiler doesn't do:

vec3 lightball( vec3 lpos, vec3 lcolor, vec3 O, vec3 D, float L )
{
    vec3 ldir = lpos - O;

    if( dot( ldir, ldir ) > L*L ) return vec3( 0.0f );

    float lv = 2.07f - ( ( ( lpos.z / 10.0f + 1.0f ) / 2.0f ) + 1.0f );

    float pw = pow( max( 0.0f, dot( normalize( ldir ), D ) ), 20000.0f * lv );

    return ( normalize( lcolor ) + 1.0f ) * pw;
}

Changes for 60 fps in Seascape:

Move ang, orig, m calculation to the CPU. Untangle heightMapTracing(). Discover that one of the two initial map() calls resolves to static value for all iterations: map( ori ). But just using a base value of 1.0f is more than precise enough. So main() becomes simpler:

(...)
    float hx = map( ori.xyz + dir * 1000.0f );
    if( hx > 0.0f ) {
        outColor = vec4( getSkyColor(dir), colscale );
        return;
    }

    vec3 p = heightMapTracing(ori.xyz,dir, hx );
(...)

And heightMapTracing() is changed to:

vec3 heightMapTracing( vec3 ori, vec3 dir, out float hx )
{
    vec3 p;
    float tm = 0.0;
    float tx = 1000.0;
//    float hm = map(ori);
    float hm = 1.0f; // ori fixed per frame, so close enough
    float tmid = 0.0;

    for( int i = 0; i < NUM_STEPS; i++ ) {
        tmid = mix( tm, tx, hm / (hm-hx) );
        p = ori + dir * tmid;
        float hmid = map( p );
        if( hmid < 0.0 ) {
            tx = tmid;
            hx = hmid;
        } else {
            tm = tmid;
            hm = hmid;
        }
    }
    return p;
}

Changes for 60 fps in Torus Thingy:

D'oh of the week: I_MAX is 100. Sounds rather arbitrary, it never gets to 100 iterations anyway. Reduce until framerate is above 60 all the way. A good value of I_MAX seems to be 52. Visual artifacts minimal.


www.ignorantus.com