zoukankan      html  css  js  c++  java
  • HLSL ddx / ddy

    HLSL ddx / ddy

      在光栅化的时刻,GPUs会在同一时刻并行运行很多Fragment Shader,但是并不是一个pixel一个pixel去执行的,而是将其组织在2x2的一组pixels分块中,去并行执行。

      偏导数就正好是计算的这一块像素中的变化率。从下图可以看出来ddx 就是右边的像素块的值减去左边像素块的值,而ddy就是下面像素块的值减去上面像素块的值。其中的x,y代表的是屏幕坐标。

        

    偏导数的应用

    1、LOD的确定。

      

      大家应该都知道mipmap 的用处,但是可能并不知道mipmap的核心在选择到底用那一块mipmap的level时,靠的就是偏导数。屏幕空间的贴图UV偏导数过大的时候代表贴图离我们过远,就会选择低等级的mipmap。

      比如,原图的LOD=1,次大的LOD=2,依此类推。

      

      在Shader中使用tex2D(tex, uv)的时候相当于在GPU内部展开成下面:
        

    tex2D(sampler2D tex, float4 uv)
    {
        float lod = CalcLod(ddx(uv), ddy(uv));
        uv.w= lod;
        return tex2Dlod(tex, uv);
    }

     

    2、计算法线。

      如果调用ddx(Pos),和ddy(Pos)这个代表求出相邻的2个像素块之间坐标的差值,即下面图中的红色和绿色2个矢量,而这2个矢量都在这个三角形的平面上,那么执行 normalize( cross(ddx(pos),ddy(pos)) ) 就求出的面的法线。

      但是这里要注意,在HlSL上面,或者Unity上面要写成normalize( cross(ddy(pos),ddx(pos)) ),不然法线是反向的。这个是由于左右手坐标系引起的。

    void surf (Input IN, inout SurfaceOutput o)
    
    {
    
    o.Albedo = normalize(cross(ddy(IN.worldPos),ddx(IN.worldPos)));
    
    }

      

    3、贴图加强勾边。

    void surf (Input IN, inout SurfaceOutput o)
    
    {
    
    half4 c = tex2D(_MainTex, IN.uv_MainTex);
    
    //c += ddx(c)*2 + ddy(c)*2;这行代码开启和关闭的效果
    
    o.Albedo = c.rgb;
    
    o.Alpha = c.a;
    
    }

      

      左边是直接显示图片,右边是在图片上面加上x和y的偏导数。

     【fwidth

      This function computes the following: abs(ddx(x)) + abs(ddy(x)).

      

    参考:

    1、https://blog.csdn.net/wylionheart/article/details/78026707

    2、http://www.aclockworkberry.com/shader-derivative-functions/#footnote_3_1104

  • 相关阅读:
    oracle 绿色版本 instantclient 使用说明
    response 后刷新页面,点击按钮后,禁用该按钮
    模式对话框里的CheckedChanged事件
    PDF合并
    Android手机上抓包神器
    春社日的推算方法
    Web APi入门之Self-Host(二)
    Web Api之Cors跨域以及其他跨域方式(三)
    Web APi入门之基本操作(一)
    Self Host WebApi服务传输层SSL加密(服务器端+客户端调用)
  • 原文地址:https://www.cnblogs.com/tekkaman/p/9542449.html
Copyright © 2011-2022 走看看