I've managed to get a  test implementation for the idea of filling the depth 
buffer early by clouds by inserting tracers into some of the cloud calls. The 
tracers are in essence just opaque white sheets marked with a top shade factor 
of 0.0 (black - no real cloud can ever have that low a value). There follow 
then two passes for cloud rendering - the first one does just the tracers and 
basically passes by all real clouds, the second pass does not consider tracers. 
During the first pass, depth buffer is written. Since there's one tracer per 
10-50 sprites and the operations done on the tracer are bare minimum, the 
additional workload caused by tracer rendering is small.

This has some quirks (the tracers become visible while the layer is drawn, 
although they are normally hidden by the real clouds, tracers at the edge of 
the range flicker,...), but it works... halfway. The depth buffer filled by the 
tracers does have a notable effect on other clouds, but not on the terrain. In 
numbers - in my benchmark situation I am halfway between a 2000 ft high Nimbus 
layer and the terrain. I get 20 fps looking straight at the horizon and 23 fps 
looking 30 deg up through the layer. With tracers I get 24 fps looking straight 
and 38 fps looking 30 degrees up, i.e. I am doing way faster to render the 
layer only. 

However, going above the cloud layer looking down, my framerate never changes. 
Even if I render only the tracers and zoom in so that only a while sheet is in 
my field of view (and no terrain pixels at all would have to be done) my 
framerate is still the same as without the tracer. In other words, the tracers 
in the depth buffer don't seem to work for the terrain, although they do work 
for other clouds. I've tested that I am not vertex-shader dominated by 
discarding half the pixels of the terrain in my field of view - that gave a 
noticeable framerate boost, so there's something else. I attach the effect xml 
for the additional first pass below. I'm not completely sure about all the 
aspects, but... it does the job on clouds, so it can't be that wrong. This 
should be done in render bin -1, i.e. before terrain. Very similar code for 
trees does have an impact for terrain rendering, i.e. an early tree pass does 
fill the depth buffer with effect on the terrain.

What am I not seeing?

 <pass>
      <lighting>true</lighting>
      <material>
        <ambient type="vec4d">0.5 0.5 0.5 1.0</ambient>
        <diffuse type="vec4d">0.5 0.5 0.5 1.0</diffuse>
        <color-mode>off</color-mode>
      </material>
     <depth>
        <function>lequal</function>
        <write-mask>true</write-mask>
      </depth>
      <render-bin>
        <bin-number>-1</bin-number>
        <bin-name>RenderBin</bin-name>
      </render-bin>
      <texture-unit>
        <unit>0</unit>
        <type>2d</type>
        <image><use>texture[0]/image</use></image>
        <wrap-s>clamp</wrap-s>
        <wrap-t>clamp</wrap-t>
      </texture-unit>
      <program>
        <vertex-shader>Shaders/tracer.vert</vertex-shader>
        <fragment-shader>Shaders/tracer.frag</fragment-shader>
        <attribute>
          <name>usrAttr1</name>
          <index>10</index>
        </attribute>
        <attribute>
          <name>usrAttr2</name>
          <index>11</index>
        </attribute>
      </program>
      <uniform>
        <name>baseTexture</name>
        <type>sampler-2d</type>
        <value type="int">0</value>
      </uniform>
      <uniform>
        <name>range</name>
        <type>float</type>
        <value><use>range</use></value>
      </uniform>
      <vertex-program-two-side>true</vertex-program-two-side>
    </pass>


Some other idea: If I extend the Nimbus layer all the way to 75 km visibility 
distance, I eventually become vertex-shader dominated in which case tracers are 
no longer a good strategy. It occurred to me that there's a fairly simple 
scheme we could try for this situation: 

We assign a random number [0..1] to each of the sprites such that all four 
vertices of the quad get the same number and pass that as attribute. Inside the 
shader, we dynamically compute a threshold based on distance (or perhaps better 
view angle) and check the random number against the threshold, so that say for 
50 km distance we render a quad only if its random number is above 0.8, for 70 
km only if its number is above 0.95. This would allow to dynamically dilute the 
clouds as we go further out, the checks inside the shader are computationally 
light and the visual effect should not be pronounced as we see the clouds under 
a very shallow angle at large distances. For very thin clouds which we don't 
want to discard, we can bias the random number distribution at creation time.

Stuart, is this feasible? There seems to be one free slot in the attribute 
vectors.

Thanks in advance for any additional insights.

* Thorsten
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel

Reply via email to