UnityShader入门精要——素描效果渲染
Shader "Unity Shaders Book/Chapter 14/Hatching" {Properties {_Color ("Color Tint", Color) = (1, 1, 1, 1)_TileFactor ("Tile Factor", Float) = 1 //纹理平铺系数,数值越大,素描线条越密集_Outline ("Outline", Range(0, 1)) = 0.1_Hatch0 ("Hatch 0", 2D) = "white" {}_Hatch1 ("Hatch 1", 2D) = "white" {}_Hatch2 ("Hatch 2", 2D) = "white" {}_Hatch3 ("Hatch 3", 2D) = "white" {}_Hatch4 ("Hatch 4", 2D) = "white" {}_Hatch5 ("Hatch 5", 2D) = "white" {}}SubShader {Tags { "RenderType"="Opaque" "Queue"="Geometry"}//调用渲染轮廓线的PassUsePass "Unity Shaders Book/Chapter 14/Toon Shading/OUTLINE"Pass {Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag #pragma multi_compile_fwdbase#include "UnityCG.cginc"#include "Lighting.cginc"#include "AutoLight.cginc"#include "UnityShaderVariables.cginc"fixed4 _Color;float _TileFactor;sampler2D _Hatch0;sampler2D _Hatch1;sampler2D _Hatch2;sampler2D _Hatch3;sampler2D _Hatch4;sampler2D _Hatch5;struct a2v {float4 vertex : POSITION;float4 tangent : TANGENT; float3 normal : NORMAL; float2 texcoord : TEXCOORD0; };struct v2f {float4 pos : SV_POSITION;float2 uv : TEXCOORD0;fixed3 hatchWeights0 : TEXCOORD1;fixed3 hatchWeights1 : TEXCOORD2;float3 worldPos : TEXCOORD3;SHADOW_COORDS(4)};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.texcoord.xy * _TileFactor;fixed3 worldLightDir = normalize(WorldSpaceLightDir(v.vertex));fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);fixed diff = max(0, dot(worldLightDir, worldNormal));o.hatchWeights0 = fixed3(0, 0, 0);o.hatchWeights1 = fixed3(0, 0, 0);float hatchFactor = diff * 7.0;if (hatchFactor > 6.0) {// Pure white, do nothing} 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;}o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;TRANSFER_SHADOW(o);return o; }fixed4 frag(v2f i) : SV_Target { fixed4 hatchTex0 = tex2D(_Hatch0, i.uv) * i.hatchWeights0.x;fixed4 hatchTex1 = tex2D(_Hatch1, i.uv) * i.hatchWeights0.y;fixed4 hatchTex2 = tex2D(_Hatch2, i.uv) * i.hatchWeights0.z;fixed4 hatchTex3 = tex2D(_Hatch3, i.uv) * i.hatchWeights1.x;fixed4 hatchTex4 = tex2D(_Hatch4, i.uv) * i.hatchWeights1.y;fixed4 hatchTex5 = tex2D(_Hatch5, i.uv) * i.hatchWeights1.z;fixed4 whiteColor = fixed4(1, 1, 1, 1) * (1 - i.hatchWeights0.x - i.hatchWeights0.y - i.hatchWeights0.z - i.hatchWeights1.x - i.hatchWeights1.y - i.hatchWeights1.z);fixed4 hatchColor = hatchTex0 + hatchTex1 + hatchTex2 + hatchTex3 + hatchTex4 + hatchTex5 + whiteColor;UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);return fixed4(hatchColor.rgb * _Color.rgb * atten, 1.0);}ENDCG}}FallBack "Diffuse"
}
顶点着色器:
我们首先对顶点进行了基本的坐标变换。然后,使用_TileFactor 得到了纹理采样坐标。在计算6张纹理的混合权重之前,我们首先需要计算逐顶点光照。因此,我们使用世界空间下的光照方向和法线方向得到漫反射系数diff。之后,我们把权重值初始化为0,并把diff缩放到[0,7]范围,得到hatchFactor。我们把[0, 7]的区间均匀划分为7个子区间,通过判断hatchFactor所处的子区间来计算对应的纹理混合权重。最后,我们计算了顶点的世界坐标,并使用TRANSFER SHADOW宏来计算阴影纹理的采样坐标。
//每一位存储一张图的权重,共六张图
o.hatchWeights0 = fixed3(0, 0, 0);
o.hatchWeights1 = fixed3(0, 0, 0);
//漫反射系数越大,说明该部分越亮,素描线条越稀疏
if (hatchFactor > 6.0) {// Pure white, do nothing} else if (hatchFactor > 5.0) {o.hatchWeights0.x = hatchFactor - 5.0; //大于5的部分分配给第一张图} else if (hatchFactor > 4.0) {o.hatchWeights0.x = hatchFactor - 4.0; //大于4的部分分配给第一张图o.hatchWeights0.y = 1.0 - o.hatchWeights0.x; //其余部分分配给第二张图} else if (hatchFactor > 3.0) {o.hatchWeights0.y = hatchFactor - 3.0; //大于3的部分分配给第二张图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;}
片元着色器:
当得到了6六张纹理的混合权重后,我们对每张纹理进行采样并和它们对应的权重值相乘得到每张纹理的采样颜色。我们还计算了纯白在渲染中的贡献度,这是通过从1中减去所有6张纹理的权重来得到的。这是因为素描中往往有留白的部分,因此我们希望在最后的渲染中光照最亮的部分是纯白色的。最后,我们混合了各个颜色值,并和阴影值atten、模型颜色Color 相乘后返回最终的渲染结果。
UnityShader入门精要——素描效果渲染相关推荐
- 《UnityShader入门精要》总结(1)理论篇
紫色:大类概念或简短有力的总结 蓝色:细分概念或重要部分 红色:重要的补充注释 第二章:渲染流程与流程分工 渲染的流程分三个阶段: 应用阶段(开发者控制阶段) 由开发者全权进行管理,控制场景内摄像机位 ...
- UnityShader入门精要-9
目录 1. Unity的渲染路径 前向渲染路径 Unity中的前向渲染 延迟渲染 Unity的光源类型 Unity的光照衰减 Unity的阴影 1. Unity的渲染路径 Unity 5.0之前,有3 ...
- UnityShader入门精要——Unity中的渲染优化技术(三)
减少需要处理的顶点数目 1 优化几何体 尽可能减少模型中三角面片的数目,一些对于模型没有影响.或是肉眼非常难察觉到区别的顶点都要尽可能去掉. 移除不必要的硬边以及纹理衔接,避免边界平滑和纹理分离. 2 ...
- UnityShader入门精要-渲染纹理 镜子 玻璃 效果
通常模式是一个摄像机的渲染结果输出到颜色缓冲内并显示到屏幕上,现代GPU允许我们把场景渲染到一个中间缓冲(渲染目标纹理RTT),与之相关的是多重渲染目标MRT允许我们把场景同时渲染到多个渲染目标中而不 ...
- UnityShader入门精要——卡通风格渲染
卡通风格是游戏中常见的一种渲染风格.使用这种风格的游戏画面通常有一些共有的特点,例如物体都被黑色的线条描边,以及分明的明暗变化等. 轮廓线渲染 ●基于观察角度和表面法线的轮廓线渲染.这种方法使用视角方 ...
- UnityShader入门精要——Unity中的渲染优化技术(二)
减少DrawCall数目 最常见的优化技术--批处理.实现原理为减少渲染每一帧所需的drawcall数目.使用同一个材质的物体可以一起处理. 优点 缺点 动态批处理 切处理都是Unity 自动完成的, ...
- UnityShader入门精要-3.3 UnityShader的结构
一个UnityShader的基础结构如下所示: Shader "ShaderName"{Properties{//属性 } SubShader{//显卡A使用的子着色器 }SubS ...
- UnityShader入门精要笔记1——顶点/片元着色器结构与BRDF(基本光照模型)——实现漫反射
文章目录 BRDF(基本光照模型) 实现漫反射 光线强度的计算 好现在开始写Shader 新建Shader 添加一个Properties语义块 添加SubShader和Pass. 使用CG/HLSL语 ...
- UnityShader入门精要——运动模糊
运动模糊是真实世界中的摄像机的一种效果.如果在摄像机曝光时,拍摄场景发生了变化,就会产生模糊的画面. 运动模糊的实现有多种方法.一种实现方法是利用一块累积缓存(accumulation buffer ...
最新文章
- QT开发(五十)——QT串口编程基础
- 《移动平台开发》第3周学习总结
- 汇编语言--通用寄存器
- (转)ubuntu 文件系统
- 牛人推荐机器学习网站
- [R]R语言中的%%和%.%
- 【JAVA基础篇】Socket编程
- 玻尔兹曼分布涨落_科学网—高分子统计物理漫谈-涨落耗散定理-2 - 苗兵的博文...
- 对XML文件进行的添加、删除、修改、查询操作。
- usermod命令,用户密码管理,makpasswd
- allavsoft mac版:支持从各种视频分享网站下载视频
- 线性代数第六版答案(全)
- 4k显卡视频测试软件,4K分辨率下体验测试
- 基于模糊集的图像增强
- 自己组装电脑配置清单 2021年组装电脑配置清单推荐
- 空间坐标系对应EPSG编号
- 上海市新能源汽车分时租赁规划策略研究
- 备份恢复Lesson 10. Restore and Recovery Concepts
- 【保姆级!完整详细!】小米路由器3 刷openwrt固件并连接上校园网
- python 实现MR
热门文章
- Java入侵检测系统(一)
- 【Unity游戏开发基础】如何在游戏菜单中实现下拉列表选择画面质量
- 性能调优实践-提升cpu利用率
- outlook 发送邮件没有“附件”、“主题”提醒
- php 汉字转拼音接口,php将汉字转化为拼音和获取ip归属地接口
- 自己制做立体影像! 揭秘你不知道的3D
- 华为机试在线训练--牛客网(python)第四部分
- 华为机考108题(c++)(31-40)
- 最新KTV娱乐微信小程序源码v3.5.15版
- 停车场系统无法连接服务器,手动挡停车场 联机版无法连接服务器是什么原因...