一、效果

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 素描渲染相关推荐

  1. Unity Shader卡通渲染 · 高清渲染管线·HDRP

    Unity Shader卡通渲染 · 高清渲染管线·HDRP 前言 最近在研究HDRP管线中的卡通渲染,就想着能不能把官方的UCTS移植到HDRP管线里面去,说干就干,到昨天晚上上传了github,今 ...

  2. Unity Shader 卡通渲染 模型描边之退化四边形

    目录 前言 一.基于空间的边缘检测算法 二.退化四边形 三.Unity中的CommandBuffer和ComputeBuffer 四.构成描边的简单实例 五.模型描边的实现 前言 之前写了一篇< ...

  3. Unity Shader 卡通渲染 实时模型动画描边的研究

    前言 卡通渲染也叫非真实感渲染(英文简写:NPR),"描边"在图形学和数字图像里都叫边缘检测.因此你可以在很多文献网站上面找到很多这类文献,但最后我发现基于图形学使用的方式基本都是 ...

  4. Unity Shader 布料渲染(丝袜)

    Unity Shader 布料渲染(丝袜) 现实中的丝袜效果 丹尼尔值 纤维的特性 分析 效果截图: Weak: Normal: Strong: 属性值定义: 丹尼尔值与拉伸程度 边缘度的计算 完整S ...

  5. 【Unity Shader】渲染纹理实现镜子效果

    1 基本概念 1.1 什么是渲染到纹理? 全称是Render To Texture,<入门精要>好像又把渲染目标纹理,即Render Target Texture也叫做RTT,但我认为&l ...

  6. Unity Shader 卡通渲染 (一):仿塞尔达荒野之息 Shader(简易版)

    温馨提示: 本系列文章面向那些 Shader 刚刚入门,想寻求进一步提升的群体,如果对 Shader 一无所知的话,建议自行搜索其他 Shader入门教程观看学习,再食用本系列文章. 前言: 说起卡通 ...

  7. Unity Shader 卡通渲染 (三):仿塞尔达荒野之息 Shader(顶点色控制细节)

    上一篇传送门: https://blog.csdn.net/qq_27534999/article/details/100925621 顶点色在卡通渲染中有挺多应用,本篇会在上一篇的基础上,运用模型顶 ...

  8. 【Unity Shader】渲染纹理(镜子与玻璃)

    一般来说,一个摄像机的渲染结果会输出到颜色缓冲之中,并显示到我们的屏幕上.现代的GPU允许我们把整个三维场景渲染到一个中间缓冲中,即渲染目标纹理(RTT),而不是传统的帧缓冲或者后备缓冲.与之相关的是 ...

  9. unity shader卡通渲染(描边)+阴影+多光源处理

    说道卡通渲染,应该都会想到描边: 我所学的描边有三种: 一种是计算边缘深度检测描边 一种是色差检测描边 一种是利用顶点法线向外扩展返回单色pass,使用正面裁剪 我用的第三种: pass {//剔除前 ...

最新文章

  1. python语言标号_Python 编码为什么那么蛋疼?
  2. Python之匿名函数
  3. 斯坦福2014机器学习笔记五----正则化
  4. C宏定义-SWAP的妙用
  5. 深入浅出 Java CMS 学习笔记
  6. Java基础:如何向控制台写输出
  7. 在线代理和缓存工具(转)
  8. .Net中加密解密相关知识
  9. linux服务器启动ftp连接
  10. ArrayUtils
  11. c语言11章谭浩强,谭浩强 C语言 第11章 结构体.ppt
  12. 十五秒破解“还原卡”
  13. java-pdf-itext7、itextpdf 生成pdf 文档 定制票据打印
  14. 查询oracle所有回收站,oracle 回收站
  15. 8.TypeScript入门之TS类型声明文件
  16. java课程设计模拟科学计算器_JAVA课程设计科学计算器
  17. math.floor java_Java Math floor、ceil、rint 及 round 用法
  18. Andriod Studio创建数据库并查看自己创建的数据库
  19. btrfs和ntfs linux5,如何选择文件系统EXT4、Btrfs 和 XFS
  20. 分布式光伏站远程监控组网解决方案

热门文章

  1. android studio 视屏播放器 MediaController
  2. 提取数据以及清洗数据
  3. 数据清洗:真值发现TruthFinder算法(附Python代码)
  4. Python Pillow (PIL) Image.save 保存为jpg图片压缩问题
  5. Linux设备驱动程序(二)——建立和运行模块
  6. tp-link无线ap服务器,TP-LINK电信定制版路由器和无线AP面板使用方法
  7. 每天学点说话技巧分享
  8. 唯品会如何实现连续30个季度盈利?
  9. Linux文件的切割与合并
  10. 新人如何从零开始学习Linux?