基于Unity实现油画风格的着色器
// 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实现油画风格的着色器的更多相关文章
- 基于Unity实现像素化风格的着色器
Shader "MyShaderTest/SimplePixelationShader" { Properties { _MainTex ("Base (RGB)&quo ...
- 使用Shader Graph实现《塞尔达传说:旷野之息》风格的着色器
https://mp.weixin.qq.com/s/19Xq6wYuXP0gQJDvC9Fh0g
- Unity 渲染教程(二):着色器基础
转载:https://www.jianshu.com/p/7db167704056 这是关于渲染基础的系列教程的第二部分.这个渲染基础的系列教程的第一部分是有关矩阵的内容.在这篇文章中我们将编写我们的 ...
- Unity Shader着色器优化
https://mp.weixin.qq.com/s?__biz=MzU5MjQ1NTEwOA==&mid=2247493518&idx=1&sn=c51b92e9300bcf ...
- Unity3d之Shader编程:子着色器、通道与标签的写法 & 纹理混合
一.子着色器 Unity中的每一个着色器都包含一个subshader的列表,当Unity需要显示一个网格时,它能发现使用的着色器,并提取第一个能运行在当前用户的显示卡上的子着色器. 我们知道,子着色器 ...
- 【浅墨Unity3D Shader编程】之三 光之城堡篇:子着色器、通道与标签的写法 & 纹理混合
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1117/120.html 作者:毛星云 ...
- Unity3D - 图形性能优化:优化着色器载入时间
Unity官方文档之"图形性能优化-优化着色器载入时间"的翻译,E文链接. Optimizing Shader Load Time 优化着色器载入时间 Shaders are sm ...
- [Unity] Shader(着色器)输入输出和语义
在Unity5.x后, 已经支持了基于物理的光照模型,也就是常说的次时代引擎所必须具备的功能. 如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理 如果在Prope ...
- Unity 内置着色器(转)
Unity包括超过40种内置的shader. 标准着色器家族 Normal Shader Family 这些着色器都是Unity基本的着色器.适用于大多数的不透明物体,如果想要物体有透明.发光效果等, ...
随机推荐
- Java pdf转高清图片
为什么80%的码农都做不了架构师?>>> package com.hyb.kai.web.controller; import java.awt.image.BufferedIm ...
- DP 60题 -2 HDU1025 Constructing Roads In JGShining's Kingdom
Problem Description JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which ...
- U盘安装Proxmox VE(一)
转自我的个人博客:U盘安装Proxmox VE(一) 年前搞了个星际蜗牛B款机箱,利用手头之前海淘dq77kb组装了个四盘位的Server. 组装完毕后,直接在实体机安装了centos 7.使用这几个 ...
- Java并发编程实战 03互斥锁 解决原子性问题
文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...
- GoF23:工厂模式(Factory)
目录 GoF23:工厂模式(Factory) 工厂模式三种模式 简单工厂模式(静态工厂模式) 工厂方法模式 抽象工厂模式 举例说明 代码实现 GoF23:工厂模式(Factory) 核心本质: 实例化 ...
- 创造DotNet Core轻量级框架【二】
上一篇 创造DotNet Core轻量级框架[一] 10 题外话 上一篇文章感谢大家提出的各种小建议和各种讨论,但是在写文章的时候框架最最最基础的样子已经做出来了,所以大家的各种建议和意见我会在后续逐 ...
- 带你看看Java的锁(一)-ReentrantLock
前言 AQS一共花了5篇文章,对里面实现的核心源码都做了注解 也和大家详细描述了下,后面的几篇文字我将和大家聊聊一下AQS的实际使用,主要会聊几张锁,第一篇我会和大家聊下ReentrantLock 重 ...
- 计算机组成及系统结构-第十章 输入输出(I/O)系统
输入输出(I/O)系统 一.概述 1.输入输出设备的编址 2.设备控制器(I/O接口)的基本功能 3.I/O设备数据传送控制方式 二.程序中断输入输出方式 1.中断的定义 2.中断的作用 3.中断的产 ...
- HMM-前向后向算法(附python实现)
基本要素 状态 \(N\)个 状态序列 \(S = s_1,s_2,...\) 观测序列 \(O=O_1,O_2,...\) \(\lambda(A,B,\pi)\) 状态转移概率 \(A = \{a ...
- MongoDB介绍及开发指南
目录 一.MongoDB介绍 二.搭建MongoDB 三.Java With MongoDB 四.Spring Session MongoDB 五.MongoDB开发规范及示例 六.MongoDB + ...