Unity Shader 素描渲染
一、效果
Unity3D Shader 素描渲染
技术参考:https://io-meter.com/2014/12/31/sketch-rendering/
效果思路来源于以前看的一部电影《小王子》
当时就被里面的意境深深吸引,一种孤单星球的画面一直印在记忆里。于是就尝试了一下和素描渲染结合,发现别有一番韵味呢。
二、实现
1.素描shader
主要思路就是使用如下系列不同密度的素描线条,通过叠加深度的方式绘制出素描效果。
shader代码
Shader "Unlit/005Sketch"
{Properties{_Color("Color",Color) = (1,1,1,1)//贴图平铺系数_TileFactor("TileFactor", Range(0, 10)) = 1_Hatch0("Hatch0",2D) = "white"{}_Hatch1("Hatch1",2D) = "white"{}_Hatch2("Hatch2",2D) = "white"{}_Hatch3("Hatch3",2D) = "white"{}_Hatch4("Hatch4",2D) = "white"{}_Hatch5("Hatch5",2D) = "white"{}//描边系数_OutlineFactor("OutlineFactor",Range(0.0,0.1)) = 0.01}SubShader{Tags{ "Queue" = "Transparent" }//描边使用两个Pass,第一个pass沿法线挤出一点,只输出描边的颜色Pass{//剔除正面,只渲染背面Cull Front//关闭深度写入ZWrite Off//控制深度偏移,描边pass远离相机一些,防止与正常pass穿插Offset 1,1CGPROGRAM#include "UnityCG.cginc"#pragma vertex vert#pragma fragment fragfloat _OutlineFactor;struct v2f{float4 pos : SV_POSITION;};v2f vert(appdata_full v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);//将法线方向转换到视空间float3 vnormal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);//将视空间法线xy坐标转化到投影空间float2 offset = TransformViewToProjection(vnormal.xy);//在最终投影阶段输出进行偏移操作o.pos.xy += offset * _OutlineFactor;return o;}fixed4 frag(v2f i) : SV_Target{return float4(0,0,0,1);}ENDCG}Pass{Tags{"LightMode" = "ForwardBase"}CGPROGRAM#include "UnityCG.cginc"#include "Lighting.cginc"//使用阴影需添加#include "AutoLight.cginc"#pragma vertex vert#pragma fragment frag//使主要平行光产生阴影#pragma multi_compile_fwdbasefloat4 _Color;float _TileFactor;sampler2D _Hatch0;sampler2D _Hatch1;sampler2D _Hatch2;sampler2D _Hatch3;sampler2D _Hatch4;sampler2D _Hatch5;struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;//6张依次加深的贴图float3 hatchWeights0:TEXCOORD1;float3 hatchWeights1:TEXCOORD2;//声明阴影SHADOW_COORDS(4)float3 worldPos:TEXCOORD3;float3 color : COLOR;};v2f vert(appdata_full v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);//平铺系数越大,显示的贴图越密集o.uv = v.texcoord* _TileFactor;//float3 worldLightDir = normalize(WorldSpaceLightDir(v.vertex));float3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);float3 worldNormal = UnityObjectToWorldNormal(v.normal);//漫反射float diffuse = max(0, dot(worldLightDir, worldNormal));o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;//六张图片的权重o.hatchWeights0 = float3(0, 0, 0);o.hatchWeights1 = float3(0, 0, 0);//根据漫反射值计算权重,漫反射越暗,线条越密集float hatchFactor = diffuse * 7.0;if (hatchFactor > 6.0) {}else if (hatchFactor > 5.0) {o.hatchWeights0.x = hatchFactor - 5.0;}else if (hatchFactor > 4.0) {o.hatchWeights0.x = hatchFactor - 4.0;o.hatchWeights0.y = 1.0 - o.hatchWeights0.x;}else if (hatchFactor > 3.0) {o.hatchWeights0.y = hatchFactor - 3.0;o.hatchWeights0.z = 1.0 - o.hatchWeights0.y;}else if (hatchFactor > 2.0) {o.hatchWeights0.z = hatchFactor - 2.0;o.hatchWeights1.x = 1.0 - o.hatchWeights0.z;}else if (hatchFactor > 1.0) {o.hatchWeights1.x = hatchFactor - 1.0;o.hatchWeights1.y = 1.0 - o.hatchWeights1.x;}else {o.hatchWeights1.y = hatchFactor;o.hatchWeights1.z = 1.0 - o.hatchWeights1.y;}float3 diff = _LightColor0.rgb*saturate(dot(worldLightDir, worldNormal));o.color = diff;//把计算的阴影传到fragment中TRANSFER_SHADOW(o);return o;}fixed4 frag(v2f i) : SV_Target{float4 hatchTex0 = tex2D(_Hatch0, i.uv) * i.hatchWeights0.x;float4 hatchTex1 = tex2D(_Hatch1, i.uv) * i.hatchWeights0.y;float4 hatchTex2 = tex2D(_Hatch2, i.uv) * i.hatchWeights0.z;float4 hatchTex3 = tex2D(_Hatch3, i.uv) * i.hatchWeights1.x;float4 hatchTex4 = tex2D(_Hatch4, i.uv) * i.hatchWeights1.y;float4 hatchTex5 = tex2D(_Hatch5, i.uv) * i.hatchWeights1.z;//漫反射暗色部分权重越大,白色越少float4 whiteColor = float4(1, 1, 1, 1)*(1 - i.hatchWeights0.x - i.hatchWeights0.y - i.hatchWeights0.z - i.hatchWeights1.x - i.hatchWeights1.y - i.hatchWeights1.z);float4 hatchColor = hatchTex0 + hatchTex1 + hatchTex2 + hatchTex3 + hatchTex4 + hatchTex5 + whiteColor;//使物体接受阴影UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);return float4(hatchColor.rgb*_Color.rgb*atten, 1.0);}ENDCG}}
}
2.场景
场景部分比较简单,泰迪熊就是在Unity的AssetStore下载的免费模型资源。
泰迪熊的身体模型主要分为眼睛和身体两部分,因为这两部分的UV不同,所以做了两个才材质球,设置不同的平铺系数,
如图:
星球是一个Sphere,同样赋予一个不用平铺系数的材质球。
然后在灯光、相机、相机围绕的中心点都挂一个运动脚本MovingControl
public class MovingControl : MonoBehaviour
{public float speed = 100;public float speed2 = 0;void Update(){transform.Rotate(0, Time.deltaTime * speed, 0,Space.World);transform.Translate(Vector3.forward * speed2* Time.time);}
}
最后在泰迪熊上挂上一个轻柔而又有点孤独的音乐来烘托氛围
注意AudioSources要设置成3D的,这样就有一种渐行渐远的感觉。
三、工程地址
https://github.com/YasinXin/SketchShader
Unity Shader 素描渲染相关推荐
- Unity Shader卡通渲染 · 高清渲染管线·HDRP
Unity Shader卡通渲染 · 高清渲染管线·HDRP 前言 最近在研究HDRP管线中的卡通渲染,就想着能不能把官方的UCTS移植到HDRP管线里面去,说干就干,到昨天晚上上传了github,今 ...
- Unity Shader 卡通渲染 模型描边之退化四边形
目录 前言 一.基于空间的边缘检测算法 二.退化四边形 三.Unity中的CommandBuffer和ComputeBuffer 四.构成描边的简单实例 五.模型描边的实现 前言 之前写了一篇< ...
- Unity Shader 卡通渲染 实时模型动画描边的研究
前言 卡通渲染也叫非真实感渲染(英文简写:NPR),"描边"在图形学和数字图像里都叫边缘检测.因此你可以在很多文献网站上面找到很多这类文献,但最后我发现基于图形学使用的方式基本都是 ...
- Unity Shader 布料渲染(丝袜)
Unity Shader 布料渲染(丝袜) 现实中的丝袜效果 丹尼尔值 纤维的特性 分析 效果截图: Weak: Normal: Strong: 属性值定义: 丹尼尔值与拉伸程度 边缘度的计算 完整S ...
- 【Unity Shader】渲染纹理实现镜子效果
1 基本概念 1.1 什么是渲染到纹理? 全称是Render To Texture,<入门精要>好像又把渲染目标纹理,即Render Target Texture也叫做RTT,但我认为&l ...
- Unity Shader 卡通渲染 (一):仿塞尔达荒野之息 Shader(简易版)
温馨提示: 本系列文章面向那些 Shader 刚刚入门,想寻求进一步提升的群体,如果对 Shader 一无所知的话,建议自行搜索其他 Shader入门教程观看学习,再食用本系列文章. 前言: 说起卡通 ...
- Unity Shader 卡通渲染 (三):仿塞尔达荒野之息 Shader(顶点色控制细节)
上一篇传送门: https://blog.csdn.net/qq_27534999/article/details/100925621 顶点色在卡通渲染中有挺多应用,本篇会在上一篇的基础上,运用模型顶 ...
- 【Unity Shader】渲染纹理(镜子与玻璃)
一般来说,一个摄像机的渲染结果会输出到颜色缓冲之中,并显示到我们的屏幕上.现代的GPU允许我们把整个三维场景渲染到一个中间缓冲中,即渲染目标纹理(RTT),而不是传统的帧缓冲或者后备缓冲.与之相关的是 ...
- unity shader卡通渲染(描边)+阴影+多光源处理
说道卡通渲染,应该都会想到描边: 我所学的描边有三种: 一种是计算边缘深度检测描边 一种是色差检测描边 一种是利用顶点法线向外扩展返回单色pass,使用正面裁剪 我用的第三种: pass {//剔除前 ...
最新文章
- python语言标号_Python 编码为什么那么蛋疼?
- Python之匿名函数
- 斯坦福2014机器学习笔记五----正则化
- C宏定义-SWAP的妙用
- 深入浅出 Java CMS 学习笔记
- Java基础:如何向控制台写输出
- 在线代理和缓存工具(转)
- .Net中加密解密相关知识
- linux服务器启动ftp连接
- ArrayUtils
- c语言11章谭浩强,谭浩强 C语言 第11章 结构体.ppt
- 十五秒破解“还原卡”
- java-pdf-itext7、itextpdf 生成pdf 文档 定制票据打印
- 查询oracle所有回收站,oracle 回收站
- 8.TypeScript入门之TS类型声明文件
- java课程设计模拟科学计算器_JAVA课程设计科学计算器
- math.floor java_Java Math floor、ceil、rint 及 round 用法
- Andriod Studio创建数据库并查看自己创建的数据库
- btrfs和ntfs linux5,如何选择文件系统EXT4、Btrfs 和 XFS
- 分布式光伏站远程监控组网解决方案