shader总结三
来源:互联网 发布:全景图拼接软件 编辑:程序博客网 时间:2024/06/04 00:27
切线空间下的法线贴图做法步骤:
1,
最后面的bump是使用模型自带的法线贴图
2,那么法线贴图也需要一个uv坐标(纹理坐标),一个物体本身的贴图一个法线贴图
3,在struct中虽然不需要用法线和切线但是依然要定义一个法线和切线,因为切线空间的切线是和法线垂直的,切线空间是通过切线和法线共同确定的
用一个float4,它的xy保存贴图的纹理坐标,zw保存法线贴图的纹理坐标,通过法线贴图的纹理坐标来获取法线贴图的颜色值
在vert函数中
4,把所有跟法线方向有关的运算都放在切线空间下
在片元函数中,先通过tex2D获取法线贴图的颜色,通过得到像素转法线的映射
而在下面的代码中是通过来将法线映射到切线空间下的
5,把光的方向转成切线空间,每个顶点的切线空间是不一样的,是有每个点的法线和切线来确定的,那么要通过顶点函数来处理,用
来作为临时变量在顶点函数中保存下来传递给片元函数
完整代码:
就得到了有凹凸效果的物体:
让贴图效果更加凹凸的做法:更改tangentNormal.xy即可,效果
最后注意的是tangent类型是float4而不是float3,原因是tangent.w分量来决定切线空间下的第三个坐标轴
渲染顺序:在一幅图像上,哪个物体先渲染,哪个后渲染是顺序是不一样的,所以在必要的情况下要在tag里面指定Queue的渲染队列,对于要把物体弄成透明的时候就要指定Queue
[FallBack]意思是当shader有多种方案时,保证能有一种方案能运行
什么是shader:
什么是渲染管线:
Shader "VertexLit" { Properties { //在unity材质面板上的属性 _Color ("Main Color", Color) = (1,1,1,0.5) _SpecColor ("Spec Color", Color) = (1,1,1,1) _Emission ("Emmisive Color", Color) = (0,0,0,0) _Shininess ("Shininess", Range (0.01, 1)) = 0.7 _MainTex ("Base (RGB)", 2D) = "white" { } //在面板上添加一个材质属性 } SubShader { Pass { Material { Diffuse [_Color] //在material中更改Diffuse漫反射的效果,括号里面是通过调用面板里面的参数 Ambient [_Color] //意思是更改面板的参数来更改漫反射,高光反射等等的效果 Shininess [_Shininess] //这个Shininess是显示高光反射的区域 Specular [_SpecColor] Emission [_Emission] } Lighting On //必须要把Lighting on打开,否则unity中物体是全黑的 SeparateSpecular On //要使用高光反射的时候使用Specular就要加上这句话把它打开 SetTexture [_MainTex] { //为物体添加上材质 constantColor [_Color] Combine texture * primary DOUBLE, texture * constant //注意的是添加材质后还有将material中的多种光源混合起来所以*primary } //DOUBLE意思是乘以2倍的光源亮度,看起来更亮,逗号第二个参数是修改Alfha的 } }}
如果添加了2张纹理,那么第二张的纹理颜色值要乘以第一张的和material中的光源的叠加,所以*previous
2、Surface shaders代码实例
3、CG代码实例
frag返回的是fixed4的数,但是还不够,还要说明返回的是什么类型,所有后面加上:COLOR
inout表示即输入又输出
uniform关键字,表示后面的这个值要由unity来给它提供
然后写一个脚本获取Renderer组件来设置,把脚本拖动到物体上
MVP中V是View即相机空间的意思
这是怎么实现的?
首先程序不能是静止的要是运行的,调用sin,cos的时间函数,改变的是一点的值,但是这里周围的颜色是做了插值运算,所以这样了,/2+0.5是把(-1,1)范围改成(0,1)
光带效果是怎么实现的?(下文仅是通过顶点函数来实现也可使用其他方式,在顶点里面处理很消耗性能)
在shader中顶点函数,要取得屏幕的x和y,先通过mvp把模型空间顶点转成剪裁空间下,x除以它的第四个分量w得到屏幕里的x和y,因为红色带就是在x某个范围内颜色为红,否则白色,x的左边和右边是移动的,所以dis用脚本的Time.deltaTime取得
再写一个脚本,挂到物体上,修改shader里面的变量
让一个平面凸起来怎么实现?
在模型空间下找到x和y距离0,0点的距离,这里用x,z轴构成的平面表示xy,取原点为圆心长度为1内的圆,圆心处d为1,圆外为0,把d乘以平面的z的值(这里y轴表示z轴)把该点转换到屏幕空间中
如果把颜色设成这样
效果就成这样
这样效果如何实现?
距离原点越远的地方旋转越大,构造旋转矩阵m,绕y轴旋转,旋转矩阵cos和sin的角度取自顶点距离圆心的距离乘以sinTime.w,从模型空间转到剪裁空间,剪裁空间下的旋转矩阵乘以模型空间下的顶点(为什么两个不放在同一空间相乘呢)
这样的效果如何实现?
其他代码不变,更改旋转矩阵变为缩放矩阵。只对x轴进行缩放
发现效果如下
这说明x轴的缩放太大了,我们要控制缩放的范围,改成sin(angle)/8+0.5, 效果如下
注意的是,它的波动是周期的,变成非周期的,就把sin去掉,直接Time.y,把顶点到原点的length改成蓝色轴的值比较好
效果就是最上面的那种
试想一下,如果构造如下的矩阵相乘后有效果吗?
答:没效果,因为该物体是个平面物体,黄轴也即y轴为0,因此如果一个平面物体让它上下运动就不能通过矩阵的形式乘了,改成点相乘
对于代码的执行效率优化:矩阵相乘有许多0相乘没必要算,那么把矩阵相乘直接改成有值的点和点的相乘,去除没必要的点
这种效果怎么实现?
思想,一个点在上下做周期运动,同时该点颜色也是周期变动,所以都是sin函数
如果要变成圆形抖动,就要把v.vertex.z改成length(v.vertex.xz)
如果改成这样
效果这样:
素材取自蛮牛教育
- shader总结三
- Unity3d Shader(三) Pass
- unity3D Shader<三>漫反射
- Shader - Pass (三)
- shader学习笔记三
- shader学习笔记三
- webgl-shader 学习总结
- Shader的学习方法总结
- Cocos Shader总结
- Shader资料总结
- shader总结一
- shader总结二
- openGL shader学习总结
- shader总结五
- shader总结六
- shader总结七
- shader总结八
- Shader的学习方法总结
- 模块API之module_refcount
- JavaWeb从入门到放弃(6)-仔细看下servlet
- Mat 数据类型保存为二进制文件
- Go语言变量的生命周期
- SpringMVC基础-2-组件
- shader总结三
- MySQL之约束、修改数据表
- oracle01创建表空间
- 学习网站总结
- SDUT-2712 派生类的构造函数
- 创建基本的搜索页面
- Splunk App for Stream
- uva 10934 Dropping water balloons
- nova 中读取proc/meminfo