Unity双面渲染shader
更新时间:2023-05-14 15:18:01 阅读量: 实用文档 文档下载
Unity双面渲染shader
双面渲染shader
Unity内置的Shader,都是单面效果,想必导入Mesh的同学都碰到过这样的痛苦,布料飘起的背面部分看起来是空气,汽车透过车窗看到是路面...各种蛋疼。
有些文章教导大家把模型做出厚度来吧,这种做法实在太那个啥了......
其实用改写Shader的方法可以很方便的实现双面材质。
Unity里有3种Shader方式:
1.Fixed Function Shaders
2.Vertex and Fragment Shaders
3. Surface Shaders
关于这部分的详细介绍,请参考官方的教程。
这三种方式里,都可以通过直接在Shader代码头部添加一个Cull off 语句,实现强制双面渲染。
但是直接用Cull off的方式有个重大的缺陷,这材质从两面看无论贴图、颜色、反光、照明情况,都是一模一样的,这并不符合大多数实际情况的常识。
在第1和第2种Shader里,是可以通过在一个渲染子程序里用两个渲染Pass来实现双面不同效果的,这部分网上的资料也很多,写起来也很简单直接。
这里主要讨论的是第三种也是最常用的Surface Shader的双面不同效果的实现。
Surface Shader是不能写在Pass里的,所以要实现它的双面不同效果就要用其他变通的办法。
首先去Unity官方网站下载一个内置Shader的代码包,链接如下:
/download_unity/builtin_shaders.zip
打开后看见一堆.shader文件,可以用任何文本编辑器打开。可以看见系统内建的Shader基本都是Surface方式。
这里随便打开一个Normal-BumpSpec.Shader这是普通的高光-凹凸贴图材质
Unity双面渲染shader
复制代码
1.Shader "Bumped Specular" {
2.Properties {
3. _Color ("Main Color", Color) = (1,1,1,1)
4. _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
5. _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
6. _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
7. _BumpMap ("Normalmap", 2D) = "bump" {}
8.}
9.SubShader {
10. Tags { "RenderType"="Opaque" }
11. LOD 400
12.
13.CGPROGRAM
14.#pragma surface surf BlinnPhong
15.
16.
17.sampler2D _MainTex;
18.sampler2D _BumpMap;
19.fixed4 _Color;
20.half _Shininess;
21.
22.struct Input {
23. float2uv_MainTex;
Unity双面渲染shader
24. float2uv_BumpMap;
25.};
26.
27.void surf (Input IN, inoutSurfaceOutput o) {
28. fixed4tex = tex2D(_MainTex, IN.uv_MainTex);
29. o.Albedo = tex.rgb * _Color.rgb;
30. o.Gloss = tex.a;
31. o.Alpha = tex.a * _Color.a;
32. o.Specular = _Shininess;
33. o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
34.}
35.ENDCG
36.}
37.FallBack "Specular"
38.}
简单解说一下几个关键行:
第一行Shader "Bumped Specular" 指定了这个shader出现在Unity系统Shader菜单里的名字,如果要修改系统内建Shader的源代码,最好把这个名字改掉,否则和系统内建Shader重名啦。我是这样写的: Shader "Hog's shaders/BumpSpec_Twoside" ,这个shader会出现在Hog's shaders组里,系统会自动完成这个加载。
第二行Properties后面的一组以下划线开头的变量表示了这个渲染器需要设置的参数。对于一个高光-凹凸材质来说,需要材质颜色、反光颜色、反光率、材质贴图和法线贴图,这5个变量就对应这5个东西啦,详细请参考系统手册。
在第11行LOD 400 后面加上一行:Cull off,这个材质就会自动双面渲染了 Cull off表示双面都渲染,不写默认是Cull back,不渲染背面。你也可以写上Cull front,不渲染正面。
Unity双面渲染shader
改完这行,把第一行改成你希望的名字,把这个shader文件拷贝到工程的assets目录底下,系统就能自动加载啦。
效果如图:
双面是双面了,但是哪有两面是一样亮、一样高光区域的....,全透光的砖墙,这种双面很少会用到吧。
如何做到双面不同效果呢?
前面说了Surface shader是不能写两个pass渲染不同面的,但其实surface方式可以写多个渲染过程,根本不需要pass的概念,Surface Shader可以这样写:
Call back
渲染正面的代码
Call front
渲染反面的代码
就可以实现双面不同的控制了。
根据这个原理,其实我们只要把系统内建shader的源代码复制一份,就能实现另一面不同效果了。以下供参考:
复制代码
1.Shader "Hog's shaders/BumpSpec_Twoside" {
2.Properties {
3.//正面5个参数
4. _Color ("Main Color", Color) = (1,1,1,1)
5. _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
6. _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
Unity双面渲染shader
7. _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
8. _BumpMap ("Normalmap", 2D) = "bump" {}
9.//反面拷贝改名也是5个
10. _BackColor ("Back Main Color", Color) = (1,1,1,1)
11. _BackSpecColor ("Back Specular Color", Color) = (0.5, 0.5, 0.5, 1)
12. _BackShininess ("Back Shininess", Range (0.03, 1)) = 0.078125
13. _BackMainTex ("Back Base (RGB) Gloss (A)", 2D) = "white" {}
14. _BackBumpMap ("Back Normalmap", 2D) = "bump" {}
15.}
16.SubShader {
17.Tags { "RenderType"="Opaque" }
18. LOD 400
19. Cull back
20.//开始渲染正面
21.CGPROGRAM
22.//表明是surface渲染方式主渲染程序是surf 光照模型是BLinnPhong
23.#pragma surface surf BlinnPhong
24.
25.
26.sampler2D _MainTex;
27.sampler2D _BumpMap;
28.fixed4 _Color;
29.half _Shininess;
30.
Unity双面渲染shader
31.struct Input {
32. float2uv_MainTex;
33. float2uv_BumpMap;
34.};
35.
36.void surf (Input IN, inoutSurfaceOutput o) {
37. fixed4tex = tex2D(_MainTex, IN.uv_MainTex);
38. o.Albedo = tex.rgb * _Color.rgb;
39. o.Gloss = tex.a;
40. o.Alpha = tex.a * _Color.a;
41. o.Specular = _Shininess;
42. o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));}
43.ENDCG
44.
45.
46. Cull front
47.//开始渲染反面其实和就是拷贝了一份正面渲染的代码除了变量名要改
48.CGPROGRAM
49.#pragma surface surf BlinnPhong
50.
51.sampler2D _BackMainTex;
52.sampler2D _BackBumpMap;
53.fixed4 _BackColor;
54.half _BackShininess;
Unity双面渲染shader
55.
56.struct Input {
57. float2uv_BackMainTex;
58. float2uv_BackBumpMap;
59.};
60.
61.void surf (Input IN, inoutSurfaceOutput o) {
62. fixed4tex = tex2D(_BackMainTex, IN.uv_BackMainTex);
63. o.Albedo = tex.rgb * _BackColor.rgb;
64. o.Gloss = tex.a;
65. o.Alpha = tex.a * _BackColor.a;
66. o.Specular = _BackShininess;
67. o.Normal = UnpackNormal(tex2D(_BackBumpMap, IN.uv_BackBumpMap));}
68.ENDCG
69.}
70.FallBack "Specular"
71.}
这是个双面可以分别指定的高光-凹凸材质,注意几个要点:
properties部分只能出现一次,所以这是不能直接拷贝的。因为要为双面指定不同的参数,双面的参数变量名肯定不能一样,这个论坛里都是程序猿,没必要多解释了。我简单的把用于正面的5个参数前面都加上了一个Back用于反面。
在CG代码内部也要对应的应用相应的参数,反面的渲染代码就用刚才全部加了Back的那5个参数。
正面代码段用Cull back 开始反面的代码用Cull front开始
以下是渲染效果:
Unity双面渲染shader
一面是砖墙一面是木板。。蛋疼了没
这个模式下,双面也完全可以指定不同的材质,基本上你不用学习很多内建Shader和CG语法,通过简单的copy-paste就能组合出无穷的双面材质来了。
再提升一下,其实我们常用的双面效果,除了透明的材质以外,无非是两种:
一是反面和正面同样纹理,但是不需要高光、反射,只需要一个相对黯淡的被环境光照亮的材质,比如砖墙木盒衣服什么的
二是反面显示为单身或其他纹理,但也不需要高光、反射,只需要被环境光照亮,比如汽车内部建筑物内部等等。
第一种情况,反面可以沿用正面纹理,但是以普通的Diffuse方式着色
第二种情况,反面不指定或者单独指定纹理,也以普通的Diffuse方式着色
两种情况,反面的渲染都可以借用系统内建Shader的Diffuse渲染代码来实现,方式一的代码:
复制代码
1.Shader "Hog's shaders/BumpSpec_Twoside1" {
2.Properties {
3. _Color ("Main Color", Color) = (1,1,1,1)
4. _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
5. _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
6. _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
7. _BumpMap ("Normalmap", 2D) = "bump" {}
8. _BackColor ("Back Main Color", Color) = (1,1,1,1)
9.}
10.SubShader {
Unity双面渲染shader
11. Tags { "RenderType"="Opaque" }
12. LOD 400
13. Cull back
14.
15.CGPROGRAM
16.#pragma surface surf BlinnPhong
17.
18.
19.sampler2D _MainTex;
20.sampler2D _BumpMap;
21.fixed4 _Color;
22.half _Shininess;
23.
24.struct Input {
25. float2uv_MainTex;
26. float2uv_BumpMap;
27.};
28.
29.void surf (Input IN, inoutSurfaceOutput o) {
30. fixed4tex = tex2D(_MainTex, IN.uv_MainTex);
31. o.Albedo = tex.rgb * _Color.rgb;
32. o.Gloss = tex.a;
33. o.Alpha = tex.a * _Color.a;
34. o.Specular = _Shininess;
Unity双面渲染shader
35. o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));}
36.ENDCG
37.
38. Cull front
39.
40.CGPROGRAM
41.#pragma surface surf Lambert
42.
43.sampler2D _MainTex;
44.fixed4 _BackColor;
45.
46.struct Input {
47. float2uv_MainTex;
48.};
49.
50.void surf (Input IN, inoutSurfaceOutput o) {
51. fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _BackColor;
52. o.Albedo = c.rgb;
53. o.Alpha = c.a;
54.}
55.ENDCG
56.}
57.FallBack "Specular"
58.}
Unity双面渲染shader
反面渲染的运算就直接借用了系统的Diffuse Shader,只不过纹理是沿用正面的纹理,只增加了一个反面的颜色变量用来模拟环境光亮度,与纹理混合实现反面效果。渲染效果如下:
方式二代码:
复制代码
1.Shader "Hog's shaders/BumpSpec_Twoside2" {
2.Properties {
3. _Color ("Main Color", Color) = (1,1,1,1)
4. _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
5. _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
6. _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
7. _BumpMap ("Normalmap", 2D) = "bump" {}
8. _BackColor ("Back Main Color", Color) = (1,1,1,1)
9. _BackMainTex ("Back Base (RGB) Gloss (A)", 2D) = "white" {}
10.}
11.SubShader {
12. Tags { "RenderType"="Opaque" }
13. LOD 400
14. Cull back
15.
16.CGPROGRAM
17.#pragma surface surf BlinnPhong
Unity双面渲染shader
18.
19.
20.sampler2D _MainTex;
21.sampler2D _BumpMap;
22.fixed4 _Color;
23.half _Shininess;
24.
25.struct Input {
26. float2uv_MainTex;
27. float2uv_BumpMap;
28.};
29.
30.void surf (Input IN, inoutSurfaceOutput o) {
31. fixed4tex = tex2D(_MainTex, IN.uv_MainTex);
32. o.Albedo = tex.rgb * _Color.rgb;
33. o.Gloss = tex.a;
34. o.Alpha = tex.a * _Color.a;
35. o.Specular = _Shininess;
36. o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));}
37.ENDCG
38.
39. Cull front
40.
41.CGPROGRAM
Unity双面渲染shader
42.#pragma surface surf Lambert
43.
44.sampler2D _BackMainTex;
45.fixed4 _BackColor;
46.
47.struct Input {
48. float2uv_BackMainTex;
49.};
50.
51.void surf (Input IN, inoutSurfaceOutput o) {
52. fixed4 c = tex2D(_BackMainTex, IN.uv_BackMainTex) * _BackColor;
53. o.Albedo = c.rgb;
54. o.Alpha = c.a;
55.}
56.ENDCG
57.}
58.FallBack "Specular"
59.}
此方式下反面可以单独指定纹理,不指定就直接显示指定的反面颜色,渲染效果如下
以上只是介绍一个基本思想,在这个基础上能应该能衍生出无穷的变化。对自定义shader有兴趣的可以参考系统手册和Nvidia的CG教学手册。
不过千万不要动不动就使用双面材质,因为会增加系统负荷,应该只用在需要的地方。 把以上代码起个名字另存为.shader文件,导入工程assets,就能直接使用。
正在阅读:
Unity双面渲染shader05-14
汽车维修中级工理论试题(国家试题库强化训练共644题) - 附参考答案 - 图文09-22
天津大学化工原理考研真题05-23
201109玻璃钢烟囱内衬06-14
国土环境与灾害监测国家测绘地理信息局重点实验室科技发展02-02
兰州市“十二五”能源产业发展规划03-08
小学英语作业规范化要求06-09
中小学教师量化赋分办法09-20
先进班组事迹材料01-01
情感失落的话语02-11
- 教学能力大赛决赛获奖-教学实施报告-(完整图文版)
- 互联网+数据中心行业分析报告
- 2017上海杨浦区高三一模数学试题及答案
- 招商部差旅接待管理制度(4-25)
- 学生游玩安全注意事项
- 学生信息管理系统(文档模板供参考)
- 叉车门架有限元分析及系统设计
- 2014帮助残疾人志愿者服务情况记录
- 叶绿体中色素的提取和分离实验
- 中国食物成分表2020年最新权威完整改进版
- 推动国土资源领域生态文明建设
- 给水管道冲洗和消毒记录
- 计算机软件专业自我评价
- 高中数学必修1-5知识点归纳
- 2018-2022年中国第五代移动通信技术(5G)产业深度分析及发展前景研究报告发展趋势(目录)
- 生产车间巡查制度
- 2018版中国光热发电行业深度研究报告目录
- (通用)2019年中考数学总复习 第一章 第四节 数的开方与二次根式课件
- 2017_2018学年高中语文第二单元第4课说数课件粤教版
- 上市新药Lumateperone(卢美哌隆)合成检索总结报告
- 双面
- 渲染
- shader
- Unity
- 多轴型螺母拧紧机的机制
- 大学 外语小说翻译实习心得 案实习报告
- 微博十大经典营销案例分享
- 初二数学动点问题 初二数学动点问题分析 初二数学动点问题总结
- 英国各地五花八门口音介绍
- 南宁市消防安全工作例会制度
- 51单片机串口通信
- 2010年度cdma网优技能比赛填空题
- 世界最经典狙击枪和最著名的狙击步枪前十名排名
- 青山区2011-2012学年度上学期七年级数学期中试题
- 中国白酒五粮液包装设计市场调研分析
- 幽门螺杆菌致病机制的研究进展
- S3C2440A中文手册【八】
- 看美国影片必须了解的英文粗语脏话,好不容易整理出来的
- 《几何图形初步》复习学案(整理)
- 《肖邦故园》课堂实录及心得
- 隧道衬砌配筋ansys验算毕业设计
- 一带一路详细介绍(背景、线路、难点风险等)
- 高中地理自然地理环境的整体性优秀教案合集
- 潜山型油藏的优化压裂设计