UnityShader入门精要学习笔记(七):基础纹理之单张纹理
来源:互联网 发布:weka java api文档 编辑:程序博客网 时间:2024/05/29 17:16
一 .基础纹理应用
纹理的最初目的就是使用一张图片来控制模型的外观。使用纹理映射技术,我们可以吧一张图“黏”在模型表面,逐纹素(texel)(名字是为了和逐像素进行区分)地控制模型的颜色。
结合之前的光照模型的单张纹理应用:
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'Shader "Custom/Edu/SingleTexture" { Properties { _MainTex("MainTex",2D)= "white"{} _Diffuse("Diffuse",Color) = (1,1,1,1) _Specular("Specular",Color) = (1,1,1,1) _Gloss("Gloss",Range(8,256)) = 40 _Color("ColorTint",Color) = (1,1,1,1) } SubShader { Pass { Tags{"LightMode" = "ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" sampler2D _MainTex; float4 _MainTex_ST; fixed4 _Diffuse; fixed4 _Specular; fixed4 _Color; float _Gloss; struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; float4 texcoord:TEXCOORD0; }; struct v2f { float4 pos:SV_POSITION; float3 worldNormal:TEXCOORD0; float3 worldPos:TEXCOORD1; float2 uv:TEXCOORD2; }; v2f vert(a2v v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); o.worldPos = mul(unity_ObjectToWorld,v.vertex); o.worldNormal = mul(v.normal,(float3x3)unity_WorldToObject); o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); return o; } fixed4 frag(v2f i):SV_Target { fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed3 albedo = tex2D(_MainTex,i.uv).rgb * _Color.rgb; fixed3 diffuse = _LightColor0.rgb * albedo * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir)); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * albedo; fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); fixed3 halfDir = normalize(viewDir + worldLightDir); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(worldNormal,halfDir)),_Gloss); return fixed4( diffuse + ambient + specular , 1.0); } ENDCG } } FallBack "Diffuse"}
TRASFORM_TEX实在UnityCG.cginc中定义的:
//Transform 2D UV by scale/bias property#define TRANSFORM_TEX(tex,name)(tex.xy * name##_ST.xy + name##_ST.zw)
它接受两个参数
第一个参数是顶点的纹理坐标
第二个参数是纹理的名称
看一下效果:
二.纹理采样区间设置
下面为了阐释纹理的属性,编写一个更为纯粹的纹理属性应用shader
Shader "Custom/Edu/SimpleTextureProperties" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} } SubShader { Pass { Tags{"LightMode" = "ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" sampler2D _MainTex; float4 _MainTex_ST; fixed4 _Color; struct a2v { float4 vertex:POSITION; float2 texcoord:TEXCOORD0; }; struct v2f { float4 pos:SV_POSITION; float2 uv:TEXCOORD0; }; v2f vert(a2v v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); return o; } fixed4 frag(v2f i):SV_Target { fixed3 color = tex2D(_MainTex,i.uv); return fixed4(color,1.0); } ENDCG } } FallBack "Diffuse"}
利用这个shader在场景中创建一个Quad。
此时我们对纹理使用的Wrap Mode的是Repeat——重复纹理采样。
这种模式下,如果纹理的坐标超过了1,那么整数部分将会被舍弃,而直接使用小数部分进行采用。
下面我们来看另外一种模式
当使用Clamp模式时,超过的部分将会截取到边界值,从而形成一个条形结构。
三.3种滤波模式
纹理导入面板中的下一个属性是FilterMode属性,它决定了当纹理由于变换而产生拉伸是将会使用哪种滤波模式。
Point模式使用了最近邻滤波,在放大或缩小时,它的采样像素数目通常只有一个,因此图像看起来有种像素风格的效果。
Bilinear滤波采用了线性滤波,对于每个目标像素,它会找4个邻近的像素,然后对他们进行线性插值混合后得到最终的像素,因此图像看起来像被模糊了。
Trilinear滤波几乎和Bilinear是一样的,知识Trilinear还会在多级渐远纹理(mipmapping)之间进行混合。
四.纹理的最大尺寸和纹理模式
【我只安装了安卓build的模块】
Unity允许我们为不同目标平选择不同的纹理尺寸和压缩格式。
如果导入的纹理超过了MaxTextureSize中的设置,那么Unity会把这个纹理所防伪这个最大分辨率。
导入的纹理的长宽大小应该是2的整数次幂。
如果使用了非2的整数次幂大小(Non Power of Two,NPOT)的纹理,那么这些纹理往往会占用更多的内存空间,而且GPU的读取该纹理的速度也会下降。甚至有一些平台不支持NPOY纹理。
对于一些不需要使用很高精度的纹理(例如漫反射颜色的纹理),我们应该尽量使用压缩格式!
- UnityShader入门精要学习笔记(七):基础纹理之单张纹理
- UnityShader入门精要学习笔记(九):基础纹理之渐变纹理与遮罩纹理
- UnityShader入门精要学习笔记(八):基础纹理之凹凸映射
- Unity Shader入门精要笔记(十一):基础单张纹理
- UnityShader入门精要学习笔记(十四):立方体纹理
- UnityShader入门精要学习笔记(十五):渲染纹理
- UnityShader入门精要学习笔记(十六):纹理动画
- UnityShader入门精要学习笔记(二十一):深度和法线纹理
- unityshader学习笔记之纹理渲染
- unity shader学习笔记(四)——Unity中的基础纹理之单张纹理
- UnityShader初级篇——单张纹理
- unity shader学习笔记(七)——Unity中的基础纹理之遮罩纹理
- UnityShader学习-纹理shader
- 【Unity Shader入门精要】— 基础纹理
- 《unity shader入门精要》学习笔记--渐变纹理与遮罩纹理
- UnityShader入门精要学习笔记(二):数学知识
- 单张纹理
- UnityShader之创建动态纹理
- jQuery—事件处理、动画
- 【HTML】兼容性代码片
- 什么是I/Q信号
- js刷新iframe方法
- Echarts图表
- UnityShader入门精要学习笔记(七):基础纹理之单张纹理
- centos7下redis主从复制安装
- LVS(Linux Virtual Server)
- 表达式中的陷阱
- OCR开源库(字幕区域定位和字幕识别):github
- 415. Add Strings 计算两个数字字符串的和
- UE4_网络项目01
- KD tree算法(1)-简介&构建KD tree
- redis列表类型list如何一次返回多个值并删除这些值