HLSL ddx / ddy

Posted tekkaman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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,依此类推。

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的偏导数。

 

参考:

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

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

 

以上是关于HLSL ddx / ddy的主要内容,如果未能解决你的问题,请参考以下文章

为啥 HLSL 有语义?

Unreal4材质表达式实用表达式类节点讲解0015

Cg入门25: Fragment shader – UV动画(模糊)

在 HLSL 着色器中任意限制值时避免“如果”

WPF 像素着色器入门:使用 Shazzam Shader Editor 编写 HLSL 像素着色器代码

Unity中HLSL代码块的基本知识归纳整理