AreaTex

  • 以下均在无SubPixel的情况下,即offset = (0,0)。subpixel将单独讲解。

areaortho.area

# Calculates the area under the line p1->p2, for the pixel x..x+1:def area(p1, p2, x):

  1. 计算底边长
 d = p2[0] - p1[0], p2[1] - p1[1]x1 = float(x)x2 = x + 1.0y1 = p1[1] + d[1] * (x1 - p1[0]) / d[0]y2 = p1[1] + d[1] * (x2 - p1[0]) / d[0]


依据三角形相似原理:
Y1 / (x1 - p1[0]) = d[1] / d[0] => Y1 = d[1] * (x1 - p1[0]) / d[0]
p1 = [0, o2] = [0, 0.5 + offset - 1.0] => p1[1] < 0
所以:y1 = p1[1] + Y1 = p1[1] + d[1] * (x1 - p1[0]) / d[0]
同理:y2 = p1[1] + Y2 = p1[1] + d[1] * (x2 - p1[0]) / d[0]


  1. 判断是梯形还是三角形
inside = (x1 >= p1[0] and x1 < p2[0]) or (x2 > p1[0] and x2 <= p2[0])if inside:istrapezoid = (copysign(1.0, y1) == copysign(1.0, y2) or abs(y1) < 1e-4 or abs(y2) < 1e-4)

  1. 计算面积
    一个梯形:

    area = (y1 + y2) * (x2 - x1) / 2
    其中:x2 - x1 = 1
    area = abs(y1 + y2) / 2
    a1 = area
    a2 = 0

两个三角形:

a1 = (x - x1) * y1 / 2
设 X1 = x - x1,要求面积,就要求出 X1。
从图中可以看出,X1 正好是 X 的小数部分。
只要求出X就能得出面积。
根据三角形相似,
X = (-1 * p1[1]) * d[0] / d[1]
x = X + p1[0] = -p1[1] * d[1] / d[1] + p1[0]
所以,a1 = y1 * modf(x) / 2
同理:a2 = y2 * (1 - modf(x)) / 2


areaortho

# Horizontal/Vertical Areas# Calculates the area for a given pattern and distances to the left and to the
# right, biased by an offset:
def areaortho(pattern, left, right, offset):

计算横向 / 纵向锯齿类型的面积。
patterns

具体计算略,套公式即可


smootharea

# Smoothing function for small u-patterns:
def smootharea(d, a1, a2):b1 = (a1 * 2.0).sqrt() * 0.5b2 = (a2 * 2.0).sqrt() * 0.5p = saturate(d / float(SMOOTH_MAX_DISTANCE))return lerp(b1, a1, p), lerp(b2, a2, p)


短U型锯齿有重复部分。
中间两个三角形面积为a1, a2。
计算时,左边a1只计算像素左边部分, 右边a2只计算像素右边部分。
为了得到整个像素的值,融合a1, a2,得到一个平滑过渡值。
长U型锯齿不存在交集。
计算时a1, a2必定有一个为 0. 即使参与计算也不会改变值。

tex2dortho

# Creates a 2D orthogonal pattern subtexture:
def tex2dortho(args):pattern, path, offset = argssize = (SIZE_ORTHO - 1)**2 + 1tex2d = Image.new("RGBA", (size, size))for y in range(size):for x in range(size):p = areaortho(pattern, x, y, offset)p = p[0], p[1], 0.0, 1.0tex2d.putpixel((x, y), bytes(p))

计算直角锯齿面积
SIZE_ORTHO = 16
16个像素能存放[0 - 15],也就是搜索的最大距离只有15。
对于纹理边界是不够用的。
为了能访问到更大的距离,size = (SIZE_ORTHO - 1)^2 + 1 = 226。


pattern7(226 * 226)


tex4dortho

把tex2dortho计算后的tex2d存入tex4d的左半部分。

# Calculate the orthogonal patterns 4D texture for a given offset:
def tex4dortho(tex4d, files, y, offset):

tex2dortho得出的tex2d
size = 226 * 226,但是每个pattern在tex4d中占的大小是 16 * 16,
这样就需要一个压缩算法,用16个像素存放226个值。
观察上面pattern 7纹理图,基本还是一个线性变化的值。
所以以坐标:x = x ^ 2, y = y ^ 2,取16个值。
通过tex4d双线性采样,得出误差很小的值。
距离越小,精度越大,很长的锯齿可以忽略误差。


areadiag.area1

# Calculates the area under the line p1->p2 for the pixel 'p' using brute# force sampling:# (quick and dirty solution, but it works)def area1(p1, p2, p):

在这里使用了暴力计算。
将一个像素分成 SAMPLES_DIAG * SAMPLES_DIAG = 30 * 30 = 900个小区块。
把在p1->p2这条射线的下方的小区块相加,除以900。
其实就是计算该像素点在p1->p2下方的面积。

为什么要暴力计算呢?
直接计算面积的话,就要分清各种锯齿形状,麻烦!
这种方式,只需要判断小区块是否在线的下方,相加即可。

但是,这种方式会产生2个问题:

第一:判断小区块是否在p1->p2下面时,与p1->p2相邻的小区块的计算会存在误差,导致错误。
临近的点最多也只有30个,不会对结果有实质性改变。

第二:如下图,分成了30 * 30 = 900个小块.
白色线条为p1->p。
p1->p2下方的小块数量是 :(900 - 30) / 2 = 435,面积是:435 / 900 = 0.4833333
p1->p2上方以及p1->p2上的数量是 (900 - 435) = 465,面积是:0.51666667
所以,计算后的权重会存在小范围误差。

areadiag.area

# Calculates the area under the line p1->p2:# (includes the pixel and its opposite)def area(p1, p2, left, offset):e1, e2 = edgesdiag[pattern]p1 = p1 + vec2(*offset) if e1 > 0 else p1p2 = p2 + vec2(*offset) if e2 > 0 else p2a1 = area1(p1, p2, vec2(1.0, 0.0) + vec2(left, left))a2 = area1(p1, p2, vec2(1.0, 1.0) + vec2(left, left))return vec2(1.0 - a1, a2)

图示:灰黑色部分表示所求部分


areadiag

计算对角线面积

# Diagonal Areas# Calculates the area for a given pattern and distances to the left and to the
# right, biased by an offset:
def areadiag(pattern, left, right, offset):

pattern 类型.

大致计算目标图示:

具体计算略,套公式即可


tex2ddiag

# Creates a 2D diagonal pattern subtexture:
def tex2ddiag(args):pattern, path, offset = argstex2d = Image.new("RGBA", (SIZE_DIAG, SIZE_DIAG))for y in range(SIZE_DIAG):for x in range(SIZE_DIAG):p = areadiag(pattern, x, y, offset)p = p[0], p[1], 0.0, 0.0tex2d.putpixel((x, y), bytes(p))tex2d.save(path, "TGA")

对角线tex2d


tex4ddiag

把tex2ddiag装入tex4d的右半部分。

# Calculate the diagonal patterns 4D texture for a given offset:
def tex4ddiag(tex4d, files, y, offset):

assemble

# Assembles 2D pattern subtextures into a 4D texture:
def assemble(tex4d, files, edges, pos, size, compress):

把tex2d装入tex4d中


SMAA算法详解 - AreaTex相关推荐

  1. SMAA算法详解 - SearchTex

    SearchTex SearchTex.png (x10) 边界样式 # This dict returns which edges are active for a certain bilinear ...

  2. SMAA算法详解 - SMAANeighborhoodBlendingPS

    目录 - SMAA代码详解 SMAANeighborhoodBlendingPS //--------------------------------------------------------- ...

  3. SMAA算法详解 - SMAALumaEdgeDetectionPS

    目录 - SMAA代码详解 SMAALumaEdgeDetectionPS /*** Luma Edge Detection** IMPORTANT NOTICE: luma edge detecti ...

  4. SMAA算法详解 - SMAANeighborhoodBlendingVS

    目录 - SMAA代码详解 SMAANeighborhoodBlendingVS /*** Neighborhood Blending Vertex Shader*/ void SMAANeighbo ...

  5. SMAA算法详解 - SMAABlendingWeightCalculationVS

    SMAABlendingWeightCalculationVS /*** Blend Weight Calculation Vertex Shader*/ void SMAABlendingWeigh ...

  6. SMAA算法详解 - SMAADetectHorizontalCornerPattern

    SMAADetectHorizontalCornerPattern 修正水平转角 //--------------------------------------------------------- ...

  7. SMAA算法详解 - SMAAEdgeDetectionVS

    SMAAEdgeDetectionVS ​计算从当前像素点到目标像素点的偏移值. /*** Edge Detection Vertex Shader*/ void SMAAEdgeDetectionV ...

  8. SMAA算法详解 - SMAADetectVerticalCornerPattern

    SMAADetectVerticalCornerPattern void SMAADetectVerticalCornerPattern(SMAATexture2D(edgesTex), inout ...

  9. SMAA算法详解 - SMAADepthEdgeDetectionPS

    SMAADepthEdgeDetectionPS /*** Depth Edge Detection*/ float2 SMAADepthEdgeDetectionPS(float2 texcoord ...

最新文章

  1. PySide2 基础入门-创建实例窗口(详细解释)
  2. 3.10 程序示例--神经网络设计-机器学习笔记-斯坦福吴恩达教授
  3. 如何创建HTML Mashup并插入到SAP Cloud for Customer标准页面里
  4. 业务配置开发平台qMISPlat 2.0 产品介绍
  5. 芯片测试探针卡_测试接口业者先受惠苹果A14 GPU双雄4Q再加Socket、探针卡急单
  6. arcgis 删除图形重复折点_【干货】ArcGIS中画环状图斑、挑子区及消除图斑重复区域...
  7. It was in 2006, and as a desktop computer
  8. 语音识别软件_语音识别软件是什么_离线语音识别软件_企业服务汇
  9. duilib中各控件响应的消息类型
  10. nike tiempo ylak raoh fmtp
  11. (高级)Matlab绘制中国地图超全教程详解
  12. 安卓软件开发面试题!五年Android开发者小米、阿里面经,小白也能看明白
  13. 开方在java中怎么计算_JAVA BigDecimal使用牛顿迭代法计算平方根(开方)
  14. 常用的数据挖掘建模工具
  15. 700页JVM虚拟机实战手册,呕心巨作,值得一看
  16. thinkphp6学习教程与源码 tp6开源CMS系统源码研究
  17. flutter中地图定位
  18. win2008系统 安装hplaserj1010打印机驱动程序
  19. 为什么不建议用字符串或者uuid做数据库主键
  20. 聊聊那些令人愉悦的动画特效(GIF图)

热门文章

  1. Nginx无证书反向代理
  2. (linux vm虚拟机网络连接失败,重启网卡失败原因及解决办法)
  3. Qt 官方例子 Callout Example
  4. 数据安全传输平台项目笔记
  5. oracle pdb监听配置,oracle 12c 监听
  6. 仿elem页面学习之表单提交的动作
  7. 乐有家携手法大大,实现租房签约数字化
  8. comparison lemma
  9. C# 重载 Equals() 方法、重载运算符、声明显隐式转换的简要整理
  10. b站React禹哥版视频笔记-React面向组件编程(上)