分类 developer 下的文章

UE4 3D Widget受后期影响问题的处理

UMG渲染时,若使用世界空间,则将使用Plane或Cylinder在场景中形成mesh的方式来处理。这样一来所有的Widget如同场景中的普通mesh,会出现在渲染管线中处理普通半透明物体的pass。此Pass位于所有后期pass之前。这样一来包括motion blur, tonemapping, TAA等均会影响Widget的显示

最为明显的症状是在相机移动时POI Widget上面的字出现严重模糊。Widget面板的颜色偏黄(Tonemapping)等

使用屏幕空间渲染则会被UE4以特殊的pass来handle(出现在后期之后,无法用renderDoc捕获),不会出现此问题

思路

让渲染3D Widget的pass出现在后期pass之后

做法

把Widget pass放到单独一个RT上

创建一个Render Target。注意将分辨率设置为与最终主相机输出的分辨率一致

使用sceneCapture2D component,与主相机同步。设置ShowOnlyComponet限制为只渲染场景中的3D Widget,并将结果输出到某个RT。注意bConsiderUnrenderedOpaquePixelAsFullyTranslucent需要为True

1571969089808.png

准备用于输出RT的pp

创建一个post processing类型的材质球。将blend location设置为After tonemapping。给此材质球设置一个Texture parameter

1571969746372.png

将给hack用的bp再增加一个单独的post processing component。用上一步创建的材质球初始化一份Dynamic Material Instance并喂给后期设置

1571969855165.png

1571969883633.png

让3D Widget材质使用User Interface 与 Trancelucent Blend的时候也能输出深度信息

这里可能涉及个trick

当Blend Mode为Trancelucent的时候,Widget Component开启Render CustomDepth Pass并不会生效(v4.23)。似乎需要在所用材质球中开启Allow Custom Depth Writes

但当材质球类型为User Interface的时候,其选项中是没有Allow Custom Depth Writes的。将材质球切换为surface后,该选项出现并勾选,再切换回User Interface,配合Widget Component上的选项,就能正常输出CustomDepth了

最后让Widget Component使用这个定制的材质球

更新sceneCapture2D的Transform和传递RT

1571971224113.png

后期材质球

思路是让Widget深度信息起效,处理遮挡

然后让传入的RT与常规pass做blend出最终结果

1571971031070.png

调整BP的更新时机

让Tick的更新时机处于物理更新后。否则RT会与主Pass结果差一帧,导致相机在快速移动时能看到明显的重影

1571971357444.png

最终结果

1571971537542.png

YouCompleteMe在Windows环境下安装折腾记录

YCM以安装设置繁琐出名
但最近的版本对于这方面已经有了相当的提升
只要确保环境配置满足需求,安装步骤相对以往会顺利很多
这里记录下在Win8.1系统环境下安装的流程和遇到的问题

通过Vundle安装应该是最方便的了

在vimrc中加上

Plugin 'valloric/youcompleteme'

保存后,执行

:source ~/_vimrc
:VundleInstall

来安装YCM在Vim部分的插件

接着开始配置环境

首先是Vim

Vim 7.4.1578 with Python 2 or Python 3 support
确保使用不低于7.4的带有python支持的vim版本
确保vim为utf8编码,确保在vimrc中有相关设置:

set encoding=utf-8

下一个,Python。Python2 或 Python3均可

x86还是x86-64看清楚
注意所用版本要与系统一致

安装CMake

安装Visual Studio Community

以前用了很久的2013。后来发现开发很多东西都要求高于此版本的VS了
干脆装个2017

安装VisualStudio 2015或更高版本。免费的社区版就行
并确保已包含下列组件:(这里的选择是我几次编译失败试出来的,不确保没有冗余)
Image.png

环境变量

需要注意的是,上文中提到组件中,无论是CMake还是python还是pip还是VS,确保其相关执行文件在系统的环境变量中
可以在命令行使用

echo %PATH%

检查一下

环境就绪,进入安装步骤

在cmd下进入ycm的目录。在我电脑上的路径如下:

cd %USERPROFILE%\.vim\bundle\youcompleteme\

执行官方推荐的方法:

python install.py --clang-completer

如果安装的VS不是2019版本,则会遇到以下错误:
Image2.png

可以通过参数(--msvc)更改所用VS版本
修改安装方法如下,2017为15,2015为14,依此类推

python install.py --clang-completer --msvc 15

等待打包编译和部分组件下载

这个步骤涉及下载,耗时可能会较久
中间也可能出现异常,并报出hash不一致的错误。这是由于网络状态不好或中断导致的
重来一遍即可

ycmd安装完成

完成后,重新打开Vim
有可能Vim里会直接提示YCMD server shutdown。YCM服务直接崩了
尝试查看错误log,发现对应的崩溃log是空的

经查发现
log空是因为ycmd在进入可记录log的状态之前就停掉了

通过手动启动ycmd的方法可以排查:

cd ~/.vim/bundle/YouCompleteMe/third_party/ycmd
cp ycmd/default_settings.json .
python ycmd --options_file default_settings.json

一般来说这一步会报python的错误,提示缺某个库。例如:

AttributeError: 'module' object has no attribute 'frozendict'

配置好pip,用pip安装对应的库。同时安装了python2和3的话要留意下对应的是哪个库
装好后再次尝试手动启动,很可能还会出现类似的错误,仍然是缺库
重复上述步骤直到执行后服务顺利启动(命令行状态下没有任何报错或者提示)
手动中止服务

根据YCM官网README的用法
将ycm目录\third_party\ycmd目录下的.ycm_extra_conf.py复制到对应的工程根目录

就绪

在vim中使用YcmRestartServer重启服务
若一切正常,vim会定位到刚才复制的.ycm_extra_conf.py,根据配置文件调整ycmd的启动
并出现如下提示:
Image3.png

OK即可

Unity中实现模拟移轴摄影的效果

移轴摄影,即移轴镜摄影(Tilt-shift photography),泛指利用移轴镜头创作的作品,所拍摄的照片效果就像是缩微模型一样,非常特别。移轴镜头的作用,本来主要是用来修正以普通广角镜拍照时所产生出的透视问题,但后来却被广泛利用来创作变化景深聚焦点位置的摄影作品。移轴镜摄影是将真实世界拍成像假的一样,使照片能够充分表现「人造都市」的感觉。

以上介绍摘自知乎

Unity自很早版本就内置了这一滤镜
在Standard assets中后期的包里,名为tilt shift的脚本就是

原图

Unity_2019-05-13_18-10-10.png

给相机加上Tilt Shift的脚本

Mode使用tilt而非iris
将max blur size调大,然后逐渐推高blur area
最好使用俯拍
适当调大相机fov
Unity_2019-05-13_18-10-39.png

效果

Unity_2019-05-13_18-10-45.png

Unity MaterialDrawer 总结

转自:https://cmwdexint.com/2017/05/06/materialpropertydrawer-in-shader-gui-without-creating-shadergui/

MaterialDrawer可将自定义的材质球参数通过面板界面的形式暴露出来,方便使用。
Shaderlab提供了很多内置的drawer,可以覆盖常见的几种使用情况
如果仍不满足,也可以通过实现MaterialPropertyDrawer类来自己定义和扩展

更详细的介绍请移步 Unity官方文档相关页面

下图包含常用drawer的面板样式

16999105_467532653370479_4085466863356780898_n.jpg

对应上图的代码

_MainTex("Texture", 2D) = "white" {}
 
[HideInInspector] _MainTex2("Hide Texture", 2D) = "white" {}
 
[NoScaleOffset] _MainTex3("No Scale/Offset Texture", 2D) = "white" {}
 
[PerRendererData] _MainTex4("PerRenderer Texture", 2D) = "white" {}
 
[Normal] _MainTex5("Normal Texture", 2D) = "white" {}
 
_Color("Color", Color) = (1,0,0,1)
 
[HDR] _HDRColor("HDR Color", Color) = (1,0,0,1)
 
_Vector("Vector", Vector) = (0,0,0,0)
 
//Can't go below zero
[Gamma] _GVector("Gamma Vector", Vector) = (0,0,0,0)
 
// Header creates a header text before the shader property.
[Header(A group of things)]
 
// Will set "_INVERT_ON" shader keyword when set
[Toggle] _Invert("Auto keyword toggle", Float) = 0
 
// Will set "ENABLE_FANCY" shader keyword when set.
[Toggle(ENABLE_FANCY)] _Fancy("Keyword toggle", Float) = 0
 
// Will show when ENABLE_FANCY is true //Feature request
//[ShowIf(ENABLE_FANCY)] _ShowIf("Show If", Float) = 0
 
// Blend mode values
[Enum(UnityEngine.Rendering.BlendMode)] _Blend("Blend mode Enum", Float) = 1
 
// A subset of blend mode values, just "One" (value 1) and "SrcAlpha" (value 5).
[Enum(One,1,SrcAlpha,5)] _Blend2("Blend mode subset", Float) = 1
 
// Each option will set _OVERLAY_NONE, _OVERLAY_ADD, _OVERLAY_MULTIPLY shader keywords.
[KeywordEnum(None, Add, Multiply)] _Overlay("Keyword Enum", Float) = 0
// ...later on in CGPROGRAM code:
//#pragma multi_compile _OVERLAY_NONE, _OVERLAY_ADD, _OVERLAY_MULTIPLY
// ...
 
// A slider with 3.0 response curve
[PowerSlider(3.0)] _Shininess("Power Slider", Range(0.01, 1)) = 0.08
 
// An integer slider for specified range (0 to 255)
[IntRange] _Alpha("Int Range", Range(0, 255)) = 100
 
// Default small amount of space.
[Space] _Prop1("Small amount of space", Float) = 0
 
// Large amount of space.
[Space(50)] _Prop2("Large amount of space", Float) = 0

Delauney Triangulator的学习和尝试实现,以及一些杂感

之前做了一些从osm数据里提取内容,过程生成建筑的demo。发现在给房子封顶的时候需要通过给定的无顺序顶点来生成一系列不那么咧姑的三角面,无从下手,于是开始研究。

经查发现叫Delauney Triangulator,似乎是代数拓扑学和计算机图形学的领域,作为文科生毫无认知

网上搜到各种博客对此课题的讲解,伪代码。尝试实现,无果,毫无头绪。
最后还是照着Bowyer-Watson算法的概念说明,自己磕磕绊绊瞎琢磨着完成了实现(尽管代码粗糙效率低下)
同时感受到中文技术圈对初学起步者的无奈和不友好:

  • 瞎比转帖的
  • 瞎比转还没转全的
  • 自顾自贴代码啥也不说的
  • 故意遗漏关键步骤的
  • 贴错了不纠正的
  • 不说人话的
  • 等等...

我能理解个人博客是一个比较放飞的地方。但哪怕是作为树洞或记事本来用,基本的原因,思考过程,注解难道不应该用正常人类能看懂的思维完整地整理好么?难道真的有这么多人只是为了凑字数篇数而贴来贴去,毫不理会博客存在的本质?

贴下实现,做个备忘