u3d shader流光效果怎么加定点着色

【风宇冲】Unity3D教程宝典之Shader篇:第二十五讲描边及外发光
原创文章如需转载请注明:转载自
Shader第二十五讲:描边及外发光
描边以及外发光一般有如下几种实现方法:
【一贴图加工】
直接在贴图上对应模型边缘的位置画描边,凹的地方画阴影轮廓,凸起的地方画高光。
(1)效率高,对渲染效率没有增加任何负担。
(2)画风可个性化。充分满足定制的需求。
(1)这种方法需要考虑视角光线的属性。
阴影高亮:&
& 需要物体面和光源的相对关系不变。 &
& 对于棱角分明的物体(如立方体,风车) 可任意使用。因为边缘固定。
对于棱角不分明的物体(如球体人物等)需要物体面和相机的相对视角稳定。因为边缘和观察角度有关。
(2)增加工作量
《武士》《武士II》
【二 法线与视线计算】(Rim Lighting)
正常来说,物体法线与视线(从顶点至相机的方向)角度越一致,就越是能被玩家看见的中间。而边缘一般与法线垂直。由点乘即可计算轮廓光。
half rim =
- saturate(dot (normalize(IN.viewDir), o.Normal));
(1)实现简单,对渲染效率增加负担极小。
(2)有渐变,较真实。
(1)只适用于法线较均匀过度的模型。而不适用于棱角分明的物体,如上图中的立方体,故使用范围与贴图加工刚好相反。
《零世界》
"Example/Rim"
Properties
_MainTex ("Texture",
_BumpMap ("Bumpmap",
_RimColor ("Rim
Color) = (0.26,0.19,0.16,0.0)
_RimPower ("Rim
Range(0.5,8.0))
"RenderType"
#pragma surface surf
surf (Input IN, inout SurfaceOutput o) {
o.Albedo =
tex2D (_MainTex, IN.uv_MainTex).
o.Normal =
UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
half rim =
- saturate(dot (normalize(IN.viewDir), o.Normal));
//saturate
限制值于[0,1]之间
o.Emission =
_RimColor.rgb * pow (rim, _RimPower);
【三法线外拓】
也有叫挤出的
用2个Pass 渲染物体2次,
第一遍:描边,顶点沿法线方向外拓。
第二遍:正常渲染物体
(1)效果最好。
(2)适用范围广。
(1)对效率有一定影响。因为有2个Pass,所以DrawCall为正常的2倍
(2)对于法线过度不均匀的模型。轮廓会有缝隙,如上图立方体的左上角和右上角。
《变身吧 主公》
Shader&"Toon/Basic&Outline"&{
&&Properties&{
&&_Color&("Main&Color",&Color)&=&(.5,.5,.5,1)
&&_OutlineColor&("Outline&Color",&Color)&=&(0,0,0,1)
&&_Outline&("Outline&width",&Range&(.002,&0.03))&=&.005
&&_MainTex&("Base&(RGB)",&2D)&=&"white"&{&}
&&_ToonShade&("ToonShader&Cubemap(RGB)",&CUBE)&=&""&{&Texgen&CubeNormal&}
&&CGINCLUDE
&&#include&"UnityCG.cginc"
&&struct&appdata&{
&&float4&vertex&:&POSITION;
&&float3&normal&:&NORMAL;
&&struct&v2f&{
&&float4&pos&:&POSITION;
&&float4&color&:&COLOR;
&&uniform&float&_Outline;
&&uniform&float4&_OutlineColor;
&&v2f&vert(appdata&v)&{
&&o.pos&=&mul(UNITY_MATRIX_MVP,&v.vertex);
&&float3&norm&&&=&mul&((float3x3)UNITY_MATRIX_IT_MV,&v.normal);
&&float2&offset&=&TransformViewToProjection(norm.xy);
&&o.pos.xy&+=&offset&*&o.pos.z&*&_Outline;
&&o.color&=&_OutlineColor;
&&return&o;
&&SubShader&{
&&Tags&{&"RenderType"="Opaque"&}
&&UsePass&"Toon/Basic/BASE"
&&Name&"OUTLINE"
&&Tags&{&"LightMode"&=&"Always"&}
&&Cull&Front
&&ZWrite&On
&&ColorMask&RGB
&&Blend&SrcAlpha&OneMinusSrcAlpha
&&CGPROGRAM
&&#pragma&vertex&vert
&&#pragma&fragment&frag
&&half4&frag(v2f&i)&:COLOR&{&return&i.color;&}
&&SubShader&{
&&Tags&{&"RenderType"="Opaque"&}
&&UsePass&"Toon/Basic/BASE"
&&Name&"OUTLINE"
&&Tags&{&"LightMode"&=&"Always"&}
&&Cull&Front
&&ZWrite&On
&&ColorMask&RGB
&&Blend&SrcAlpha&OneMinusSrcAlpha
&&CGPROGRAM
&&#pragma&vertex&vert
&&#pragma&exclude_renderers&shaderonly
&&SetTexture&[_MainTex]&{&combine&primary&}
&&Fallback&"Toon/Basic"
使用offset指令,这种方法能够避免法线外拓方法中产生的法线过渡不均匀的问题,但同时会产生新的问题,将普通物体置于其和相机之间有时候会,产生显示错误,如右下图的小黑点漏出。
&&&&&&&&&&&&&&&&&&&&&&&&&
Shader&"Custom/Cartoon_Offset"&{
&Properties&{
&_MainTex&("Texture",&2D)&=&"white"&{&}
&SubShader
& &Cull&front
& &offset&-5,-1
& &CGPROGRAM
& &#pragma&vertex&vert
& &#pragma&fragment&frag
& &#include&"UnityCG.cginc"
& &sampler2D&_MainTex;
& &float4&_MainTex_ST;
& &struct&v2f&{
&float4&&pos&:&SV_POSITION;
&float2&&uv&:&TEXCOORD0;
& &v2f&vert&(appdata_base&v)
&o.pos&=&mul(UNITY_MATRIX_MVP,v.vertex);
&o.uv&=&TRANSFORM_TEX(v.texcoord,_MainTex);
&return&o;
& &float4&frag&(v2f&i)&:&COLOR
&return&float4(0,0,0,0);
&//绘制物体
& &offset&2,-1
& &CGPROGRAM
& &#pragma&vertex&vert
& &#pragma&fragment&frag
& &#include&"UnityCG.cginc"
& &sampler2D&_MainTex;
& &float4&_MainTex_ST;
& &struct&v2f&{
&float4&&pos&:&SV_POSITION;
&float2&&uv&:&TEXCOORD0;
& &v2f&vert&(appdata_base&v)
&o.pos&=&mul(UNITY_MATRIX_MVP,v.vertex);
&o.uv&=&TRANSFORM_TEX(v.texcoord,_MainTex);
&return&o;
& &float4&frag&(v2f&i)&:&COLOR
&float4&texCol&=&tex2D(_MainTex,i.uv);
&float4&outp&=&texCol;
&return&outp;
【五描边加光照】
二 :光的特殊处理:光的离散化
主要就两句代码
//***&漫反射光离散化&***
diffuseF&=&floor(diffuseF*&_DiffuseStep)/_DiffuseStep;
//***&镜面反射光离散化&***
specF&=&floor(specF*&_SpecFacStep)/_SpecFacStep;
Shader&"Custom/mylightCartoon"&{
&Properties&{
&_OutlineColor&("Outline&Color",&Color)&=&(0,0,0,1)
&_Outline&("Outline&width",&Range&(.002,&0.03))&=&.005
&_MainTex&("Base&(RGB)",&2D)&=&"white"&{&}
&_DiffuseStep("_DiffuseStep&0.1-3",Range(0.1,3))&=&0.5
&_SpecFacStep("_SpecFacStep&0.1-3",Range(0.1,3))&=&0.5
&SubShader
&&Name&"OUTLINE"
& &Tags&{&"LightMode"&=&"Always"}
& &Cull&front
& &CGPROGRAM
& &#pragma&vertex&vert
& &#pragma&fragment&frag
& &#include&"UnityCG.cginc"
& &sampler2D&_MainTex;
& &float4&_MainTex_ST;
&&uniform&float&_Outline;
&uniform&float4&_OutlineColor;
&struct&v2f&{
&float4&pos&:&POSITION;
&float4&color&:&COLOR;
& &v2f&vert&(appdata_full&v)
&o.pos&=&mul(UNITY_MATRIX_MVP,&v.vertex);
&float3&norm&&&=&mul&((float3x3)UNITY_MATRIX_IT_MV,&v.normal);
&float2&offset&=&TransformViewToProjection(norm.xy);
&o.pos.xy&+=&offset&*&o.pos.z&*&_Outline;
&o.color&=&_OutlineColor;
&return&o;
& &float4&frag&(v2f&i)&:&COLOR
&return&i.color;
& &tags{"LightMode"="Vertex"}
& &CGPROGRAM
& &#pragma&vertex&vert
& &#pragma&fragment&frag
& &#include&"UnityCG.cginc"
& &#include&"Lighting.cginc"
& &sampler2D&_MainTex;
& &float4&_MainTex_ST;
& &float&_DiffuseStep;
& &float&_SpecFacStep;
& &struct&v2f&{
&float4&&pos&:&SV_POSITION;
&float2&&uv&:&TEXCOORD0;
&float3&normal:TEXCOORD1;
&float3&lightDir:TEXCOORD2;
&float&atten:TEXCOORD3;
&float3&viewDir:TEXCOORD4;
& &float4x4&inverse(float4x4&input)
&#define&minor(a,b,c)&determinant(float3x3(input.a,&input.b,&input.c))
&//determinant(float3x3(input._22_23_23,&input._32_33_34,&input._42_43_44))
&float4x4&cofactors&=&float4x4(
&&minor(_22_23_24,&_32_33_34,&_42_43_44),&
&-minor(_21_23_24,&_31_33_34,&_41_43_44),
&&minor(_21_22_24,&_31_32_34,&_41_42_44),
&-minor(_21_22_23,&_31_32_33,&_41_42_43),
&-minor(_12_13_14,&_32_33_34,&_42_43_44),
&&minor(_11_13_14,&_31_33_34,&_41_43_44),
&-minor(_11_12_14,&_31_32_34,&_41_42_44),
&&minor(_11_12_13,&_31_32_33,&_41_42_43),
&&minor(_12_13_14,&_22_23_24,&_42_43_44),
&-minor(_11_13_14,&_21_23_24,&_41_43_44),
&&minor(_11_12_14,&_21_22_24,&_41_42_44),
&-minor(_11_12_13,&_21_22_23,&_41_42_43),
&-minor(_12_13_14,&_22_23_24,&_32_33_34),
&&minor(_11_13_14,&_21_23_24,&_31_33_34),
&-minor(_11_12_14,&_21_22_24,&_31_32_34),
&&minor(_11_12_13,&_21_22_23,&_31_32_33)
&#undef&minor
&return&transpose(cofactors)&/&determinant(input);
& &v2f&vert&(appdata_full&v)
&o.pos&=&mul(UNITY_MATRIX_MVP,v.vertex);
&o.uv&=&TRANSFORM_TEX(v.texcoord,_MainTex);
&o.normal&=&v.normal;
&#ifndef&USING_DIRECTIONAL_LIGHT
&float3&lightPos&=&mul(&inverse(UNITY_MATRIX_MV),unity_LightPosition[0]).xyz;
&o.lightDir&=&lightPos;
&o.lightDir&=&mul(&inverse(UNITY_MATRIX_MV),unity_LightPosition[0]).xyz;
&float3&viewpos&=&mul&(UNITY_MATRIX_MV,&v.vertex).xyz;
&float3&toLight&=&unity_LightPosition[0].xyz&-&viewpos.xyz&*&unity_LightPosition[0].w;
&float&lengthSq&=&dot(toLight,&toLight);
&o.atten&=&1.0&/&(1.0&+&lengthSq&*&unity_LightAtten[0].z);
&o.viewDir&=&mul&((float3x3)inverse(UNITY_MATRIX_MV),&float3(0,0,1)).xyz;
&return&o;
& &float4&frag&(v2f&i)&:&COLOR
&float4&texCol&=&tex2D(_MainTex,i.uv);
&i.normal&=&normalize(i.normal);
&i.lightDir&=&normalize(i.lightDir);
&i.viewDir&=&normalize(i.viewDir);
&//(<span STYLE="FonT-sTYLe: CoLor: #)漫反射强度
&float&diffuseF&=&max(0,dot(i.normal,i.lightDir));
&//***&漫反射光离散化&***
&&diffuseF&=&floor(diffuseF*&_DiffuseStep)/_DiffuseStep;
&&//(<span STYLE="FonT-sTYLe: CoLor: #)镜面反射强度
&float&specF;
&float3&H&=&normalize(i.lightDir&+&i.viewDir);
&float&specBase&=&max(0,dot(i.normal,H));
& &//&shininess&镜面强度系数
& &specF&=&pow(specBase,32);
& &//***&镜面反射光离散化&***
& &specF&=&floor(specF*&_SpecFacStep)/_SpecFacStep;
&&//(<span STYLE="FonT-sTYLe: CoLor: #)结合漫反射光与镜面反射光
&float4&outp&=&texCol*unity_LightColor[0]*(0.9&+&0.5*&diffuseF*i.atten&)+&unity_LightColor[0]*specF&*1;
&return&outp;
还有一种方法,与使用floor离散化不同。
将diffuse的强度映射至[0,1]
然后通过一张亮度表来纹理查询
diff=smoothstep(0,1,diff);
float&toon=tex2D(_ToonMap,float2(diff,diff)).r;
Shader&"Tut/Shader/Toon/Cel_2"&{
&Properties&{
&_ToonMap("Map&to&Toon",2D)="white"{}
&_Color("Main&Color",color)=(1,1,1,1)
&_Outline("Thick&of&Outline",range(0,0.1))=0.02
&_Factor("Factor",range(0,1))=0.5
&_ToonEffect("Toon&Effect",range(0,1))=0.5
&SubShader&{
&Tags{"LightMode"="Always"}
&Cull&Front
&ZWrite&On
&CGPROGRAM
&#pragma&vertex&vert
&#pragma&fragment&frag
&#include&"UnityCG.cginc"
&float&_Outline;
&float&_Factor;
&struct&v2f&{
& &float4&pos:SV_POSITION;
&v2f&vert&(appdata_full&v)&{
& &float3&dir=normalize(v.vertex.xyz);
& &float3&dir2=v.normal;
& &float&D=dot(dir,dir2);
& &dir=dir*sign(D);
& &dir=dir*_Factor+dir2*(1-_Factor);
& &v.vertex.xyz+=dir*_Outline;
& &o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
& &return&o;
&float4&frag(v2f&i):COLOR
& &float4&c=0;
& &return&c;
&}//end&of&pass
&Tags{"LightMode"="ForwardBase"}
&Cull&Back
&CGPROGRAM
&#pragma&vertex&vert
&#pragma&fragment&frag
&#include&"UnityCG.cginc"
&sampler2D&_ToonMap;
&float4&_LightColor0;
&float4&_Color;
&float&_ToonEffect;
&struct&v2f&{
& &float4&pos:SV_POSITION;
& &float3&lightDir:TEXCOORD0;
& &float3&viewDir:TEXCOORD1;
& &float3&normal:TEXCOORD2;
&v2f&vert&(appdata_full&v)&{
& &o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
& &o.normal=v.normal;
& &o.lightDir=ObjSpaceLightDir(v.vertex);
& &o.viewDir=ObjSpaceViewDir(v.vertex);
& &return&o;
&float4&frag(v2f&i):COLOR
& &float4&c=1;
& &float3&N=normalize(i.normal);
& &float3&viewDir=normalize(i.viewDir);
& &float3&lightDir=normalize(i.lightDir);
& &float&diff=max(0,dot(N,i.lightDir));
& &diff=(diff+1)/2;
& &diff=smoothstep(0,1,diff);
& &float&toon=tex2D(_ToonMap,float2(diff,diff)).r;
& &diff=lerp(diff,toon,_ToonEffect);
& &c=_Color*_LightColor0*(diff);
& &return&c;
&Tags{"LightMode"="ForwardAdd"}
&Blend&One&One
&Cull&Back
&ZWrite&Off
&CGPROGRAM
&#pragma&vertex&vert
&#pragma&fragment&frag
&#include&"UnityCG.cginc"
&float4&_LightColor0;
&sampler2D&_ToonMap;
&float4&_Color;
&float&_ToonEffect;
&struct&v2f&{
& &float4&pos:SV_POSITION;
& &float3&lightDir:TEXCOORD0;
& &float3&viewDir:TEXCOORD1;
& &float3&normal:TEXCOORD2;
&v2f&vert&(appdata_full&v)&{
& &o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
& &o.normal=v.normal;
& &o.viewDir=ObjSpaceViewDir(v.vertex);
& &o.lightDir=_WorldSpaceLightPos0-v.vertex;
& &return&o;
&float4&frag(v2f&i):COLOR
& &float4&c=1;
& &float3&N=normalize(i.normal);
& &float3&viewDir=normalize(i.viewDir);
& &float&dist=length(i.lightDir);
& &float3&lightDir=normalize(i.lightDir);
& &float&diff=max(0,dot(N,i.lightDir));
& &diff=(diff+1)/2;
& &diff=smoothstep(0,1,diff);
& &float&atten=1/(dist);
& &diff=diff*atten;
& &float&toon=tex2D(_ToonMap,float2(diff,diff)).r;
& &diff=lerp(diff,toon,_ToonEffect);
& &half3&h&=&normalize&(lightDir&+&viewDir);
& &float&nh&=&max&(0,&dot&(N,&h));
& &float&spec&=&pow&(nh,&32.0);
& &float&toonSpec=floor(spec*atten*2)/2;
& &spec=lerp(spec,toonSpec,_ToonEffect);
& &c=_Color*_LightColor0*(diff+spec);
& &return&c;
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。扫一扫,访问微社区
后使用快捷导航没有帐号?
签到成功!您今天第{todayrank}个签到,签到排名竞争激烈,记得每天都来签到哦!已连续签到:{constant}天,累计签到:{days}天
当前位置: &
查看: 688|回复: 0
可编程管线Shader教程:顶点和片段着色器程序
71558/5000排名<font color="#FF昨日变化1主题帖子积分
日久生情, 积分 1558, 距离下一级还需 3442 积分
日久生情, 积分 1558, 距离下一级还需 3442 积分
蛮牛币1313
在线时间684 小时
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
才可以下载或查看,没有帐号?
本帖最后由 soulvision 于
19:19 编辑
这个教程将带你学习如何自定义一个Unity顶点和片段着色器,在此之前,你可以先参阅ShaderLab的基础篇:《Getting Started tutorial》,如果你想编写一个能与光线交互的shader,那么你可以参阅这篇文章:《Surface Shaders》开始前我们先概述一下shader的框架:
Shader &MyShaderName& {& & Properties {& && &&&
// ... properties here ...& &
SubShader {& && &&&
// ... subshader for graphics hardware A ...& && &&&
Pass {& && && && &
// ... pass commands ...& && &&&
// ... more passes if needed ...& &
SubShader {& && &&&
// ... subshader for graphics hardware B ...& &
// ... Optional fallback ...& &
FallBack &VertexLit&
在这个框架的结尾,我们看到了这个命令:FallBack “VertexLit”
Fallback命令在shader的最后被调用,它表示:如果当前的subshaders无法运行在用户的显卡上,它将指定一个shader执行。比如说:你编写一个normal-mapped shader,然而你的旧显卡并不支持,所以你只好使用命令fallback,让它回滚到内置的VertexLit shader。
shader的一些基础内建块可以参阅[first shader tutorial],这里将有完整的介绍[Properties, SubShaders,和 Passes.
创建 SubShaders 的快速方法是使用在其他着色器中定义的passes。使用UsePass命令就可以实现shader代码的复用,例如你可以使用这样的命令来调用内建的Specular shader中名为”BASE”的pass:UsePass”Specular/BASE”.
当然,要让UsePass命令起作用,关键的一点是要给被调用的pass取名,在pass中你需要这样定义:Name”MyPassName”.
顶点和片段程序在上一个教程中,我们说的pass调用只是单张纹理贴图的混合指令,这回我们要来说说如何在pass中使用顶点和片段程序。
顶点&片段程序也称作:可编程管线程序。当然,大部分函数在显卡硬件中是被写死的,叫做固定管线。比如使用顶点程序完全关闭标准的3d变形、关照和纹理坐标。同样,使用片段程序替换SetTexture命令中定义的纹理合并模式,因此不需要SetTexture命令。
编写顶点/片段程序需要大量关于3D变换,光照和坐标控件的知识,因为你不得不重写内置的函数,比如你将自定义OpenGL的固定功能,另一方面,比起内置的那些功能,你可以扩展的更多。
在ShaderLab开发中使用Cg/HLSLshader通常使用Cg/HLSL程序语言编写,Cg和HLSL实际上是同一种语言(Cg语言是Microsoft和NVIDIA相互协作在标准硬件光照语言的语法和语义上达成了一致),所以我们可以交换使用这两种语言。
着色器代码写的着色器文本中嵌入&Cg 片段&。Cg 片段由Unity编辑器编译成低级着色器程序集,最终着色器将是包含在你的那些只包含此低级程序集或字节码的游戏数据文件中,当然这是特定于平台。当您在项目视图中选择shader时,检查面板有一个按钮用于显示编译着色器代码,可能会帮助帮助调试。Unity将自动编译所有相关的平台 (Direct3D 9、 OpenGL,Direct3D 11、 OpenGL ES 等等) 的 Cg 片段代码。请注意,由于 Cg 代码由编辑器编译,所以你不能在运行时创建 Cg 着色器。
总的来说,Cg片段放在Pass块中,就像这样:
// ... the usual pass state setup ...& &
CGPROGRAM& &
// compilation directives for this snippet, e.g.:& &
#pragma vertex vert& &
#pragma fragment frag& &
// the Cg code itself& & ENDCG& &
// ... the rest of pass setup ...
下面的示例演示完整的着色器,Cg 程序呈现对象法线作为颜色:
Shader &Tutorial/Display Normals& {& &
SubShader {& && &&&
Pass {& && && && &
CGPROGRAM& && && && &
#pragma vertex vert& && && &&&
#pragma fragment frag& && && && &
#include &UnityCG.cginc&& && && && &
struct v2f {& && && && && &
float4 pos : SV_POSITION;& && && && && &
fixed3 color : COLOR0;& && && && &};& && && && &
v2f vert (appdata_base v)& && && &&&
{& && && && && &
v2& && && && && &
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);& && && && && &
o.color = v.normal * 0.5 + 0.5;& && && && && &
& && && && &}& && && && &
fixed4 frag (v2f i) : SV_Target& && && && &
{& && && && && &
return fixed4 (i.color, 1);& && && && &
}& && && && &
ENDCG& && &&&}& & }}
测试结果:
在我们这个&Display Normals&的shader中并没有任何属性(Properties),除了Cg代码外,只包含了一个SubShader和一个Pass,让我们逐一分析下Cg代码:
CGPROGRAM#pragma vertex vert#pragma fragment frag// ...ENDCG
全部Cg 代码将在 CGPROGRAM 和 ENDCG 关键字之间编写。#pragma 将声明开始编译指令的语句。其中#pragma vertex name 将告诉程序这里包含了一个顶点着色器
#pragma fragment name 将告诉程序这里包含了一个片段着色器
以下编译指令是只是纯 Cg 代码。它告诉程序包含了一个内置的 Cg 文件(文件里包含了我们需要的函数):
#include &UnityCG.cginc&
UnityCG.cginc 文件包含常用的声明和函数,这样我们的着色器可以保持一个比较SMALL的状态 (参见Shader include files页面的详细信息)。我们将从该文件使用 appdata_base 结构。当然,我们也可以直接在当前shader定义,这样就不用引入这个文件。
接下来,我们定义&vertex to fragment&结构 (这里命名为 v2f):v2f表示:顶点到片断程序的信息传递。这里我们传递的是位置和颜色的参数。顶点着色器将计算color并且输出给片段着色器。我们继续通过定义顶点程序-vert函数。我们计算位置信息并且输出,输入法线作为color:o.color = v.normal * 0.5 +0.5;(这里为什么是*0.5+0.5呢?因为法线的值为-1到1,而color的值为0到1,为了让他们的值能规范匹配,否则会报错)。
接下来,我们定义一个片段程序-用于输出计算出来的颜色和1作为alpha component。fixed4 frag (v2f i) : SV_Target{& & return fixed4 (i.color, 1);}就这样,我们的shader就完成了,虽然很简单,但是对于可视化网格法线是非常有用的。当然,这个shader并无法响应灯光,这也是有趣的地方。与灯光相关,可以参考Surface Shader。在Cg代码中使用属性当你在shader中定义属性,你可以给它们命名类似:_Color或者_MainTex。要使用它们,你就必须要定义一个变量和对应的名称及类型。Unity会自动设定具有名称与属性匹配的Cg变量。下面是一个关于颜色调节纹理的完整shader,当然你同样可以轻易的在纹理合成器中调用,但这里主要是为了SHOW一下:如何在Cg中使用属性。Shader &Tutorial/Textured Colored& {& & Properties {& && &
_Color (&Main Color&, Color) = (1,1,1,0.5)& && &&&
_MainTex (&Texture&, ) = &white& { }& & }& &
SubShader {& && &&&
Pass {& && &&&
CGPROGRAM& && &&&
#pragma vertex vert& && &&&
#pragma fragment frag& && &
#include &UnityCG.cginc&& && &
fixed4 _C& && &&&
sampler2D _MainT& && &&&
struct v2f {& && && && &
float4 pos : SV_POSITION;& && && && &
float2 uv : TEXCOORD0;& && &&&};& && &&&
float4 _MainTex_ST;& && &&&
v2f vert (appdata_base v)& && &&&
{& && && && &v2& && && && &o.pos = mul (UNITY_MATRIX_MVP, v.vertex);& && && && &
o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);& && && && && && &&&}& && &&&
fixed4 frag (v2f i) : SV_Target& && &&&
{& && && && &fixed4 texcol = tex2D (_MainTex, i.uv);& && && && &return texcol * _C& && &&&}& && &&&
ENDCG& && &&&}& & }}
这个shader的结构跟之前的例子里的是一样样的。这里我们定义了两个属性,分别命名为:_Color和_MainTex.在Cg代码段中我们定义了相对应的变量:
fixed4 _Csampler2D _MainT
可以参阅《Accessing Shader Properties in Cg》获取更多信息。
顶点着色器和片段着色器并不是想象中那么的难懂和神秘。顶点着色程序通过UnityCG.cginc的TRANSFORM_TEX宏来确定纹理的缩放和偏移是否正确,而片段着色程序只是采样纹理并乘以颜色属性。
总结(终于要结束了)在这篇译文中,我们SHOW了如何自定义着色器,简单几步就写出了一个shader程序,例子虽然简单,但万变不离其宗,你依然能基于此写出更加复杂绚丽的shader程序,本篇可以充分帮助你利用unity来优化渲染。翻译自官方教程:《Shaders: Vertex and Fragment Programs》译者:优三帝同学
原帖地址:
unity 水波纹
每日推荐:购买商品:
商品价格:
价格读取中
支付方式:
请扫码进行支付
请扫码进行支付
由百度云提供技术支持
&学院APP&&
扫描微信二维码精彩活动、课程更新抢先知
下载客户端,离线视频任您学
1.&实时阴影实现方式
2.&编码实现
3.&角色透明材质解决方案
4.&角色阴影重叠解决方案
【课程类型】实战教学
【难度级别】高级
【适合人群】初级研发工程师
【课程介绍】 主要是针对移动端的手游开发对于角色的实时阴影绘制,以及解决透明材质的角色阴影绘制和阴影重叠问题。
【课程目标】 掌握实时阴影在移动端的绘制以及解决角色透明材质的阴影问题。
【课程计划】 共分为四个课时,从讲解到编码实现。
全部评价(0)
18课程281577学员[Unity3D][Shader&着色器]给物体边缘加高光轮廓的办法
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 u3d去切边的shader 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信