游戏蛮牛学习群(纯技术交流,不闲聊):159852603
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

首页   >   博客   >   18803836360

shader

个人分类: shader | 2018-10-9 20:18

MeshFilter :存储三角面 顶点信息

存储一个mesh(网格 模型的网格,就是模型由哪些三角面组成)

Meshrender  渲染一个模型的外观,就是样子,,按照mesh给它皮肤,,给他颜色;

 

材质:贴图(非必须)+shader

 

Unityshader 入门精要:(书籍)

 

 

应用程序(在cpu上执行)(shader 应用程序层)

调用opengl  directx(绘制图形图像的接口)

告知  gpu

Cpu 进行渲染

 

(语言)程序由cpu 运行   shader  传递给opengl directx

Shader 一种渲染命令  opengl 或者directx 负责解析shader 控制丰富多彩图形的渲染

 

Dx pc平台多  opengl 在移动端比较多  

 

Glsl  shader 用于opengl        slshader language

Hlsl shader 语言用于directx (微软出的)

 

nvidia)英伟达公司出的CG语言编写shader     cg语言是跨平台的

 

使用shaderlab编写unity中的shader      shaderlab是对shader的封装)

1,表面着色器 surface shader    unity独有的shader     (本身复杂,封装后简单)

2,顶点/片元着色器    vertex/fragment shader  (可以认为表面着色器,是对顶点/片源的一种封装)

3,固定函数着色器  fixed function shader  (旧设备不支持新效果)(弃用)

 

 

顶点/片源  实现效果更基本 ,更强大  (表面实现的顶点/片元一定可以实现)

(顶点/片元实现的效果,表面不一定能实现)

 

多个光源(多余两个)  使用表面,封装层已经对光源进行处理,会直接有效果

 

shader"ylq/01capsuleshader"//可以与名字不同    检视面板路径
{
Properties
{
//属性 属性名   类型    默认值
_Color("_Color",Color)=(1,1,1,1)
//                        x,y,z,w
_Vector("vector",Vector)=(1,2,3,4)
//
_Int("int",Int)=34234
//只有float 所以不用f   没double  
_Float("float",Float)=4.5
//必须有范围限制
_Range("range",Range(1,11))=6
//不设置图片  默认为白色
_2D("texture",2D)="White"{}
//立方体纹理 贴到天空上
_Cube("cube",Cube)="Red"{}

_3D("texture",3D)="Black"{}
}
//控制效果 可以有多个hsader   显卡运行效果的时候,从第一个subshader开始
//如果第一个subshader效果中的效果都可以实现,那么就是用第一个shader 
//如果发现subshaer中的某些效果实现不了,会自动运行下一个subshader
//由上倒下-由好变差  效果

//确保一定有运行的效果
subshader
{
//#region相当于一个方法(一个pass) 至少有一个pass块
pass
{
//写shader  代码         可以使用多个语言
CGPROGRAM
//使用cg 语言编写代码
//#region 使用属性时需要在pass块重新设置,检视面板会自动获取/
//pass 块的值    ,在pass只需要声明重新使用的值
float4 _Color;  //4  个值
float4 _Vector;
float _Float;
float _Range;
sampler2D _Range;
samplerCube _Cube;
sample3D _3D;
ENDCG
}
pass{}
}
//#region 用来指定一个原来存在的shader
//#endregion              subshader如果没起作用的话 ,会直接启用 fallback 
//不启用sub fall 时 属性不起作用
Fallback"VertexLit"

 

//float  使用二进制32位进行存储
//half   -6-6w 16位 不在范围就需要使用float  
//fixed 11位  -2到2 w    

颜色都用fixed存储
} 

 

 

 

 

 

 

 

shader"ylq/02ylq can run"
{
subshader{
pass
{
CGPROGRAM
//确定位置
//顶点坐标   建模时候  ,相对于中心的坐标       不是物体在3d的中心
//坐标转换   将顶点坐标从模型空间转换到剪裁空间(不是实际的)     作用
//(从游戏环境到视野屏幕)
//顶点函数     这里只是声明了顶点函数的函数名
#pragma vertex myvertex
//函数名

//处理像素
//模型空间-》剪裁空间(屏幕空间)     长500高  800   40w像素
//片元函数        这里只是声明了顶点函数的函数名

//返回模型对应屏幕上的每一个像素的颜色

//函数名   不固定系统调用   参数 返回值   位空  固定
//xxx  函数名   参数 xxrx       float4  需要经过quation的转换


//(通过语义告诉系统我这个参数是干嘛的,比如position 是告诉系统我需要顶点坐标)
//sv_position这个语义用来解释说明返回值,意思是返回值是剪裁空间下的顶点坐标
//四维向量容易与矩阵相乘做转换     position 把顶点坐标传送给v
//顶点坐标传送到v

#pragma fragment myfrag



float4 myvertex(float4 v:POSITION):SV_POSITION
{
//             宏        矩阵就是完成从模型空间到剪裁空间的转换
//从系统获取再返回给系统
float4 pos= mul(UNITY_MATRIX_MVP,v);//与矩阵相乘
return pos;//返回值   返回给系统     系统通过语义传递给系统    a-b  ,b-a
}
fixed4 myfrag():SV_Target//xxx  函数名   参数 xxrx
{
return fixed4(0.5,0.5,1,1);
}
ENDCG
}
}

fallback"VertexLit"
} 

 

 

 

shader"ylq/03normalMap"
{
//properties{}
subshader
{
pass
{
CGPROGRAM
//声明两个方法
#pragma vertex myvertex
#pragma fragment myfragment

struct a2v
{
float4 vertex:POSITION;//告诉unity将模型空间下的顶点坐标填充给vertex

float3 normal:NORMAL;//告诉unity把模型空间下的发线法向填充给normal

float4 texcoord:TEXCOORD0;//告诉unity把第一套纹理坐标填充给texcoord
};

//结构体之间需要有空行
struct v2f
{
float4 position:SV_POSITION;
float3 temp:COLOR;
};


v2f myvertex(a2v v)
{
//float4 ff=mul(UNITY_MATRIX_MVP,v);
//return ff;
v2f vv;

vv.position=mul(UNITY_MATRIX_MVP,v.vertex);
vv.temp=v.normal;
return vv;
}


fixed myfragment(v2f vv ):SV_Target
{
return fixed4(vv.temp,1);
}
ENDCG
}



}
fallback"VertexLit"
//fallback"02ylq can run"
} 

 

 

从应用程序传递到顶点的函数:a2v   application to  vertex

Position 顶点坐标(模型空间下的)

Normal 法线模型空间下的

Tangent 切线(模型空间)

Texcoord0 -n 纹理坐标

Color 顶点颜色

 

从定点函数传递给片元函数可以使用的语义

Sv—position(剪裁空间的顶点坐标)(一般是系统使用)

Color0 可以传递颜色,或者坐标值(传四十值)

 

Color1  可以传递颜色,或者坐标值(传四十值)

 

Texcooed0 -7 传递纹理坐标

 

片元函数传递给系统

Sv——target   颜色值,显示屏幕上的颜色

 

什么是光照模型

就是一个公式,使用这个公式来计算光照效果

 

标准光照模型:把进入摄像机的光分为四个部分

 

自发光()

高光反射:镜子

漫反射:木头 cos(x))x  为0到90   光与法线的夹角

好多物体介于高光反射与漫反射之间:金属等

环境光;

 

颜色叠加时直接相乘         颜色融合时相加

系统内置环境光的宏,unity_lightmodel_ambient          .rgb才是光的颜色

环境光可以由天空盒子决定,也可以由单一的颜色决定

Window-》lighting-》ambient ->sky/color

因为可能单个物体想改颜色,所以需要自身有颜色的属性

 

顶点着色器消耗的性能相对较少,因为顶点个数有限,片元着色器消耗的性能相对较高,因为像素相对比较多

 

半兰伯特光照模型  

Diffuse =直射光颜色*(cosx*0.5+0.5)  取值-1-1   *0.5 -0.5-0.5    +0.5 0-1;不为负值那么背面不会全黑

 

高光反射:直射光 *pow(max(cosx,0),高光的参数)x:反射光方向和视野方向的夹角

 

高光反射2:直射光 *pow(max(cosx,0),高光的参数)x:平行光方向和视野方向的夹角

 

 

高光参数越大,高亮的范围越小,因为小于1的数,次方越高,越小

 

Shader使用贴图颜色,代替漫反射的颜色

 

(取得像素点)Tex2d(_MainTex,f.uv.xy)(返回颜色的值)   取得文理坐标对应的颜色

 

凹凸映射:高度映射,法线贴图

 

每一个像素都有一个rgb的值,使用tex2D可以获取像素的值

 

法线的取值每个轴-1-1  颜色的值0-1      法线的坐标使用颜色表示

 

 Pixel =(normal+1)/2            所以像素值并不是真的法线值

Normal=pixel*2-1;

法线贴图一般不再模型空间下表示(可以)  如果法线在当前模型空间的话,其他的模型便不能用了

切线空间:和模型没关系,所以效果可以在任何地方使用


错误1:冒号为中文冒号

错误2:函数必须在pass内   vertex fragment必须在program

错误3:片元不能直接操作uv,但是片元可以根据结构体存储的数据进行法线的绘制

(通过将法线转存到float3中,color0中)

错误4:每一个数据变量后边都要有对应的语义解释

错误5:片元函数不能直接操作顶点,法线,但是可以间接操作

Float32half16fixed2) 对应的范围不一样  (位数对应内存)

_color  _是因为怕与系统重复(变量别名,变量类型)

Shader{

properties{}

Subshader{}

Fallback“指定shader

}        一个shader可以包含多个pass块 ,pass块可以包含多个program



顶点着色器背光的部分为黑色,主要因为光的  lightcolor*cosx 之后  cosx取值为-1到1,所以小于0的部分为黑色

片元着色器因为描绘的更加具体(消耗性能大),所以效果好

兰伯特片元着色器因为,对光的cos值进行了*0.5.所以光的取值-0.5->0.5

然后取值再加上0.5,所以黑的地方应该只有一个点的范围而不是全部

兰伯特材质整体更加的高亮



原来的错误是因为,兰伯特光的强度为1,太高了遮盖了物体原本的颜色


高光因为平行光的方向是摄入的,高光的方向是反射出来的,所以反射光的方向与平行光的方向相反

因为摄像机相当与人眼,所以反射的时候,要根据摄像机的方向与反射光的夹角确定反射的亮度

根据反射公式,需要获得反射方向与摄像机的方向

反射的方向等于平行光的方向与法线(所在点)的夹角

摄像机的方向等于  摄像机与当前点法线的夹角


只有物体本身的颜色,与光的颜色是混的的,其他的都是相容(相加)


最后需要将环境光,漫反射,加上高光的亮度相加


trilliner  计算量大 ,效果好,减少像素拉伸

billiner   中间级别的计算,效果相对比较好

point 没裁切 像素被拉伸,会模糊 (像素风格)


clamp 超过后会取得最外边的贴图一直拉伸


切线空间:纯蓝色

法线空间:五颜六色

把所有与法线方向有关的运算都放在切线空间下

从法线贴图里面取得的法线方向是在切线空间下的


切线空间的确定是通过法线和切线决定的

tangent.w确定坐标轴的方向//w是用来确定切线空

间中坐标轴的方向的


颜色值:即像素值   ,获取像素


使用tangent ——space ——rotation时需要保证

a2v中有法线和切线

rotation(模型空间转换到切线空间)


unpacknormal()   物体有正常的normal法线贴图的时候

不能用自己制定的方法获取像素法线的颜色,负责会出现读取错误


贴图透明度,自定义透明度,混合透明度


0 0

作者的其他最新博客

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册帐号

个人分类

标签

阅读排行

评论排行

推荐博客

最新博客

返回顶部