UnityShader官方案例讲解——SurfaceShader(3)
来源:互联网 发布:知乎live怎么免费听 编辑:程序博客网 时间:2024/06/10 16:29
“Focus on where you’re going and you’ll know what steps to take. Focus on the steps you’re taking and you won’t know where you’re going.”
– Simon Sinek, Inspirational Speaker
step1
接下来实现的是将细节纹理显示在游戏对象上
Shader"Example / AutisticPatient SurfaceShader5"{ Properties { _MainTex("MainTex",2D) = "white"{} _Bump("Bump",2D) = "Bump"{} _Detail("Detail",2D) = "gray"{} } SubShader { //子着色器标签,表示这个子着色器渲染非透明物体 Tags{"RenderType" = "Opaque"} CGPROGRAM //定义表面着色器,并指定光照模型Lambert #pragma surface surf Lambert //真的 这些没什么可说的 简单带过吧 //输入结构体,存放各个纹理的uv坐标值 struct Input { float2 uv_MainTex; float2 uv_Bump; float2 uv_Detail; }; sampler2D _MainTex; sampler2D _Bump; sampler2D _Detail; void surf(Input IN,inout SurfaceOutput o) { //着色器会找到贴图上对应的UV坐标点,直接使用这个点的颜色信息rgb来进行着色. o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb; //很上边同理,只不过这行处理的是细节纹理,将颜色值扩大了2倍,大家可以试试扩大4倍的效果 o.Albedo *= tex2D(_Detail,IN.uv_Detail).rgb * 2; //unpcakNormal是接受fixed4类型的变量,然后转化为三维法线向量(fixed3)再赋值给标准输出结构体的Normal o.Normal = UnpackNormal(tex2D(_Bump,IN.uv_Bump)); } ENDCG }}
接下来上效果图进行对比,图片来自网络
step2
屏幕空间中的细节纹理 (Detail Texture)
其实主要就是讲内置变量screenPos的作用
Shader "Example / AutisticPatient SurfaceShader6" { Properties { //跟上面相比只是去掉了法线贴图 _MainTex ("Texture", 2D) = "white" {} _Detail ("Detail", 2D) = "gray" {} } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { float2 uv_MainTex; //关于screenPos:screenPos是一个三维点,但是用齐次坐标的形式表示出来就是(x,y,z,w) //根据齐次坐标的性质。(x,y,z,w)的齐次坐标对应三维点(x/w,y/w,z/w). //因此把w值除掉可以看来是一种Normalize的作法,这样就取出了实际的屏幕xy的UV值. //这个说法是网上的一个前辈解释的,更加接近原理 //如果大家感觉难理解的话,就把它当成“屏幕坐标”后面随着用法的深入,大家会有自己的理解的. float4 screenPos; }; sampler2D _MainTex; sampler2D _Detail; void surf (Input IN, inout SurfaceOutput o) { //着色器会找到贴图上对应的UV坐标点,直接使用这个点的颜色信息rgb来进行着色. o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; //ok这里所做的就是刚才上面所说的了 //取出屏幕xy的UV值,怎么取呢? //就是将xy坐标除以w. float2 screenUV = IN.screenPos.xy / IN.screenPos.w; //对screenUV进行倍增 //x轴扩大8倍,y轴扩大6倍 screenUV *= float2(8,6); o.Albedo *= tex2D (_Detail, screenUV).rgb * 2; } ENDCG } Fallback "Diffuse" }
效果图大家可以自己找模型搞搞,我找的模型实在是看不出太大的区别,就不上图了
step3
立方体贴图反射
这里使用了一个新的内置变量,
worldRefl:世界空间的反射向量,使用它可以方便的对CubeMap进行采样
Cube : Cube map texture(立方体纹理),简单说就是6张有联系的2D贴图的组合,主要用来做反射效果(比如天空盒和动态反射),也会被转换为对应点的采样.不理解?上代码就理解了,在properties里它的作用跟2D一样的
Shader"Example / AutisticPatient SurfaceShader7" { Properties { _MainTex ("Texture", 2D) = "white" {} //这里官方加入了法线贴图的影响,加入法线贴图印象所必须的代码都将用//NM 注释 //为什么要用法线贴图?如果希望模拟一个被雪花覆盖的物体,或者是一个凹凸不平的反射面 //我们是可以通过其他方式模拟出来的,但是这么做的话,占用的资源就大了很多,游戏的帧数就会受到影响 //现在我们可以用法线贴图来“假装”这种效果 _Bump("Bump",2D) = "Bump"{} //立方体贴图,和2D纹理贴图在代码中的操作相似,但是功能不一样 _Cube ("Cubemap", CUBE) = "" {} } SubShader { Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input { //NM unity的内置结构(struct),它的作用是获取修改后的法线信息 //换句话说:有了它我们可以访问经过法线贴图修改后的平面的法线信息 INTERNAL_DATA; float2 uv_MainTex; //NM float2 uv_Bump; float3 worldRefl; }; //NM sampler2D _Bump; sampler2D _MainTex; //这里生命同名变量进行关联 samplerCUBE _Cube; //不需要法线贴图版的surf void surf (Input IN, inout SurfaceOutput o) { //对纹理采样,将UV坐标点的颜色值 * 0.5 后赋值给输出结构体的颜色属性 o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * 0.5; //这里是对立方体贴图进行纹理采样,可对照上一行代码理解 //texCUBE是对立方体贴图(CubeMap)进行采样的函数, //参数1(CubeMap参数2(采样点) //然后对输出结构的Emission进行填充,输出 o.Emission = texCUBE (_Cube, IN.worldRefl).rgb; } //NM 需要法线贴图版的surf void surf(Input IN, inout SurfaceOutput o) { o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * 0.5; //我们想要使用逐像素的法线贴图来修改反射贴图 //为了这个目的,需要得带物体的平面法线信息 o.Normal = UnpackNormal(tex2D(_Bump,IN.uv_Bump)); //这里面的WorldReflectionVertor函数是新接触的 //它的作用:获得在使用法线贴图的情况下,逐像素的获取世界空间的反射向量,这个解释比较模糊 //其实在执行完上一行代码后,物体的平面法线已经被修改了,然后我们就可以就它来影响反射。 //在结构体中已经声明了INTERVAL_DATA来访问修改后的法线信息. //然后使用WorldReflectionVertor函数去查找CubMap中对应的反射信息(反射向量). o.Emission = texCUBE(_Cube,WorldReflectionVertor(IN,o.Normal)).rgb; } ENDCG } Fallback "Diffuse" }
*吐槽*
一大篇的大白话和病句搞得我看着有点尴尬了
以后的解释中太基础的东西就偏术语化了
非常影响代码的美感呀/(ㄒoㄒ)/~~
0 0
- UnityShader官方案例讲解——SurfaceShader(3)
- UnityShader官方案例讲解——SurfaceShader(1)
- UnityShader官方案例讲解——SurfaceShader(2)
- UnityShader官方案例讲解——SurfaceShader(4)
- unityshader之surfaceshader
- UnityShader案例(一)——漫反射
- UnityShader案例(二)——Phong高光反射
- UnityShader案例(三)——BlinnPhong高光反射
- UnityShader案例(四)——单张纹理
- UnityShader案例(五)——法线纹理
- UnityShader案例(六)——渐变纹理
- UnityShader案例(七)——遮罩纹理
- UnityShader案例(八)——透明效果(1)
- UnityShader案例(九)——透明效果(2)
- UnityShader官方案例之表面着色器光照示例
- UnityShader官方案例之编写顶点和片段着色器
- UnityShader——Wireframe
- SurfaceShader
- oibh2006 容易的网络游戏(离散)
- Python 数据处理的 Some tips --- 索引
- ActiveBpel部署运行BPEL流程实例
- Selenium配合chromedriver提示“Message: 'chromedriver' executable needs to be in PATH.Please see ...”
- 约瑟夫环
- UnityShader官方案例讲解——SurfaceShader(3)
- 关键字 extern
- docker pull 下来的镜像文件存放的位置
- 控制公司(dfs)
- Hibernate中Session.load/get方法
- 总结的前端入门方法
- eclipse 当中,小白们所不知道的 CRTL+1 快捷键
- JSP文件和Servlet在文件目录以及服务器中配置的不同
- 自定义ViewGroup-自定义LayoutParams支持显示方位