// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/oilScreen" {
//------------------------------------【属性值】------------------------------------
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
_Distortion("_Distortion", Range(0.0, 1.0)) = 0.3
_ScreenResolution("_ScreenResolution", Vector) = (0., 0., 0., 0.)
_ResolutionValue("_ResolutionValue", Range(0.0, 5.0)) = 1.0
_Radius("_Radius", Range(0.0, 5.0)) = 2.0
} //------------------------------------【唯一的子着色器】------------------------------------
SubShader
{
//--------------------------------唯一的通道-------------------------------
Pass
{
//设置深度测试模式:渲染所有像素.等同于关闭透明度测试(AlphaTest Off)
ZTest Always //===========开启CG着色器语言编写模块===========
CGPROGRAM //编译指令: 指定着色器编译目标为Shader Model 3.0
#pragma target 3.0 //编译指令:告知编译器顶点和片段着色函数的名称
#pragma vertex vert
#pragma fragment frag //包含辅助CG头文件
#include "UnityCG.cginc" //外部变量的声明
uniform sampler2D _MainTex;
uniform float _Distortion;
uniform float4 _ScreenResolution;
uniform float _ResolutionValue;
uniform int _Radius; //顶点输入结构
struct vertexInput
{
float4 vertex : POSITION;//顶点位置
float4 color : COLOR;//颜色值
float2 texcoord : TEXCOORD0;//一级纹理坐标
}; //顶点输出结构
struct vertexOutput
{
half2 texcoord : TEXCOORD0;//一级纹理坐标
float4 vertex : SV_POSITION;//像素位置
fixed4 color : COLOR;//颜色值
}; //--------------------------------【顶点着色函数】-----------------------------
// 输入:顶点输入结构体
// 输出:顶点输出结构体
//---------------------------------------------------------------------------------
vertexOutput vert(vertexInput Input)
{
//【1】声明一个输出结构对象
vertexOutput Output; //【2】填充此输出结构
//输出的顶点位置为模型视图投影矩阵乘以顶点位置,也就是将三维空间中的坐标投影到了二维窗口
Output.vertex = UnityObjectToClipPos(Input.vertex);
//输出的纹理坐标也就是输入的纹理坐标
Output.texcoord = Input.texcoord;
//输出的颜色值也就是输入的颜色值
Output.color = Input.color; //【3】返回此输出结构对象
return Output;
} //--------------------------------【片段着色函数】-----------------------------
// 输入:顶点输出结构体
// 输出:float4型的颜色值
//---------------------------------------------------------------------------------
float4 frag(vertexOutput Input) : COLOR
{
//【1】根据设置的分辨率比值,计算图像尺寸
float2 src_size = float2(_ResolutionValue / _ScreenResolution.x, _ResolutionValue / _ScreenResolution.y); //【2】获取坐标值
float2 uv = Input.texcoord.xy; //【3】根据半径,计算出n的值
float n = float((_Radius + 1) * (_Radius + 1));; //【4】定义一些参数
float3 m0 = 0.0; float3 m1 = 0.0;
float3 s0 = 0.0; float3 s1 = 0.0;
float3 c; //【5】按半径Radius的值,迭代计算m0和s0的值
for (int j = -_Radius; j <= 0; ++j)
{
for (int i = -_Radius; i <= 0; ++i)
{
c = tex2D(_MainTex, uv + float2(i, j) * src_size).rgb;
m0 += c;
s0 += c * c;
}
} //【6】按半径Radius的值,迭代计算m1和s1的值
for (int j = 0; j <= _Radius; ++j)
{
for (int i = 0; i <= _Radius; ++i)
{
c = tex2D(_MainTex, uv + float2(i, j) * src_size).rgb;
m1 += c;
s1 += c * c;
}
} //【7】定义参数,准备计算最终的颜色值
float4 finalFragColor = 0.;
float min_sigma2 = 1e+2; //【8】根据m0和s0,第一次计算finalFragColor的值
m0 /= n;
s0 = abs(s0 / n - m0 * m0); float sigma2 = s0.r + s0.g + s0.b;
if (sigma2 < min_sigma2)
{
min_sigma2 = sigma2;
finalFragColor = float4(m0, 1.0);
} //【9】根据m1和s1,第二次计算finalFragColor的值
m1 /= n;
s1 = abs(s1 / n - m1 * m1); sigma2 = s1.r + s1.g + s1.b;
if (sigma2 < min_sigma2)
{
min_sigma2 = sigma2;
finalFragColor = float4(m1, 1.0);
} //【10】返回最终的颜色值
return finalFragColor;
} ENDCG
} }
}

在材质上赋予着色器之后将材质球贴敷到游戏对象上就能够看到油画效果,需要根据需求取调节材质球上的着色器各个参数,以应对不同的需求。

基于Unity实现油画风格的着色器的更多相关文章

  1. 基于Unity实现像素化风格的着色器

    Shader "MyShaderTest/SimplePixelationShader" { Properties { _MainTex ("Base (RGB)&quo ...

  2. 使用Shader Graph实现《塞尔达传说:旷野之息》风格的着色器

    https://mp.weixin.qq.com/s/19Xq6wYuXP0gQJDvC9Fh0g

  3. Unity 渲染教程(二):着色器基础

    转载:https://www.jianshu.com/p/7db167704056 这是关于渲染基础的系列教程的第二部分.这个渲染基础的系列教程的第一部分是有关矩阵的内容.在这篇文章中我们将编写我们的 ...

  4. Unity Shader着色器优化

    https://mp.weixin.qq.com/s?__biz=MzU5MjQ1NTEwOA==&mid=2247493518&idx=1&sn=c51b92e9300bcf ...

  5. Unity3d之Shader编程:子着色器、通道与标签的写法 & 纹理混合

    一.子着色器 Unity中的每一个着色器都包含一个subshader的列表,当Unity需要显示一个网格时,它能发现使用的着色器,并提取第一个能运行在当前用户的显示卡上的子着色器. 我们知道,子着色器 ...

  6. 【浅墨Unity3D Shader编程】之三 光之城堡篇:子着色器、通道与标签的写法 &amp; 纹理混合

    本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1117/120.html 作者:毛星云 ...

  7. Unity3D - 图形性能优化:优化着色器载入时间

    Unity官方文档之"图形性能优化-优化着色器载入时间"的翻译,E文链接. Optimizing Shader Load Time 优化着色器载入时间 Shaders are sm ...

  8. [Unity] Shader(着色器)输入输出和语义

    在Unity5.x后, 已经支持了基于物理的光照模型,也就是常说的次时代引擎所必须具备的功能. 如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理 如果在Prope ...

  9. Unity 内置着色器(转)

    Unity包括超过40种内置的shader. 标准着色器家族 Normal Shader Family 这些着色器都是Unity基本的着色器.适用于大多数的不透明物体,如果想要物体有透明.发光效果等, ...

随机推荐

  1. HR问了一句DB是啥?SQL是啥?DB是Database数据库,SQL是数据库语言! 然后呢? 数据库从入门到精通--入门必看!

    写在前面 本文的写作知识体系来源于我的数据库老师SDAU张承明,部分知识来自于网络,我呢对知识进行了细化和添加了自己的一些看法,并且加入了一些实例帮助理解,本文不是面向SQL高手写的,可以看作是数据库 ...

  2. 网络流--最大流--POJ 2139(超级源汇+拆点建图+二分+Floyd)

    Description FJ's cows really hate getting wet so much that the mere thought of getting caught in the ...

  3. 如何使用badboy录制一个脚本并成功的导入jmeter中?

    前言: 虽然,很多人已经不适用这种方式进行录制脚本了,因为不好维护.但是,还是有一些朋友在刚开始学习的过程中使用badboy. 可能有人会好奇了,人家五一都出去玩了,你在家学习吗?正巧前一阵有粉丝留言 ...

  4. 自己封装函数,实现数组的内置方法indexOf的功能

    在学习或开发过程中,经常会有朋友需要使用到一个数组方法-indexOf,这里我们先来谈谈它的功能:返回指定数据所在的索引,如果没有则返回-1. 那么我们在使用时通常是直接使用它这个数组内置方法 今天这 ...

  5. MES系统介绍(一)

    由于本人从事的行业主要为Mes行业,所以这里准备介绍一下Mes系统的基础概念和实际运用,并且以自己做过的一个实际案例(包括代码)来详细描述自己对Mes系统的认识,帮助小白扫盲,望大神勿喷. MES系统 ...

  6. java运行时跟编译时的区别,欢迎大家指正

    个人博客地址:https://blog.csdn.net/qq_41907991 关于java运行时及编译时期的区别: 首先我们要了解编译以及运行的概念: 编译就是指,编译器帮你把源码翻译成机器能识别 ...

  7. GitHub上Asp.Net Core的源代码

    记录,备查. https://github.com/aspnet/AspNetCore/tree/master/src

  8. RHCSA 第一题 修改root密码

    题目要求 请修改系统的root帐号密码为redhat,确保能够使用root帐号登录系统.说明:server0 的IP为172.25.0.11/24desktop0的IP为172.25.0.10/24 ...

  9. QtCreator MSVC 搭建 Debugger

    QtCreatorForWindows搭建Debugger QtCreator for windows选择mingw或者msvc: qt-opensource-windows-x86-msvc2015 ...

  10. GP1UM26(78)1RK远程红外遥控接收IC数据手册学习

    1.Features 该系列IC具有多种BMP带通频率可供选择,典型的GP1UM261RK带通频率为38KHz,内部的前置放大器等放大电路工作频率均为38KHz. Compact紧凑型,体积小 2.i ...