Unity3D Rendering复习之瞎几把写(二),纹理贴图的混合

复习第三章:(学习请看下面的文章链接)

原文:https://catlikecoding.com/unity/tutorials/rendering/part-3/

译文:http://gad.qq.com/program/translateview/7173931

第三章使用多张纹理贴图

1.   对多张纹理贴图进行采样。

2.   使用细节纹理贴图。

3.   在线性空间中处理颜色

4.   使用splat贴图。

 

多个纹理的采样

float4 MyFragmentProgram (Interpolators i) : SV_TARGET {

float4 color = tex2D(_MainTex, i.uv)* _Tint;

color = tex2D(_MainTex,i.uv * 10);

    returncolor;

}

 

以上的代码color被赋值了两次,编译器会自动去掉第一行无用的代码

color *=tex2D(_MainTex, i.uv * 10);

两个纹理贴图结果通过相乘,进行混合

单独的细节纹理贴图

两个纹理贴图相乘在一起的时候,结果将变得更暗。除非至少有一个纹理是白色的。纹理像素的每个颜色通道的值介于0和1之间。当向纹理添加细节贴图的时候,你可能需要进行变暗处理,也可以进行增亮处理。

例如:color *= tex2D(_MainTex, i.uv * 10) * 2;

或者使用另一张细节纹理贴图,在顶点数据结构增加一对UV

 float2 uvDetail : TEXCOORD1;

顶点UV坐标值介于0和1之间,需要在顶点着色器中变换到贴图坐标系,输入到片段着色器中。

Unity3D Rendering复习之瞎几把写(二),纹理贴图的混合

贴图的细节从这张贴图上采样,这样就可以可以单独编辑

float4 MyFragmentProgram(Interpolators i) : SV_TARGET {

    float4color = tex2D(_MainTex, i.uv) * _Tint;

    color *=tex2D(_DetailTex, i.uvDetail) * 2;

    return color;

}

 

让细节纹理贴图淡出

添加细节纹理贴图原因:可以在离得很近或者纹理被放大的时候改善材质的外观表现

通过使用Fadeout Mip贴图,可以使得远处的纹理淡出

Unity3D Rendering复习之瞎几把写(二),纹理贴图的混合

 Unity3D Rendering复习之瞎几把写(二),纹理贴图的混合

 

线性颜色空间

两种颜色空间,线性空间(斜率1),伽马空间

参考文章https://blog.csdn.net/bill2ccssddnn/article/details/53423410

 

最广泛使用的图像颜色格式是sRGB:存储颜色 = 原始颜色  ^ 1 /2.2

要将sRGB图像颜色格式中的数据转换回其原始颜色,请应用2.2的伽玛校正。

       Unity3D Rendering复习之瞎几把写(二),纹理贴图的混合  Unity3D Rendering复习之瞎几把写(二),纹理贴图的混合

使用gamma 1 / 2.2进行编码和使用gamma 2.2进行解码。

在gama空间渲染时,直接访问sRGB中的原始颜色,

线性空间的颜色值的优点之一是它可以实现更加逼真的光照计算

将上述Gama空间中的计算转换到线性空间时,细节贴图会变暗,原因是,转换为线性颜色空间后,细节纹理采样值更小了,假设原本为 0.5, 转换后变成,

Unity定义了一个变量unity_ColorSpaceDouble

color *=tex2D(_DetailTex, i.uvDetail) * unity_ColorSpaceDouble;

这样可以保证无论哪个细节材质都是一样的。

 

 

TextureSplatting

Splatting纹理是一张只存储0 1 贴图,它可以只有一个通道,R,也可以是RGB分别存储。

通过这个技术,可以用Splatting纹理来规定哪些像素使用哪一张纹理,例如,在地形可以标记哪些位置是草地,哪些是泥土等。

Unity3D Rendering复习之瞎几把写(二),纹理贴图的混合

Unity3D Rendering复习之瞎几把写(二),纹理贴图的混合

要启用“Bypass sRGB Sampling”,保证采样结果为0或者1。

使用R通道

return

    tex2D(_Texture1, i.uv) * splat.r +

    tex2D(_Texture2, i.uv) * (1 - splat.r);

 

同时使用RGB通道

return

    tex2D(_Texture1, i.uv) * splat.r +

    tex2D(_Texture2, i.uv) * splat.g +

    tex2D(_Texture3, i.uv) * splat.b +

    tex2D(_Texture4, i.uv) * (1 - splat.r -splat.g - splat.b);