文章目录
- 前言
- 一、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 depthCull Off ZWrite Off ZTest AlwaysPass{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 colorvec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));// Output to screenfragColor = 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);
}