Curved Frosted Glass Shader?

后端 未结 1 350
闹比i
闹比i 2020-12-12 04:42

Well making something transparent isn\'t that difficult, but i need that transparency to be different based on an object\'s curve to make it look like it isn\'t just a flat

1条回答
  •  囚心锁ツ
    2020-12-12 05:32

    (moved comments into answer and added some more details)

    Use (Sub Surface) scattering instead of transparency.

    You can simplify things a lot for example by assuming the light source is constant along whole surface/volume ... so you need just the view ray integration not the whole volume integral per ray... I do it in my Atmospheric shader and it still looks pretty awesome almost indistinguisable from the real thing see some newer screenshots ... have compared it to the photos from Earth and Mars and the results where pretty close without any REALLY COMPLICATED MATH.

    There are more options how to achieve this:

    1. Voxel map (volume rendering)

      It is easy to implement scattering into volume render engine but needs a lot of memory and power.

    2. use 2 depth buffers (front and back face)

      this need 2 passes with Cull face on and CW/CCW settings. This is also easy to implement but this can not handle multiple objects in the same view along Z axis of camera view. The idea is to pass both depth buffers to shader and integrating the pixel rays along its path cumulating/absorbing light from light source. Something like this:

      1. render geometry to both depth buffers as 2 textures.
      2. render quad covering whole screen
      3. for each fragment compute the ray line (green)
      4. compute the intersection points in booth depth buffers obtain 'length,ang'
      5. integrate along the length using scattering to compute pixel color

        I use something like this:

           vec3 p,p0,p1; // p0 front and p1 back face ray/depth buffer intersection points
           int n=16; // integration steps
           dl=(p1-p0)/float(n); // integration step vector
           vec3 c=background color;
           float q=dot(normalize(p1-p0),light)=fabs(cos(ang)); // normal light shading
        
           for (p=p1,i=0;i p0 path through object
                {
                b=B0.rgb*dl;  // B0 is saturated color of object
                c.r*=1.0-b.r; // some light is absorbed
                c.g*=1.0-b.g;
                c.b*=1.0-b.b;
                c+=b*q;       // some light is scattered in
                } // here c is the final fragment color
        

      After/durring the integration you should normalize the color ... so that the resulting color is saturated around the real view depth of the rendered material. for more informatio see the Atmospheric scattering link below (this piece of code is extracted from it)

    3. analytical object representation

      If you know the surface equation then you can compute the light path intersections inside shader without the need for depth buffers or voxel map. This Simple GLSL Atmospheric shader of mine uses this approach as ellipsoids are really easily handled this way.

    4. Ray tracer

      If you need precision and can not use Voxel maps then you can try ray-tracing engines instead. But all scattering renderers/engines (#1,#2,#3 included) are ray tracers anyway... As you can see all techniques discussed here are the same the only difference is the method of obtaining the ray/object boundary intersection points.

    0 讨论(0)
提交回复
热议问题