弧形磨砂玻璃着色器?

Curved Frosted Glass Shader?

好吧,制作透明的东西并不难,但我需要根据对象的曲线使透明度有所不同,以使其看起来不仅仅是一个平面对象。像下图这样的东西。

中心比圆柱体的两侧更透明,它更黑,这是背景色。然后是边框,顶部似乎有某种镜面照明以使其更闪亮,但我不知道在那种情况下如何实现透明度。使用相对于眼睛位置的表面法线来确定透明度值?任何帮助将不胜感激。

(将评论移至答案中并添加了更多详细信息)

使用(Sub Surface) scattering代替透明度。

你可以简化很多事情,例如假设光源在整个过程中是恒定的 surface/volume ...所以你只需要视图光线积分而不是每条光线的整个体积积分...我做它在我的大气着色器中,它看起来仍然非常棒,几乎与真实事物无法区分,请参阅 ...将它与地球和火星的照片进行比较,结果非常接近,没有任何真正复杂的数学。

有更多选项可以实现:

  1. 体素图(体积渲染)

    在体积渲染引擎中实现散射很容易,但需要大量内存和电源。

  2. 使用2个深度缓冲区(正面和背面)

    这需要 2 次通过剔除面和 CW/CCW 设置。这也很容易实现,但这不能处理沿相机视图 Z 轴的同一视图中的多个对象。这个想法是将两个深度缓冲区都传递给着色器,并沿其路径 cumulating/absorbing 从光源发出的光整合像素光线。像这样:

    1. 将几何图形作为 2 个纹理渲染到两个深度缓冲区。
    2. 渲染覆盖整个屏幕的四边形
    3. 为每个片段计算射线(绿色)
    4. 计算摊位深度缓冲区中的交点 获得'length,ang'
    5. 使用散射沿长度积分以计算像素颜色

      我用的是这样的:

         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<n;p1-=dp,i++)                // p = p1 -> 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 您应该将颜色归一化的集成...以便生成的颜色在渲染的真实视图深度周围饱和 material。有关更多信息,请参阅下面的大气散射 link(这段代码是从中提取的)

  3. 分析对象表示

    如果您知道表面方程,那么您可以在着色器内计算光路交点,而无需深度缓冲区或体素贴图。 Simple GLSL Atmospheric shader of mine 使用这种方法,因为这样处理椭球体真的很容易。

  4. 光线追踪器

    如果您需要精确度并且不能使用体素贴图,那么您可以尝试使用光线追踪引擎。但是所有散射 renderers/engines(包括 #1、#2、#3)无论如何都是光线追踪器……如您所见,所有 技术这里讨论的是一样的唯一的区别是获取ray/object边界交点的方法。