您的位置:首页 > 移动开发 > Unity3D

Unity2017 中新加入的 CustomRenderTexture类用户手册翻译

2017-09-25 15:43 477 查看
由于最近研究一些使用熔岩等粘稠流体模拟技术,需要计算生成一张中间纹理,并用相应的shader实时更新中间纹理中的信息,以实现流体模拟。使用GLSL可以实现,在UnityShader中的实现需要依赖Unity2017新加入的CustomRenderTexture类,来自定义中间纹理,保存需要的信息。这样使用UnityShader同样可以方便的将一些中间信息保存到纹理中,实现更加丰富的模拟效果。

下面现根据官方手册介绍一下新CustomRenderTexture类。边看便翻译的,水平有限,各位凑合着看
https://docs.unity3d.com/2017.2/Documentation/Manual/CustomRenderTextures.html
一、CustomRenderTexture类

CustomRenderTexture是继承自Unity之前版本中的RenderTexture类。RenderTexture的使用需要结合相机,将这个相机所看到的图像渲染到RenderTarget中,这个RenderTarget就是一张RenderTexture类的纹理,这一技术常用语模拟镜面效果(具体应用参考《UnityShader入门精要》一书)。CustomRenderTexture类是对RenderTexture类的一个扩充。我们可以使用Shader来实时地更新纹理,将我们需要的信息保存在纹理中,以方便使用。这一技术可以用来进行很多复杂的模拟,比如:腐蚀、水面产生的涟漪、刚体表面的粘稠流体(血液、熔岩)等等。我们还可以通过脚本,来配置更新纹理使用的Shader的通道、更新区域、以及更新频率等等,来实现许多逼真的模拟效果。

CustomRenderTexture的属性面板展示了RenderTexture已有的许多属性,同时也加入了一些新的独特的属性:

Render Texture:

Property:
Function:
Dimension
Render Texture的维度类型
     2D
2D的Render Texture
     Cube
CubeMap的Render Texture
     3D
3D的Render Texture
Size
纹理分辨率大小
Color Format
Render Texture的数据格式及类型
sRGB (Color Render Texture)
是否开启sRGB转换
[b]Enable Mip Maps
是否开启MipMaps(多级纹理映射)
Auto generate Mip Maps
是否自动生成MipMaps(多级纹理)
Wrap Mode
纹理映射方式
     Repeat
重复平铺
     Clamp
拉伸
Filter Mode
平滑处理模式
     Point
单像素
     Bilinear
双线性
     Trilinear
三线性
Aniso Level
各向异性等级(越高消耗性能越大)
Custom Texture:
Custom Texture自己独有的属性可以分为三类:

Material: 指定了更新这个纹理所使用的shader.

Initialization: 指定初始化时使用的纹理

Update:用来控制Shader如何更新这张纹理.

Property:
Function:
Material
Material used to update the Custom Render Texture
     Shader Pass
更新所调用的Pass
Initialization Mode
纹理初始化模式
     OnLoad
被创建时初始化
     Realtime
每一帧都初始化一次
     OnDemand
脚本中控制,调用时才初始化.
Source
纹理初始化使用的资源
 Texture and Color
初始化纹理的像素值与Color值相乘得到最终纹理颜色
     Initialization Color
Color值
     Initialization Texture
初始化纹理
Material
使用一个material来初始化纹理
     Initialization Material
初始化纹理使用的材质
Update Mode
更新模式
     OnLoad
创建时更新
     Realtime
每帧更新
     OnDemand
通过脚本控制更新
Period
(RealTime模式下可用) 多少秒更新一次 (0.0表示每帧更新)
Double Buffered
是否开启(Double Buffered)双重缓存技术,交替使用。这允许我们使用上一帧渲染纹理中的信息来进行模拟
Wrap Update Zones
更新区域是否可以包含边界
Cubemap Faces
(Cubemap类纹理可用)一些分别控制更新六个面的开关
Update Zone Space
自定义纹理的更新区域(可以通过脚本控制)
     Normalized
归一化后坐标在(0,1)范围内,左上角是纹理的原点
     Pixel
使用像素位置作为坐标,左上角是原点
Update Zone List
更新区域列表(可以通过脚本控制)
Custom Render Texture可以使用Export菜单导出为png格式的或者EXR格式的文件

UpdateZones
默认情况下CustomRenderTexture整体更新,但可以通过设置或者脚本控制选择更新区域列表,而实现纹理的部分更新,这一点对于实现雨滴涟漪的模拟十分有效,比如用UpdateZones来定义雨滴坠落点,在使用一个全局整体更新的pass来实现涟漪(官方给出的示例中正是这样做的)。这同样可以作为一种优化技术使用,比如当你确信并不需要更新整张纹理的全部像素时,只需要指定更新区域即可。

在属性面板上可以对UpDateZones进行配置:

Property:
Function:
Center
updateZone的中心
Size
update zone.的大小
Rotation
旋转度数(3D类型的纹理不可用)
Shader Pass
使用的Shader中的Pass。默认情况下使用上面主面板上的Pass配置
Swap (Double Buffer)
(只在 Double Buffered模式下可用)如果勾选的话,缓存Buffer将在这个UpdateZone执行之前交换
Double Buffered Custom Textures

双重缓存技术

CustomRenderTexture可以使用双重缓存技术,在内部实现上,实际上存在两张纹理,但从开发者的家排毒看他们是一样的。在每一次更新之后,他们的位置将被交换,这样我们可以在更新CustomRenderTexture时使用上一次的结果,这在许多模拟渲染中经常用到。我们可以读取使用上一次已经写入纹理缓存的数据,但我们不能用传统的混合模式来更新其中的值。
性能警告:由于这一技术在内存中实际还拥有一份该纹理的拷贝,在交换时也会影响一定的性能,同时纹理的分辨率大小,交换的频率都可能导致使用双重缓存技术造成性能上的下降。

将CustomRenderTexture连起来

CustomRenderTexture需要使用一个材质(一份Shader实例)来进行更新,这个材质同样可以使用一张纹理作为输入(比如法线纹理,高度纹理等等),这张纹理同样可以是CustomRenderTexture。也就是说我们可以使用一张CustomRenderTexture作为射程或者更新另一张CustomRenderTexture的输入,这样我们就可以使用一个CustomRenderTexture链来完成一些复杂的多步模拟,Unity引擎将会为我们管理好这些纹理更新的先后顺序。

给Custom Render Texture写一个更新Shader
更新CustomRenderTexture的Shader和我们在RenderTexture中使用的2D处理类似,并没有什么特别的不同,官方手册为我们提供了简单的例子:
Shader "CustomRenderTexture/Simple"
{

Properties

{

_Color ("Color", Color) = (1,1,1,1)

_Tex("InputTex", 2D) = "white" {}

}

SubShader

{ Lighting Off Blend One Zero

Pass

{

CGPROGRAM

#include "UnityCustomRenderTexture.cginc"

#pragma vertex CustomRenderTextureVertexShader

#pragma fragment frag

#pragma target 3.0

float4 _Color;

sampler2D _Tex;

float4 frag(v2f_customrendertexture
IN) : COLOR

{

return _Color * tex2D(_Tex, IN.localTexcoord.xy);

}

ENDCG

}

}
}
上面的例子中必须的步骤是:
1、 #include “UnityCustomRenderTexture.cginc”
2、使用内置的顶点着色器函数:CustomRenderTextureVertexShader
3、使用内置的是结构体作为片元着色器的输入: v2f_customrendertexture
除此之外,我们可以自由的编写我们需要的像素着色器函数

下面的例子为我们提供了一个简单的初始化CustomRenderTexture的Shader:
Shader "CustomRenderTexture/CustomTextureInit"
{

Properties

{ _Color ("Color", Color) = (1,1,1,1)

_Tex("InputTex", 2D) = "white" {}

}

SubShader

{ Lighting Off Blend One Zero

Pass

{

CGPROGRAM

#include "UnityCustomRenderTexture.cginc"

#pragma vertex InitCustomRenderTextureVertexShader

#pragma fragment frag

#pragma target 3.0

float4 _Color;

sampler2D _Tex;

float4 frag(v2f_init_customrendertexture IN) : COLOR

{ _Color * tex2D(_Tex, IN.texcoord.xy); }

ENDCG }

}
}
与更新Shader一样,下面三个地方是我们必须做的:
1、包含 “UnityCustomRenderTexture.cginc”文件
2、使用内置顶点着色器函数:InitCustomRenderTextureVertexShader
3、使用内置的片元着色器输入结构:v2f_init_customrendertexture

下面是我们为了方便开发者提供的内置数据结构和相关函数,以及他们的说明
v2f_customrendertexture结构体:

Name
Type
Value
localTexcoord
float3
当前正在处理的UpdateZone的纹理坐标
globalTexcoord
float3
Custom Render Texture纹理坐标
primitiveID
uint
当前正在处理的update zone 的ID索引
direction
float3
对Cube Custom Render Texture,表示像素在CubeTexture中的方向
v2f_init_customrendertexture 结构体:

Name
Type
Value
texcoord
float3
Custom Render Texture纹理坐标
全局变量:

Name
Type
Value
_CustomRenderTextureWidth
float
纹理宽度(像素)
_CustomRenderTextureHeight
float
纹理高度(像素)
_CustomRenderTextureDepth
float
纹理深度 (只是对 3D纹理有效,其他情况下为1).
_CustomRenderTextureCubeFace
float
只对 Cubemaps有效,返回正在处理的纹理面的ID (-X, +X, -Y, +Y, -Z, +Z).
_CustomRenderTexture3DSlice
float
只对3D纹理有效: 返回正在处理的3D Slice
_SelfTexture2D
Sampler2D
双重缓存技术有效: 返回最近交换前上一次更新的纹理结果
_SelfTextureCube
SamplerCUBE
同上
_SelfTexture3D
Sampler3D
同上
我们可以通过C#脚本来对CustomRenderTexture进行控制
上面属性面板中的多种设置都可以通过脚本来进行控制。有一件事要始终注意的就是:任何根据当前CustomRenderTexture当前状态对CustomRenderTexture的更新请求都是发生在这一帧的开始时,这可以保证所有使用这个纹理作为输入的材质都能获取最新的结果。例如:
customRenderTexture.updateZones = updateZones1;customRenderTexture.Update();customRenderTexture.updateZones = updateZones2;customRenderTexture.Update();
这样的代码将不会向我们书写逻辑一样先对updateZones1更新,在对updateZones2更新,而是对updateZones2调用两次Update()。
这样的规则的好处在于:确保了脚本中任何对CustomRenderTexture的属性配置的改变只会在下一帧的更新时起作用。

翻译水平有限,边看便翻译,大家凑合着看。之后分享官方发布的使用CustomRenderTexture的示例程序WaterSimulation分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息