Unity3D基于CG的Shader基础(二)

来源:互联网 发布:电子书包的软件 编辑:程序博客网 时间:2024/04/30 03:29

3.顶点和片段着色器:

实现颜色过渡,

添加边框

//顶点片段着色器的工作流程://1.首先:vertexProgram收到系统传递给他的模型数据//3.然后,把这些数据处理成我们后续需要的数据(至少包含定点的位置信息),其他的数据还包含一些文理的UV坐标以及他们的要传递的fragmentPraogram的数据//3.然后,系统对vertexProgram输入的顶点数据进行插值计算,并将差值结果传递给frgmentProgram,最后fragemntProgram根据这些插值计算屏幕上的显示的像素颜色Shader "CustomLearn/VertexAndFragShader" {Properties{//颜色设置_myColor("Color",color) = (1,1,1,1)//边框距离_outLine("OutLine",Range(0,1)) = 0.1}SubShader{//渲染不透明物体,IgnoreProjector指不受投影的影响Tags{"Queue" = "Geometry" "RenderType" = "Opaque" "IgnoreProjector" = "True"}//第一个通道。用来渲染物体表面的颜色PASS{CGPROGRAM//告诉程序定义一个顶点着色器#pragma vertex vert//定义一个片段着色器#pragma fragment frag//使用顶点和片段的CG时,需要引入头文件UnityCG.cginc#include "UnityCG.cginc"//定义vertex to fragment结构体//v2f:顶点程序到片段程序的信息传递//本结构体传递的是位置和颜色参数fixed4 _myColor;struct v2f{//该结构体中还可以包含其他的一些成员变量//1.float4 vertex:POSTION 顶点位置//2.float3 normal:POSTION 顶点法线//3.float4 texcoord:TEXCOORD0 第一UV坐标//4.float4 texcoord:TEXCOORD1 第二UV坐标//5.float4 tangent:TANGENT切线向量(一般是用在法线贴图中)//6.float4 color:COLOR 每个顶点的颜色//SV_POSITON:SV前缀的变量代表SystemValuefloat4 pos:SV_POSITION;float3 color:COLOR;};//顶点函数,参数十一结构体,返回值也是一个结构体//appdata_full是“UnityCG.cginc”的结构体类型//顶点函数的参数类型可以有://appdata_base:包含顶点位置,法线和一个纹理坐标//appdata_full:包含顶点的位置,法线和两个纹理坐标//appdata_tan:包含顶点位置,法线,切线和一个的纹理坐标//appdata_img:包含位置和一个纹理坐标v2f vert(appdata_full v) {v2f o;//UNITY_MATRIX_MVP表示当前模型视图投影的矩阵//UNITY_MATRIX_MV表示当前模型的视图矩阵//UNITY_MATRIX_V表示当前视图矩阵//UNITY_MATRIX_P表示当前视图投影矩阵//UNITY_MATRIX_T_MV:转置模型视图矩阵//UNITY_MATRIX_IT_MV:表示逆转置视图矩阵//mul:表示矩阵相除函数 o.pos = mul(UNITY_MATRIX_MVP,v.vertex);//彩虹色o.color = v.vertex*0.8+0.5;//纯色//o.color = v.normal*0.4+0.5;return o;}//片段函数,参数是v2f的结构体类型fixed4 frag(v2f i):COLOR{return fixed4(i.color*_myColor,1);}ENDCG}//第二个通道,用来渲染模型的边框pass{Name "Bordor"Tags{"LightModel" = "ForwardBase"}//前方剔除CULL FrontLighting OnCGPROGRAM#pragma vertex vert#pragma fragment frag//编译指令:编译正向渲染的基础通道//用于正向渲染中,应用环境关照,主方向光照和顶点所需要的变体#pragma multi_compile_fwdbase#include "UnityCG.cginc"//float相当于一个Range类型float _outLine;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 pos:POSITION;};v2f vert(a2v v){v2f o;float4 pos = mul(UNITY_MATRIX_MV,v.vertex);float3 normal = mul(UNITY_MATRIX_IT_MV,v.normal);pos = pos+float4(normalize(normal),0)*_outLine;o.pos = mul(UNITY_MATRIX_P,pos);return o;}fixed4 frag(v2f i):COLOR{ return fixed4(0,0,0,1);}ENDCG}}}
例子:

1.Earth的纹理和云层:

Shader "CustomPractice/Earth" {Properties {//地球纹理_EarthTex("EarthTex",2D) = "white"{}//云的纹理_CloudTex("CloudTex",2D) = "white"{}}SubShader {Tags{"RenderType" = "Transparent"}LOD 200Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _EarthTex;sampler2D _CloudTex;struct v2f{//顶点的位置float4 vertex:POSITION;//纹理的坐标fixed4 texcoord:TEXCOORD0;};void vert(inout v2f v){v.vertex = mul(UNITY_MATRIX_MVP,v.vertex);}fixed4 frag(v2f v):COLOR{//渲染出地球fixed u = v.texcoord.x+_Time*0.3;float2 uv = float2(u,v.texcoord.y);fixed4 earthColor = tex2D(_EarthTex,uv);//渲染出云层fixed uc = v.texcoord.x+_Time*0.5;float2 uvc = float2(uc,v.texcoord.y);fixed4 cloudColor = tex2D(_CloudTex,uvc);cloudColor = cloudColor.r*fixed4(1,1,1,1);//取地球和云颜色的插值return lerp(earthColor,cloudColor,0.5);}ENDCG}}FallBack "Diffuse"}

2.流水的效果

Shader "CustomPractice/River" {Properties {//设置颜色值_Color("Color",color) = (1,1,1,1)//设置纹理_MainTex("Albeo(RGB)",2D) = "white"{}//水流速度X_RiverSpeedX("X_Speed",Range(2,10)) = 5//水流速度_RiverSpeedY("Y_Speed",Range(2,10))= 5}SubShader {Tags{"RenderType" = "Opaque"}CGPROGRAM//使用漫反射的光照模型#pragma surface surf Lambert//CG程序中要使用外部输入的值,定义变量是,一定要与属性里面的变量名一致sampler2D _MainTex;fixed4 _Color;fixed _RiverSpeedX;fixed _RiverSpeedY;//输入结构体struct Input{float2 uv_MainTex;};void surf(Input IN,inout SurfaceOutput o){fixed xSpeed = _RiverSpeedX*_Time;fixed ySpeed = _RiverSpeedY*_Time;//使用内置的_Time变量来根据运行时间滚动Texturefixed2 uv = IN.uv_MainTex+fixed2(xSpeed,ySpeed);fixed4 c = tex2D(_MainTex,uv)*_Color;o.Albedo = c.rgb;o.Alpha = c.a;}ENDCG}FallBack "Diffuse"}

3.三种任务模型不同效果的对比

(1):法线贴图

Shader "CustomPractice/David01" {Properties {_MainTex("MainTexture",2D) = "white"{}}SubShader {Tags{"RenderType" = "Opaque"}Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _MainTex;struct v2f{float4 vertex:POSITION;fixed4 texcoord:TEXCOORD0;};void vert(inout v2f v){//将模型中的点转到屏幕中的位置v.vertex = mul(UNITY_MATRIX_MVP,v.vertex);}fixed4 frag(v2f v):COLOR{//片段方法:负责每个顶点在屏幕中的颜色//通过纹理坐标在纹理图片上进行采样,进行输出return tex2D(_MainTex,v.texcoord);}ENDCG}}FallBack "Diffuse"}

(2)透明

Shader "CustomPractice/David02" {Properties {_MainTex("Albedo(RGB)",2D) = "white"{}_LogoTex("LogoTexture",2D) = "white"{}}SubShader {Tags{"RenderType" = "Transparent"}//透明设置Blend SrcAlpha OneMinusSrcAlphaPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.CGINC"sampler2D _MainTex;sampler2D _LogoTex;void vert(inout appdata_base v){v.vertex = mul(UNITY_MATRIX_MVP,v.vertex);}fixed4 frag(appdata_base v):COLOR{fixed4 col = tex2D(_MainTex,v.texcoord);fixed4 logo = tex2D(_LogoTex,v.texcoord);return col*logo;}ENDCG}}FallBack "Diffuse"}

(3)卡通

Shader "CustomPractice/David03" {Properties {_MainTex("MainTexture",2D) = "white"{}_BumpTex("BumpTexture",2D) = "white"{}_EmssionColor("EmssionColor",Color) = (1,1,1,1)isEnter("IsEnter",int) = 0//卡通度Cartoon("Cartoon",Range(-0.05,0.05)) = 0.00}SubShader {Tags{"RenderType" = "Opaque"}CGPROGRAM//自定义光照,模型#pragma surface surf CustomLighting vertex:vert//主纹理sampler2D _MainTex;//法线纹理sampler2D _BumpTex;//高光颜色fixed4 _EmssionColor;//判断条件fixed isEnter;//缩放系统float Cartoon;struct Input{fixed2 uv_MainTex;fixed2 uv_BumpTex;//视觉方向float3 viewDir;};//注意:自定义光照模型名字前一定要加Lightinghalf4 LightingCustomLighting(SurfaceOutput o,half3 lightDir,half atten){half4 result;half4 nDot = dot(lightDir,o.Normal);nDot = nDot*0.5+0.5;//_LightColor0:表示当前光照颜色,由系统填充result.rgb = o.Albedo * _LightColor0.rgb * nDot*atten;return result;}//顶点方法:所有纹处理完之后才会执行这个方法来移动顶点void vert(inout appdata_full v){v.vertex.xyz+= v.normal.xyz*Cartoon;} void surf(Input IN,inout SurfaceOutput o){ fixed4 albedo = tex2D(_MainTex,IN.uv_MainTex); o.Albedo = albedo; //采样法线纹理 fixed4 bump = tex2D(_BumpTex,IN.uv_BumpTex); if(isEnter>0){ //求视觉方向上的单位向量 float3 view = normalize(IN.viewDir); //计算法线和视觉方向上的点积 float value = dot(view,o.Normal); //限制一下范围 value = 1-saturate(value); //边缘视觉高光现象 o.Emission=_EmssionColor*value*isEnter; } } ENDCG}FallBack "Diffuse"}
第一个是系统提供的Shader。

====================================================================================================================

下面是对上次一个用表面着色器写的云图的修正

Shader "CustomLearn/Five 1" {Properties{_MainTex("Albedo RGB", 2D) = "white"{}_Color("Color", color) = (0,0,0,1)_Alpha("Alpha", Range(0.5,1)) = 0.6_SpeedX("X_Speed",Range(0.5,10)) = 0.6_SpeedY("Y_Speed",Range(0.5,10)) = 0.6}SubShader{Tags {"RenderType" = "Transparent"}LOD 200CGPROGRAM//alpha 便是透明度#pragma surface surf Lambert alphasampler2D _MainTex;fixed4 _Color;half _Alpha;half _SpeedX;half _SpeedY;struct Input{float2 uv_MainTex;};void surf(Input IN, inout SurfaceOutput o){fixed  xSpeed = _SpeedX * _Time;fixed  ySpeed = _SpeedY * _Time;fixed2 uv = IN.uv_MainTex - fixed2(xSpeed,ySpeed);fixed4 c = tex2D(_MainTex, uv);o.Albedo = _Color * c.rgb;//o.Alpha = _Color.a * c.a * _Alpha;o.Alpha = c.a;}ENDCG}FallBack "Diffuse"}
效果图太大了没传上来……

0 0
原创粉丝点击