基于SDF的云朵消散效果

2023-10-13 00:20
文章标签 效果 sdf 云朵 消散

本文主要是介绍基于SDF的云朵消散效果,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.前置

SDF,即Signed Distance Function(符号距离函数)。SDF是一种数学表示方法,通常用于表示二维或三维几何图形的形状。关于这方面我也是找了许多的参考资料,都是二维的。(三维的我还没开始研究😢)

Signed Distance Field与Multi-channel signed distance field - 知乎前言最近总结了一下SDF方面的知识,参考了很多知乎上的文章,但是却发现对于SDF的圆角问题以及多通道SDF的参考资料却少得可怜。但是实际上UE4上已经有相关方面的插件: SharpText for Unreal Engine 4以及原作者的…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/398656596#:~:text=SDF%EF%BC%88signed,distance%20field%EF%BC%89%EF%BC%8C%E4%B8%AD%E6%96%87%E5%90%8D%E5%B8%A6%E7%AC%A6%E5%8F%B7%E8%B7%9D%E7%A6%BB%E5%9C%BA%EF%BC%8C%E6%9C%AC%E8%BA%AB%E5%8D%81%E5%88%86%E7%AE%80%E5%8D%95%EF%BC%8C%E5%B0%B1%E6%98%AF%E5%AF%B9%E6%AF%8F%E4%B8%AA%E5%83%8F%E7%B4%A0%E9%83%BD%E8%AE%B0%E5%BD%95%E8%87%AA%E5%B7%B1%E4%B8%8E%E8%B7%9D%E7%A6%BB%E8%87%AA%E5%B7%B1%E6%9C%80%E8%BF%91%E7%89%A9%E4%BD%93%E4%B9%8B%E9%97%B4%E7%9A%84%E8%B7%9D%E7%A6%BB%EF%BC%8C%E5%A6%82%E6%9E%9C%E5%9C%A8%E7%89%A9%E4%BD%93%E5%86%85%EF%BC%8C%E5%88%99%E8%B7%9D%E7%A6%BB%E4%B8%BA%E6%AD%A3%EF%BC%8C%E6%AD%A3%E5%A5%BD%E5%9C%A8%E7%89%A9%E4%BD%93%E8%BE%B9%E7%95%8C%E4%B8%8A%E5%88%99%E4%B8%BA0%E3%80%82SDF(signed distance field)基础理论和计算 - 知乎一、SDF基础理论1.1SDF简单介绍一般来说,无论2d或者3d资产都有 隐式(implicit)和显式(explicit)两种存储方式,比如3d模型就可以用mesh直接存储模型数据,也可以用sdf、点云(point cloud)、神经网络(nerual re…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/536530019Signed Distance Fieldsicon-default.png?t=N7T8http://www.codersnotes.com/notes/signed-distance-fields/这些资料都详尽准确地给我们介绍了了sdf,SDF描述了空间中的每个点到最近图形表面的有向距离(即距离的正负表示方向)。如果点位于图形表面内部,则距离为负;如果点位于图形表面外部,则距离为正;如果点位于图形表面上,则距离为零。

然后,然后我就照着写了一个python版本的

from PIL import Image
import mathimage = Image.open("表情.png")
picture_width = 1024
picture_height = 1024class Point:#dx,dy表示对于当前点的偏移值dx = 0;dy = 0;def __init__(self,y,x):self.dx = xself.dy = ydef DisSq(self):return self.dx*self.dx + self.dy*self.dy
class Grid:grid = Nonedef __init__(self,w,h):self.grid = [[Point(0,0) for i in range(w)] for j in range(h)]#g1和g2分别表示内部和外部两部分的距离
g1 = Grid(picture_width,picture_height)
g2 = Grid(picture_width,picture_height)#inside = Point(0,0)
#empty = Point(999,999)def Get(g,y,x):if x>=0 and x<picture_width and y>=0 and y<picture_height:return g.grid[y][x]else:return Nonedef Put(g,y,x,p):if x>=0 and x<picture_width and y>=0 and y<picture_height:g.grid[y][x] = pelse:return Nonedef Compare(g,curP,curY,curX,offsetY,offsetX):curDis = curP.DisSq()    if curX + offsetX>=0 and curX + offsetX<picture_width and curY + offsetY>=0 and curY + offsetY<picture_height:#nexP是偏移后的点nexP = g.grid[curY + offsetY][curX + offsetX]nexDis = Point(nexP.dy + offsetY,nexP.dx + offsetX)        if nexDis.DisSq()<curDis:#更新偏移值curP.dy = nexP.dy + offsetYcurP.dx = nexP.dx + offsetX#遍历周围8个格子,找到最近距离
def GenerateSDFs(g):#由上到下遍历,再由下到上遍历for i in range(picture_height):#由左到右遍历,再由右到左遍历for j in range(picture_width):curP = Get(g,i,j)Compare(g,curP,i,j,-1,0)Compare(g,curP,i,j,-1,-1)Compare(g,curP,i,j,0,-1)                for k in range(picture_width-1,-1,-1):curP = Get(g,i,k)Compare(g, curP, i,k,-1, 1)Compare(g, curP, i,k,0, 1)for i in range(picture_height-1,-1,-1):for k in range(picture_width - 1, -1, -1):curP = Get(g, i, k)Compare(g, curP, i,k,1, 1)Compare(g, curP, i,k,0, 1)for j in range(picture_width):curP = Get(g, i, j)Compare(g, curP, i,j,1, 0)Compare(g, curP, i,j,1, -1)Compare(g, curP, i,j,0, -1)return###########################
####      GenerateSDF
###########################
for i in range(picture_height):for j in range(picture_width):v = image.getpixel((j,i))if v[0]<128:Put(g1,i,j,Point(0,0))Put(g2,i,j,Point(999,999))else:Put(g2, i, j, Point(0,0))Put(g1, i, j, Point(999,999))
GenerateSDFs(g1)
GenerateSDFs(g2)###########################
####      Render the picture
###########################def clamp(v,min,max):if v<min:return minelif v>max:return maxelse:return vimage = Image.new('RGB', (picture_width, picture_height), color='white')# Access the pixels of the image
pixels = image.load()# min max
mi_g1 = 999
ma_g1 = 0
mi_g2 = 999
ma_g2 = 0
for y in range(picture_height):for x in range(picture_width):mi_g1 = min (mi_g1,g1.grid[y][x].DisSq())ma_g1 = max (ma_g1,g1.grid[y][x].DisSq())mi_g2 = min (mi_g2,g2.grid[y][x].DisSq())ma_g2 = max (ma_g2,g2.grid[y][x].DisSq())# Set the color of each pixel to red
for y in range(picture_height):for x in range(picture_width):#把外部距离重映射到0-128dist1 = math.floor((g2.grid[y][x].DisSq() / (ma_g2 - mi_g2)) * 128)#把内部距离重映射到0-128,并用128减去这个数,让距离最远处为0    dist2 = 128 - math.floor((g1.grid[y][x].DisSq() / (ma_g1 - mi_g1)) * 128)dist = dist1 + dist2#rgbpixels[x, y] = (dist,dist,dist)# Save the image
image.save('表情sdf.png')

输入:

输出:

 (有种难以言表的美,哈哈哈哈)

2.云消散效果的思路

做面片云也参考了许多的资料,分享一下

程序化天空盒实现昼夜变换 - 知乎一、资料收集与分析1.昼夜变换 Unity Shader 基于光照图的简易昼夜变化 Unity日夜循环天空球(Procedural Skybox) 【unity URP】昼夜循环天空球 Unity 卡通渲染 程序化天空盒 Unity 卡通渲染 程序化天空盒 昼夜变化…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/603032215Unity 卡通渲染 程序化天空盒 - 知乎写这篇文章快一年过去了,放两张在这期间里,用URP中最后做的仿原神的demo图。之前没考虑到tonemapping和叠加高度雾的效果。色彩参考原神和间谍过家家ED(约尔在天台24h的天空变化)。 分享一下学习过程中的碎碎念…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/540692272Signed Distance Field - 知乎signed distance field最近UE4.26上线了,离UE5又近了一点。UE的各种渲染大量运用了一种名为Signed Distance Field的技术,前段时间刷屏的《黑神话·悟空》的主程,在一次分享会上也介绍说《悟空》项目中,使用了S…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/337944099神作面部阴影渲染还原 - 知乎前几年学过两天渲染,昨天花了一个晚上,学Unity的shaderlab,做的这个还原。 结果折腾了半天我也没访问到shadowmap,只好装了URP然后在这个项目上写的代码 https://github.com/ColinLeung-NiloCat/UnityURPToonLi…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/279334552卡通渲染之基于SDF生成面部阴影贴图的效果实现(URP) - 知乎看了很多大佬的教程: 黑魔姬:神作面部阴影渲染还原 这篇讲了图的制作流程(大概思路) Signed Distance Fields 这篇讲了SDF的算法 橘子猫:如何快速生成混合卡通光照图 这是之前一个群里的大佬写的脚本,可以生…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/361716315大佬们做云阈值图的时候似乎都采用了多张图插值的方式(),这种方法可以自由控制消散的开始位置和结束位置。

图片来源: Unity 卡通渲染 程序化天空盒 - 知乎

但是本懒狗直接把云的贴图扔进python脚本用8ssedt方法处理。(在脚本中我只使用了内部距离)

输入:云.png

(这张图是没有亮部和暗部的,是纯白的云的轮廓图)

 输出:云sdf.png

 效果:

 额,效果不太行,到最后甚至变成了一个不规则多变型,甚至不能称之为云

如果我把云的阴影图和生成的sdf图混合一下会怎样

输入:云.png

(这张图是没有亮部和暗部的,是纯白的云的轮廓图)

云阴影.png

(自己画的云,丑是丑了点)

 输出:

 效果:

 好很多了,虽然到后面还是那样😂,只是让阴影图*0.5 + sdf图 * 0.5

其它优化方法还没试,这种方法的缺点也很明显,消散的最后位置一定是中心(可以用ps的变形工具弄一下)

SDF_cloud

这篇关于基于SDF的云朵消散效果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/199454

相关文章

防近视护眼台灯什么牌子好?五款防近视效果好的护眼台灯推荐

在家里,灯具是属于离不开的家具,每个大大小小的地方都需要的照亮,所以一盏好灯是必不可少的,每个发挥着作用。而护眼台灯就起了一个保护眼睛,预防近视的作用。可以保护我们在学习,阅读的时候提供一个合适的光线环境,保护我们的眼睛。防近视护眼台灯什么牌子好?那我们怎么选择一个优秀的护眼台灯也是很重要,才能起到最大的护眼效果。下面五款防近视效果好的护眼台灯推荐: 一:六个推荐防近视效果好的护眼台灯的

【Godot4.3】多边形的斜线填充效果基础实现

概述 图案(Pattern)填充是一个非常常见的效果。其中又以斜线填充最为简单。本篇就探讨在Godot4.3中如何使用Geometry2D和CanvasItem的绘图函数实现斜线填充效果。 基础思路 Geometry2D类提供了多边形和多边形以及多边形与折线的布尔运算。按照自然的思路,多边形的斜线填充应该属于“多边形与折线的布尔运算”范畴。 第一个问题是如何获得斜线,这条斜线应该满足什么样

UniApp实现漂亮的音乐歌词滚动播放效果

在现代的音乐播放应用中,歌词的展示和滚动播放已经成为了一个非常常见的功能。今天,我们将通过UniApp来实现一个漂亮的歌词滚动播放功能。我们将使用UniApp提供的组件和API来完成这个任务。 页面结构 在页面的模板部分,我们需要创建一个音频播放器和歌词展示区域。使用<scroll-view>组件来实现歌词的滚动效果。 <template><view class="audio-co

Nuxt3入门:过渡效果(第5节)

你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。 Nuxt 利用 Vue 的 <Transition> 组件在页面和布局之间应用过渡效果。 一、页面过渡效果 你可以启用页面过渡效果,以便对所有页面应用自动过渡效果。 nuxt.config.js export default defineNuxtConfig({app: {pageTransition: {name: 'fade',mode

Differential Diffusion,赋予每个像素它应有的力量,以及在comfyui中的测试效果

🥽原论文要点 首先是原论文地址:https://differential-diffusion.github.io/paper.pdf 其次是git介绍地址:GitHub - exx8/differential-diffusion 感兴趣的朋友们可以自行阅读。 首先,论文开篇就给了一个例子: 我们的方法根据给定的图片和文本提示,以不同的程度改变图像的不同区域。这种可控性允许我们再现

【Unity小技巧】URP管线遮挡高亮效果

前言 在URP渲染管线环境下实现物体遮挡高亮显示效果,效果如下: Unity URP遮挡高亮 实现步骤 创建层级,为需要显示高亮效果的物体添加层级,比如Player 创建一个材质球,也就是高亮效果显示的材质球找到Universal Renderer Data Assets 4.在Assets上添加两个Render Objects组件 第一个做如下三处设置 指定遮挡层级指

海鲜加工污水处理设备处理效果高

诸城市鑫淼环保小编带大家了解一下海鲜加工污水处理设备处理效果高   海鲜加工污水处理设备通常采用物理、化学和生物处理相结合的方法,对废水中的污染物进行高xiao去除。设备设计紧凑,占地面积小,操作简便,适用于不同规模的海鲜加工厂。   设备特点   高xiao性:采用先进的处理工艺和技术,确保废水处理效果稳定可靠。   占地面积小:设备设计紧凑,占地面积小,适合在有限的空间内安装。

图像分割分析效果2

这次加了结构化损失 # 训练集dice: 0.9219 - iou: 0.8611 - loss: 0.0318 - mae: 0.0220 - total: 0.8915  # dropout后:dice: 0.9143 - iou: 0.8488 - loss: 0.0335 - mae: 0.0236 - total: 0.8816 # 加了结构化损失后:avg_score: 0.89

Untiy TTF转换为SDF

Untiy TTF转换为SDF 原因 下载的字体是TTF格式,但是TMP使用的是SDF格式,不支持TTF,需要转换网络没有检索到TTF转SDF的教程,可能是太简单了,自己记录一下吧 Unity内转换即可 在Asset中找到自己的TTF右键点击TTF,找到TMP,选择Font Asset 即可将自己下载的TTF字体转换为SDF格式 补充-修改默认的SDF 就是每次都自己拖动SDF效率低