文章目录
- 前言
- 一、ShaderToy网站
- 二、ShaderToy基本框架
- 1、我们可以在ShaderToy网站中,这样看用到的GLSL文档
- 2、void mainImage 是我们的程序入口,类似于片断着色器
- 3、fragColor作为输出变量,为屏幕每一像素的颜色,alpha一般赋值为 1
- 4、fragCoord作为输入变量
- 三、怎么把ShaderToy的Shader转化为Unity中的Shader
- 1、使用到的代码基础模板
- 2、逐条把ShaderToy代码转化到Unity中Shader
- 三、最终效果
前言
我们在之前的文章中,学习了很多的Shadar知识。但是,我们没有自己实现一些奇特的效果。而ShaderToy是一个国外的网站,上面刚好有很多Shader大神实现的效果,提供给我们借鉴。我们在这篇文章中了解一下ShaderToy。
一、ShaderToy网站
- ShaderToy
我们可以借鉴这个网站中的 视觉灵感 和 算法 来提升自我
- 我们来看看iq大神的作品:
ShaderToy本质使用的是GLSL,我们可以查看OpenGL的官方文档来学习
二、ShaderToy基本框架
1、我们可以在ShaderToy网站中,这样看用到的GLSL文档
2、void mainImage 是我们的程序入口,类似于片断着色器
3、fragColor作为输出变量,为屏幕每一像素的颜色,alpha一般赋值为 1
4、fragCoord作为输入变量
三、怎么把ShaderToy的Shader转化为Unity中的Shader
因为ShaderToy的操作是类似于,直接对屏幕上的图像做处理并且覆盖。
处理起来和Unity中的后处理很像,所以我们可以直接使用后处理脚本框架来实现
-
Unity中后处理简介
-
Unity中后处理 脚本 和 Shader
1、使用到的代码基础模板
因为ShaderToy是直接对屏幕像素进行覆盖修改。
所以,我们的功能主要在Shader的片元着色器中完成,并且不需要外部传入属性
- C#:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//后处理脚本
[ExecuteInEditMode]
public class P2_8 : MonoBehaviour
{
public Shader PostProcessingShader;
private Material mat;
public Material Mat
{
get
{
if (PostProcessingShader == null)
{
Debug.LogError("没有赋予Shader");
return null;
}
if (!PostProcessingShader.isSupported)
{
Debug.LogError("当前Shader不支持");
return null;
}
//如果材质没有创建,则根据Shader创建材质,并给成员变量赋值存储
if (mat == null)
{
Material _newMaterial = new Material(PostProcessingShader);
_newMaterial.hideFlags = HideFlags.HideAndDontSave;
mat = _newMaterial;
return _newMaterial;
}
return mat;
}
}
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source,destination,Mat);
}
}
- Shader:
Shader "MyShader/P2_8"
{
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return 1;
}
ENDCG
}
}
}
2、逐条把ShaderToy代码转化到Unity中Shader
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
// Output to screen
fragColor = vec4(col,1.0);
}
-
i 开头的变量都是着色器的内部输入变量
-
fragCoord:输入图像的像素 所在屏幕中的位置 x(宽)、y(高)
-
iResolution.xy : x代表屏幕宽度,y代表屏幕高度
-
fragCoord/iResolution.xy :得到一个归一化后(0,1)的值
等效: i.uv -
iTime:是一个一维变量,单位为秒
等效:_Time.y -
fragColor:输出变量
等效:return col
转化后的片元着色器:
fixed4 frag (v2f i) : SV_Target
{
//vec2 uv = fragCoord/iResolution.xy;
//i.uv
//vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
float3 col = 0.5 + 0.5*cos(_Time.y + i.uv.xyx + fixed3(0,2,4));
//fragColor = vec4(col,1.0);
return fixed4(col,1);
}