How do I calculate pixel shader depth to render a circle drawn on a point sprite as a sphere that will intersect with other objects?

前端 未结 3 1948
野的像风
野的像风 2020-12-28 09:15

I am writing a shader to render spheres on point sprites, by drawing shaded circles, and need to write a depth component as well as colour in order that spheres near each ot

3条回答
  •  独厮守ぢ
    2020-12-28 09:42

    Sphere will not project into a circle in general case. Here is the solution.

    This technique is called spherical billboards. An in-depth description can be found in this paper: Spherical Billboards and their Application to Rendering Explosions

    You draw point sprites as quads and then sample a depth texture in order to find the distance between per-pixel Z-value and your current Z-coordinate. The distance between the sampled Z-value and current Z affects the opacity of the pixel to make it look like a sphere while intersecting underlying geometry. Authors of the paper suggest the following code to compute opacity:

    float Opacity(float3 P, float3 Q, float r, float2 scr)
    {
       float alpha = 0;
       float d = length(P.xy - Q.xy);
       if(d < r) {
          float w = sqrt(r*r - d*d);
          float F = P.z - w;
          float B = P.z + w;
          float Zs = tex2D(Depth, scr);
          float ds = min(Zs, B) - max(f, F);
          alpha = 1 - exp(-tau * (1-d/r) * ds);
       }
       return alpha;
    }
    

    This will prevent sharp intersections of your billboards with the scene geometry.

    In case point-sprites pipeline is difficult to control (i can say only about OpenGL and not DirectX) it is better to use GPU-accelerated billboarding: you supply 4 equal 3D vertices that match the center of the particle. Then you move them into the appropriate billboard corners in a vertex shader, i.e:

    if ( idx == 0 ) ParticlePos += (-X - Y);
    if ( idx == 1 ) ParticlePos += (+X - Y);
    if ( idx == 2 ) ParticlePos += (+X + Y);
    if ( idx == 3 ) ParticlePos += (-X + Y);
    

    This is more oriented to the modern GPU pipeline and of coarse will work with any nondegenerate perspective projection.

提交回复
热议问题