700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > unity shader遮挡边缘光描边

unity shader遮挡边缘光描边

时间:2018-12-29 19:38:56

相关推荐

unity shader遮挡边缘光描边

Shader "Unlit/遮挡边缘光描边"{Properties{_MainTex("Texture", 2D) = "white" {}_Diffuse("Color",Color) = (1,1,1,1)_Outline("Outline",Range(0,1)) = 0.1 // 描边参数控制_OutlineColor("Outline Color",Color) = (0,0,0,0) // 描边颜色默认黑色_Steps("Steps",Range(1,30)) = 1 // 颜色分阶参数_ToonEffect("ToonEffect",Range(0,1)) = 0.5 // 卡通影响_RimColor("Rim Color",Color) = (1,1,1,1) // 边缘光颜色默认白色_RimPower("Rim Power",Range(0.001,3)) = 1 // 边缘光强度// X-ray_XRayColor("XRayColor",Color) = (1,1,1,1)_XRayPower("XRayPower",Range(0.01,3)) = 1}SubShader{Tags { "Queue" = "Geometry+1000" "RenderType" = "Opaque"} // +1000在其他不透明物体之后渲染LOD 100Pass // 遮挡X-ray{Name "Xray"Tags{"ForceNoShadowCasting" = "true"} // 无阴影Blend SrcAlpha One // SrcAlpha现颜色a通道做原颜色的目标因子 One目标颜色做目标颜色因子 就是将这两个因子混合叠加ZWrite Off // 不写深度ZTest Greater // 被挡住才画CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f{float4 vertex : SV_POSITION;float3 viewDir : TEXCOORD0; // 模型空间视角方向fixed3 normal : TEXCOORD1; // 模型空间法线};fixed4 _XRayColor;float _XRayPower;v2f vert(appdata_base v) {v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.viewDir = ObjSpaceViewDir(v.vertex); // 模型空间视角方向o.normal = v.normal; // 模型空间法线return o;}fixed4 frag(v2f i) : SV_Target{float3 normal = normalize(i.normal);float3 viewDir = normalize(i.viewDir); // 分别标准化float rim = 1 - dot(normal, viewDir);return _XRayColor * pow(rim , 1/ _XRayPower); // 乘上_XRayColor赋值颜色 这两步添加控制}ENDCG}Pass // 这个pass通道画图和边缘光{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc" // 不然没有 _LightColor0#include "UnityCG.cginc"struct v2f{float2 uv : TEXCOORD0;fixed3 worldNormal : TEXCOORD1; // 世界法线向量,计算漫反射 需要世界光向量和世界法线向量点乘float3 worldPos : TEXCOORD2; // 计算世界光向量需要世界坐标,所以这里把世界坐标传下去 计算漫反射float4 vertex : SV_POSITION; // 顶点坐标};sampler2D _MainTex;float4 _MainTex_ST;float4 _Diffuse;float _Steps;float _ToonEffect;fixed4 _RimColor;float _RimPower;v2f vert(appdata_base v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex); // 顶点信息从模型转到裁剪空间再放到输出结构体o.worldNormal = UnityObjectToWorldNormal(v.normal); // 法线从模型变换到世界坐标 法线是向量所以fixed3 为世界光向量和世界法线向量点乘计算漫反射做准备 所以要计算世界法线向量o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); // 拿到uvo.worldPos = mul(unity_ObjectToWorld, v.vertex); // 模型的世界坐标 顶点信息从模型坐标系转到世界坐标系得到return o;}fixed4 frag(v2f i) : SV_Target{fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; // 环境光fixed4 albedo = tex2D(_MainTex, i.uv); // 采样这个图fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos); // 世界光向量 漫反射世界光向量和世界法线向量点乘fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); // 世界视角向量float difLight = max(0,dot(worldLightDir,i.worldNormal)) * 0.5 + 0.5; // max不让这个值小于零 *0.5+0.5半兰伯特光照模型 这是漫反射光的值// 卡通颜色difLight = smoothstep(0, 1, difLight); // 颜色平滑在【0,1】之间 // 颜色离散化float toon = floor(difLight * _Steps) / _Steps; // floor参数向下取整 目的:分几块difLight = lerp(difLight, toon, _ToonEffect); // lerp前两个值插值,第三个是权值fixed3 diffuse = _LightColor0.rgb * albedo * _Diffuse.rgb * difLight; // 漫反射 // 边缘光float rim =1 - dot(i.worldNormal, worldViewDir); // 坐标的世界法线与世界视角方向点积 越接近0说明越垂直,也就越接近边缘 1-改逻辑为越近边值越大fixed3 rimColor = _RimColor * pow(rim , 1/_RimPower); // pow取次方 rim是0到1,取次方放大影响return fixed4(ambient + diffuse + rimColor,1);}ENDCG}Pass// 画边 裁剪空间外拓{ Name "Outline"Cull Front // 模型不画正面 防止与画图发生冲突CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"float _Outline;fixed4 _OutlineColor;struct v2f {float4 vertex : SV_POSITION; // 顶点坐标};v2f vert(appdata_base v) { // 顶点v2f o;o.vertex = UnityObjectToClipPos(v.vertex); // 顶点信息从模型转到裁剪空间float3 normal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, v.normal)); // 模型法线转到视角坐标系,z值变成纯粹的深度float2 viewNormal = TransformViewToProjection(normal.xy); // 把世界法线xy轴转到投影(Projection) z值是深度就不要了o.vertex.xy = o.vertex + viewNormal * _Outline; // 添加控制参数return o;}fixed4 frag(v2f i) : SV_Target{ // 片元return _OutlineColor;}ENDCG}}FallBack "Diffuse" // 阴影}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。