Unity 渲染教程(03):使用多张纹理贴图

更新时间:2023-06-12 01:21:47 阅读: 评论:0

Unity 渲染教程(三):使用多张纹理贴图
 译者: 张乾光(星际迷航)    审校:崔国军(飞扬971)
对多张纹理贴图进行采样。
使用细节纹理贴图。
在线性空间中处理颜色
使用splat贴图。
这是关于渲染基础的系列教程的第三部分。前面两个部分介绍了着色器和纹理。我们已经看到了如何使用单个纹理来让平坦表面看起来更复杂。现在我们继续向前进,试下同时使用多个纹理。
这个系列教程是使用Unity 5.4.0开发的,这个版本目前还是开放测试版本。我使用的是build5.4.0b10版本
 
同时使用多个纹理。
细节贴图
纹理对于渲染的效果是很好的,但是纹理也有自己的局限性。纹理的像素数目是固定数量的,无论它们显示出来的尺寸是什么。如果它们被渲染得很小的时候,我们可以使用mipmap来尽量让纹理看起来还不错。但是当纹理被渲染得很大的时候,它们会变得模糊。我们不能无条件地提供额外的细节,所以没有办法处理放大的问题。或者是否有其他办法可以处理纹理被放大的问题?
当然,我们肯定可以使用更大的纹理。而更多的纹理的像素意味着更多的细节。但是纹理的大小有限制。而且存储大量额外的数据是很浪费的,这些数据只能在用户很靠近的时候才会注意到。
增加纹理的像素密度的另一种方法是平铺纹理。然后你可以得到你所期望的一个很小的纹理,但你会明显得到一个重复的模式。虽然这可能在很靠近看的时候不是很明显。毕竟,当你站在你的鼻子就能触到一堵墙的位置的时候,你只会看到整个墙一个非常小的一部分。
因此,我们应该能够通过将一个没有进行平铺操作的纹理与一个进行了平铺操作的纹理组合来添加细节。为了尝试这个组合效果,让我们使用具有明显重复模式的纹理。这是一个方格网格。下载得到它,并把它放到你的项目中去,使用默认的导入设置。我稍微了扰乱了下网格线,使它更加的有趣,也能感知到它处于平铺模式。
网格线稍微扭曲下的纹理贴图。感恩教育作文
复制My First Shader里面的代码到新的文件里面并将它命名为TexturedWith Detail。从现在开始,我们将使用这个新的着色器。
1
2
3
4
5
6
7
8
9
10
11
Shader "Custom/Textured With Detail" {
 
    Properties {
        _Tint ("Tint", Color) = (1, 1, 1, 1)
        _MainTex ("Texture", 2D) = "white" {}
    }
 
    SubShader {
       
    }
}
使用这个着色器创建一个新的材质,然后为这个材质分配网格贴图。
带有网格的详细材质。
将材质分配给一个四边形并看下效果。从远处看的话,它的效果会看起来很好。但是如果
离得太近的话,它会变得模糊和含糊不清。除了缺乏细节以外,由纹理压缩引起的瑕疵也将变得愈发明显。
网格的特写,显示了纹理像素过低和DXT1这种压缩方式引起的瑕疵。
多个纹理的采样
现在我们采用的是单个纹理的采样,并使用单个纹理的采样作为我们的片段着色器的结果。
因为我们要改变这种方法,所以将采样的颜色存储在一个临时变量中是很方便的。
兰溪地下长河于的用法
1
2
3
4
float4 MyFragmentProgram (Interpolators i) : SV_TARGET {
    float4 color = tex2D(_MainTex, i.uv) * _Tint;
    return 关于友谊的诗color;
}
我们推测我们可以通过引入平铺纹理来增加纹理像素的密度。让我们简单地执行对第二个纹理的采样,这个纹理采样的密度是原始纹理采样的密度的10倍。 第二个纹理实际上替换原来的颜色,只是还有添加它。
1
2
孟格布禄3
float4 color = tex2D(_MainTex, i.uv) * _Tint;
color = tex2D(_MainTex, i.uv * 10);
return color;
这产生了更小的网格。你可以在它开始看起来效果不好之前能够离得更近进行观察。当然,因为网格是不规则的,它很显然在不停的重复。
硬编码进行的平铺。
需要的注意是,在现在进行处理的时候,我们执行的是两个纹理采样,但最终只使用了其中一个采样的结果。这似乎是一种浪费。是吗?看下编译后的顶点程序。就像在前面的教程所做的中一样,我将包括OpenGLCore平台和Direct3D 11平台上的相关编译代码。
1
2
3
4
5
6
7
8
9
10
uniform  sampler2D _MainTex;
in  vec2 vs_TEXCOORD0;
layout(location = 0) out vec4 SV_TARGET0;
vec2 t0;
void main()
{
    t0.xy = * vec2(10.0, 10.0);
    SV_TARGET0 = texture(_MainTex, t0.xy);
    return;
}
1
2
3
4
5
6
7
8
9
10
SetTexture 0 [_MainTex] 2D 0
      ps_4_0
      dcl_sampler s0, mode_default
      dcl_resource_texture2d (float,float,float,float) t0
      dcl_input_ps
      dcl_w
      dcl_temps 1
   0: , v0.xyxx, l(10.000000, 10.000000, 0.000000, 0.000000)
   1: w, r0.xyxx, t0.xyzw, s0
   2: ret
你注意到编译后代码中只有一个纹理采样么?没错,编译器删除了不必要的代码!基本上,它的工作方式是从最终结果往回推所需要的东西,并丢弃任何在最终结果中未使用的东西。
当然,我们不想替换原始的纹理采样。我们想结合这两个纹理采样。让我们试验下将它们相乘在一起。但是,我们再一次给纹理贴图添加一点扭曲。对纹理采样两次,并使用完全相同的UV坐标。
1
2
3
float4 color = tex2D(_MainTex, i.uv) * _Tint;
color *= tex2D(_MainTex, i.uv);
return color;
着色器的编译器到底做了什么?
1
2
3
4客服职责
5
6
7
8
9
10
11
12
uniform  sampler2D _MainTex;
in  vec2 vs_TEXCOORD0;
layout(location = 0) out vec4 SV_TARGET0;
mediump vec4 t16_0;
lowp vec4 t10_0;
void main()
{
    t10_0 = texture(_MainTex, );
    t16_0 = t10_0 * t10_0;
    SV_TARGET0 = t16_0 * _Tint;
    return;
}
1
2
3
4
5
我的人生故事
6
7
8
9
10
11
12
13
14
15
SetTexture 0 [_MainTex] 2D 0
ConstBuffer "$Globals" 144
Vector 96 [_Tint]
BindCB  "$Globals" 0
      ps_4_0
      dcl_constantbuffer cb0[7], immediateIndexed
      dcl_sampler s0, mode_default
      君子之约dcl_resource_texture2d (float,float,float,float) t0
      dcl_input_ps
      dcl_w
      dcl_temps 1
   0: w, v0.xyxx, t0.xyzw, s0
   1: w, r0.xyzw, r0.xyzw
   2: w, r0.xyzw, cb0[6].xyzw
   3: ret
再次,我们最终得到了一个单一的纹理采样。着色器的编译器检测到重复代码并对其进行了优化。所以纹理贴图只采样一次。纹理采样的结果存储在寄存器中并重复使用。着色器的编译器足够聪明,可以检测出这样的代码重复,即使你使用了中间变量也是如此。着色器的编译器将一切都追溯到提供给编译器的原始输入。然后它尽可能有效地重组所有的一切
现在把第二个纹理贴图乘以10以后 UV坐标进行打包。我们终于看到大的和小的网格的结合。
1
color *= tex2D(_MainTex, i.uv * 10);

本文发布于:2023-06-12 01:21:47,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1034498.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:纹理   使用   采样   贴图   进行   平铺   着色器   代码
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图