Shader入门——我的第一篇shader
Posted 御雪妃舞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shader入门——我的第一篇shader相关的知识,希望对你有一定的参考价值。
说到shader,很早前就开始看了,但是只是个大概,没有深入的研究,所以只能大概看看,自己写不出来,但是后来发现做项目过程中还是自己写比较快,于是,从这篇博客开始,准备深入研究一下。
另外,发现博客被抄袭和转载的厉害,还被别人加上了别人的水印,这点很不喜欢,所以,以后的博客,楼主会加自己的水印。
言归正传,我们将简单的从开头,属性和简单的调用介绍,后面还有一个博主研究的郁闷的问题,会的可以解答下:
1.前期准备
前期准备很简单,新建一个工程,新建一个场景,并保存,在场景中创建一个plane,两个球,如图:
然后,在Project面板下新建一个文件夹,叫1DiffuseShading,在下面分别建立Materials和Shaders文件夹,子文件夹下新建对应的shader和材质,并命名,最终结果如图:
2.Shader头部路径
如下是我新建的Shader的头部路径Shader "MyShaders/_BasicDiffuse"
shader的头部路径代表的是你的材质选择shader时的下拉菜单的路径,也可以直接把shader拖到材质上,如图
或者直接下拉菜单选择:
3.Shader属性
Properties
_EmissiveColor("Emissive Color",Color) = (1,1,1,1)
_AmbientColor("Ambient Color",Color) = (1,1,1,1)
_MySliderVale("This is a Slider",Range(0,10)) = 2.5
_Color("Color",Color) = (1,1,1,1)
这一段代码就是我的Shader的属性,包含变量名,变量显示名,变量类型,变量默认值,详细如下
这里举列的是Color,下面我们介绍下还有那些类型和举列,具体见下面表格
4.调用变量
整个代码如下:Shader "MyShaders/_BasicDiffuse"
Properties
_EmissiveColor("Emissive Color",Color) = (1,1,1,1)
_AmbientColor("Ambient Color",Color) = (1,1,1,1)
_MySliderVale("This is a Slider",Range(0,10)) = 2.5
SubShader
Tags "RenderType" = "Opaque"
LOD 200
CGPROGRAM
#pragma surface surf Lambert
float4 _EmissiveColor;
float4 _AmbientColor;
float _MySliderVale;
struct Input
float2 uv_MainTex;
;
void surf(Input IN,inout SurfaceOutput o)
float4 c;
c = pow((_EmissiveColor + _AmbientColor), _MySliderVale);
o.Albedo = c.rgb;
o.Alpha = c.a;
ENDCG
其中这个
Tags:
标签,暗示你的Shader输出什么 RenderType有Opaque(非透明物体),Transparent(透明物体) "IgnoreProjector"="True"(不被Projectors影 响) "ForceNoShadowCasting"="True"(从不产生阴影)"Queue"="xxx"(指定渲染顺序队列),预定义的Queue有Backgroud,Geometry,AlphaTest,Transparent,Overalay
- Background - 最早被调用的渲染,用来渲染天空盒或者背景
- Geometry - 这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
- AlphaTest - 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
- Transparent - 以从后往前的顺序渲染透明物体
- Overlay - 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)
LOD:
Level of Detail,Diffuse用200,根据设备图形性能调整值。
- VertexLit及其系列 = 100
- Decal, Reflective VertexLit = 150
- Diffuse = 200
- Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
- Bumped, Specular = 300
- Bumped Specular = 400
- Parallax = 500
- Parallax Specular = 600
CGPROGRAM:
与ENDCG对应,代表这部分代码是cg代码然后三个Float开始的字段要跟属性的名字一致,是为了跟属性面板里的变量建立连接, 名字一定要一样,这样我们下面方法点用的就是这个变量,也就是你面板里的变量值。
下面我们看surf方法,是让两种颜色相加然后做了增减,最后显示输出。 我给了Emissive Color一个红色,Ambinet Color一个绿色,最后输出了黄色:
如同颜色的变化,效果如图:
色彩效果如图:
红色加上绿色应该是黄色
5.关于pow的疑问
出来效果是对的,但是博主对pow有了疑问,C#中Mathf.pow是指x的y次方,参数是float,源码如图然后我试着f传入四元数是不可以的,然后我查了cg官网对pow的解释,也是说x的y次方。官网如图:
然后博主产生了严重的怀疑,按照高中数学的话,pow的结果应该是一个值,为何cg脚本里结果是一个四维数?
然后继续问,找到了官网pow的源码处理:地址:http://http.developer.nvidia.com/Cg/pow.html
有如下发现:
a.发现pow的重载方法,第一和第二个参数都是一样的,而我们shader中的第二个参数不是四元数?
b.log没有底数
后来技术群里问了下,大家猜测第二个参数是自动填充的,四个值一样,都是我们传的float,然后log的底数应该默认是e. 依据这样的条件下,我们做了这样的运算:
也就是说
我们验证我们上面unity里的效果,红加上绿应该等于黄色:
可是根据这个算出来确是红色加绿色等于白色。楼主郁闷了?不知道哪一步是有问题的,总不能官网上的方法是错的吧?求大神指教
以上是关于Shader入门——我的第一篇shader的主要内容,如果未能解决你的问题,请参考以下文章
Unity Shader入门精要学习笔记 - 第8章 透明效果
Unity Shader入门精要学习笔记 - 第10章 高级纹理
Unity Shader-后处理:简单的颜色调整(亮度,饱和度,对比度)