前言
小伙伴们是否有过这样的场景:看到一个精美的3D模型,很想知道它是如何被创作出来的?于是开始了一番搜索引擎查找之后,得知需要建模工具来完成,例如3D Max、Maya、Blender、Photoshop。那么本篇就使用这些工具来完成一个精美的3D模型吧!哈哈,当然不是,本篇不会介绍如何使用这些工具来建模,而是假设在拥有了模型和纹理之后,如何利用Shader来将一张纹理贴到模型上。
纹理采样
为了获取一张纹理图上的纹素,我们需要对纹理进行采样,而在Unity当中对纹理进行采样需要用到以下函数:
tex2D(纹理图,uv坐标)
uv坐标即纹理的映射坐标,其定义了模型的顶点在该纹理图中对应的2D坐标。uv坐标信息通常是在建模软件中通过展uv的方式将其存储在顶点坐标上的。
采样结果应用
使用tex2D(纹理图,uv坐标)函数得到的结果是一个颜色值,包含了r、g、b、a四个值。我们通常会将其应用到光照模型中的漫反射的颜色上,在之前的文章中,对光照模型中的漫反射和高光进行了介绍,这次在之前的基础上做修改即可。
//float3 diffuse = _LightColor0.rgb * _Diffuse.rgb * lambert;
fixed3 diffuse = _LightColor0.rgb * col * saturate(nDotl);
在Unity中的具体实现
- 1、在Project面板右键创建一个Unlit Shader,将其命名为TexureMap。
- 2、选中刚刚创建的Specular,右键创建一个Material。
- 3、在Hierarchy面板创建一个Sphere,并将第2步创建的Material拖拽赋值到Sphere上。
- 4、使用脚本IDE打开第一步创建的Shader,添加代码如下:
Shader "Unlit/TexureMap"
{Properties{ _MainTex("Texures",2D) = "white"{} _Specular("Specular",Color) = (1,1,1,1) _Gloss("Gloss",Range(1,100)) = 10}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "UnityLightingCommon.cginc"sampler2D _MainTex;float3 _Specular;float _Gloss;struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;};struct v2f{float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;float3 nDirWS : TEXCOORD1;float4 posWS : TEXCOORD2;};v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;o.nDirWS = UnityObjectToWorldNormal(v.normal);o.posWS = mul(unity_ObjectToWorld,v.vertex);return o;}fixed4 frag (v2f i) : SV_Target{float3 lDirWS = _WorldSpaceLightPos0.xyz;float3 vDirWS = normalize(_WorldSpaceCameraPos.xyz - i.posWS.xyz);float3 rDirWS = reflect(-lDirWS,i.nDirWS);float nDotl = dot(i.nDirWS,lDirWS);float vDotr = dot(vDirWS,rDirWS);//采样纹理fixed3 col = tex2D(_MainTex, i.uv).rgb;//光照模型fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 diffuse = _LightColor0.rgb * col * saturate(nDotl);fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(vDotr),_Gloss);fixed3 finalColor = ambient + diffuse + specular;return fixed4(finalColor,1.0);}ENDCG}}
}
- 5、回到Unity,选中material,将纹理图拖拽赋值到_MainTex。
- 6、查看最终效果。
最后
纹理映射的代码实现起来比较简单,不过其背后的工作其实并不简单,如果想要深入理解纹理映射背后的原理,可以翻看图形学相关书籍。OK,本篇就到这里。
最后
整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。
有需要的小伙伴,可以点击下方卡片领取,无偿分享