描边shader(法线外拓)
描边的思路是需要两个pass。第一个pass让顶点沿着法线方向延伸出去,使得模型变大一圈。第二个pass正常渲染,让正常渲染的模型挡在第一个pass之上,这样就会露出延伸出去的部分,延伸出去的就是我们要的描边了。代码实现如下:
Shader "Custom/PjOutlineTest" {
Properties {
_Color ("Color", Color) = (,,,)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_OutlineWidth("OutlineWidth",Range(,))=0.01
_Diffuse("Diffuse",Color)=(,,,)
}
SubShader {
//第一个pass沿着法线“膨胀”一点,并且剔除正面
pass{
Cull FRONT
Offset ,
CGPROGRAM
#include "UnityCG.cginc"
float4 _Color;
float _OutlineWidth;
#pragma vertex vert
#pragma fragment frag
struct v2f{
float4 pos:POSITION;
float4 color:COLOR;
};
v2f vert(appdata_full v){
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
//法向量转换到view坐标
float3 vNormal=mul((float3x3)UNITY_MATRIX_MV,v.normal);
//转换到投影面只需要x和y方向
float2 offsetDir=TransformViewToProjection(vNormal.xy);
//顶点坐标沿着法向量偏移“宽度值”
o.pos.xy+=offsetDir*_OutlineWidth;
o.color=_Color;
return o;
}
float4 frag (v2f i) : COLOR
{
return i.color;
}
ENDCG
}
//正常渲染
Pass
{
Tags{"LightMode" = "ForwardBase"}
CGPROGRAM
//引入头文件
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Diffuse;
sampler2D _MainTex;
//使用了TRANSFROM_TEX宏就需要定义XXX_ST
float4 _MainTex_ST;
struct v2f
{
float4 pos : SV_POSITION;
float lambert : TEXCOORD0;
float2 uv : TEXCOORD1;
};
v2f vert(appdata_full v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
float3 worldNormal = normalize(mul(v.normal, (float3x3)_World2Object));
float3 worldPos = mul(_Object2World, o.pos);
float3 worldLightDir =normalize(_WorldSpaceLightPos0.xyz);
o.lambert = dot(worldNormal, worldLightDir) ;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed3 diffuse = i.lambert * _Diffuse.xyz * _LightColor0.xyz ;
fixed4 color = tex2D(_MainTex, i.uv);
color.rgb = color.rgb* diffuse;
return fixed4(color);
}
ENDCG
}
}
FallBack "Diffuse"
}
效果如下:

法线外拓有些缺陷,在棱角分明的模型中表现较差,锐利的部分,描边会有断裂。
描边shader(法线外拓)的更多相关文章
- 小强学渲染之Unity Shader边缘描边加强
项目开发遇到一个需求,就是当坦克的准心瞄准敌方(enemy tank 或 item box)时,要让选中的对象的轮廓高亮起来,这实际上是接下来要讲解的实时渲染中轮廓线的渲染应用.实现方式有多种,下面逐 ...
- Unity Shader实现描边效果
http://gad.qq.com/article/detail/28346 描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果.本篇文章和大家介绍下利用S ...
- unity描边效果
这里总结了几种在unity实现描边效果的方法,首先准备一个模型导入在unity中,使用默认shader,上传一张原始图,以便后面实现功能效果的对比 一.边缘光,这里参照官方的一个SurfaceShad ...
- Unity——卡通渲染实现
效果展示: 原模型: 一.简单分析 卡通渲染又叫非真实渲染(None-Physical Rendering-NPR),一般日漫里的卡通风格有几个特点: 1.人物有描边 2.有明显的阴影分界线,没有太平 ...
- 基于Shader实现的UGUI描边解决方案
基于Shader实现的UGUI描边解决方案 前言 大扎好,我系狗猥.当大家都以为我鸽了的时候,我又出现了,这也是一种鸽.创业两年失败后归来,今天想给大家分享一个我最近研究出来的好康的,比游戏还刺激,还 ...
- Cocos2d-x shader学习3: sprite描边(Outline)
Cocos2d-x 3.x的label使用了freetype字体引擎(http://www.freetype.org/),可以很轻松的实现描边和阴影效果.所以本篇文章只针对于sprite来实现描边效果 ...
- Unity3d shader之卡通着色Toon Shading
卡通着色的目的是为了让被着色物体显得过渡的不那么好,明暗交界线很明显,等等卡通风格的一系列特征, 也叫Non-photorealisticrendering非真实渲染 重点要做到两点: 1. 描 ...
- Unity shader 官网文档全方位学习(一)
转载:https://my.oschina.net/u/138823/blog/181131 摘要: 这篇文章主要介绍Surface Shaders基础及Examples详尽解析 What?? Sha ...
- Unity3d游戏角色描边
本文发布于游戏程序员刘宇的个人博客,欢迎转载,请注明来源https://www.cnblogs.com/xiaohutu/p/10834491.html 游戏里经常需要在角色上做描边,这里总结一下平时 ...
随机推荐
- hadoop理解
Hadoop的主核心有2部分: 1,HDFS 2, MapReduce 首先: HDFS HDFS(Hadoop Distributed File System,Hadoop分布式文件系统),它是一个 ...
- bt协议详解 基础篇(下)
bt协议详解 基础篇(下) 最近开发了一个免费教程的网站,产生了仔细了解bt协议的想法,所以写了这一篇文章,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的技术,敬请期待. 1 ...
- HDU 6096 String (AC自动机)
题意:给出n个字符串和q个询问,每次询问给出两个串 p 和 s .要求统计所有字符串中前缀为 p 且后缀为 s (不可重叠)的字符串的数量. 析:真是觉得没有思路啊,看了官方题解,真是好复杂. 假设原 ...
- (I/O流)在100ms内桌面上生成一个200M大小的文件
最终速度取决于硬盘的读写速度 package com.laurdawn; import java.io.File; import java.io.FileInputStream; import jav ...
- C# 判断是否是在设计模式下有效的方法
public static bool IsDesignMode() { bool returnFlag = false; #if DEBUG if (LicenseManager.UsageMode ...
- 在win10 + ie11上使用控件
1.1. 在Win10+IE11上提示创建文件错误的问题 解决方法: 1.打开Internet选项 2.取消勾选启用保护模式 选择"不再显示此消息"
- Lua中“.”调用方法与“:”调用方法的区别
Lua中“.”调用方法与“:”调用方法的区别: ...
- 单例模式到Java内存模型
先说单例模式: 经典的单例模式实现: 饿汉式: public class Singleton { private static Singleton instance = new Singleton() ...
- python变量和简单的数据类型
1.运行hello_world.py时发生的情况 运行hello_world.py时,Python都做了些什么呢?实际上,即便是运行简单的程序,Python所做的工作也相当多: #!/usr/bin/ ...
- Linux daemon与service 学习笔记
service 常驻在内存中的进程,且可以提供一些系统或网络功能,就是服务. daemon service的提供需要进程的运行,所以实现service的程序我们称为daemon. eg: 实现 ...