Unity3D复刻UnityShader 之 ShaderToy - Bubbles
背景:
突然发现了一个Shader相关的神仙网站,之前对Shader也不了解,准备把能自己搬得,都用Unity实现[复刻]一遍…
官方地址/参考资料:
官网地址:https://www.shadertoy.com/view/4dl3zn
参考:https://www.freesion.com/article/2242713762/
ShaderToy-Bubbles原始代码:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = -1.0 + 2.0*fragCoord.xy / iResolution.xy;
uv.x *= iResolution.x / iResolution.y;
vec3 color = vec3(0.8 + 0.2*uv.y);
for( int i=0; i<40; i++ )
{
float pha = sin(float(i)*546.13+1.0)*0.5 + 0.5;
float siz = pow( sin(float(i)*651.74+5.0)*0.5 + 0.5, 4.0 );
float pox = sin(float(i)*321.55+4.1) * iResolution.x / iResolution.y;
float rad = 0.1 + 0.5*siz;
vec2 pos = vec2( pox, -1.0-rad + (2.0+2.0*rad)*mod(pha+0.1*iTime*(0.2+0.8*siz),1.0));
float dis = length( uv - pos );
vec3 col = mix( vec3(0.94,0.3,0.0), vec3(0.1,0.4,0.8), 0.5+0.5*sin(float(i)*1.2+1.9));
float f = length(uv-pos)/rad;
f = sqrt(clamp(1.0-f*f,0.0,1.0));
color -= col.zyx *(1.0-smoothstep( rad*0.95, rad, dis )) * f;
}
color *= sqrt(1.5-0.5*length(uv));
fragColor = vec4(color,1.0);
}
Unity复刻开始
核心显示类:
using System;
using UnityEngine;
[ExecuteInEditMode]
public class ShaderToy : MonoBehaviour
{
public int horizontalResolution = 320;
public int verticalResolution = 240;
public Shader shaderToy;
private Material shaderToyMaterial = null;
public Material material
{
get
{
shaderToyMaterial = CheckShaderAndCreateMaterial(shaderToy, shaderToyMaterial);
return shaderToyMaterial;
}
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
RenderTexture scaled = RenderTexture.GetTemporary(horizontalResolution, verticalResolution);
Graphics.Blit(source, scaled, material);
Graphics.Blit(scaled, destination);
RenderTexture.ReleaseTemporary(scaled);
}
protected Material CheckShaderAndCreateMaterial(Shader shader, Material material)
{
if (shader == null)
{
return null;
}
if (shader.isSupported && material && material.shader == shader)
return material;
if (!shader.isSupported)
{
return null;
}
else
{
material = new Material(shader);
material.hideFlags = HideFlags.DontSave;
if (material)
return material;
else
return null;
}
}
}
核心unity shader:
Shader "Custom/Bubbles" {
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct v2f{
float4 position : SV_POSITION;
};
v2f vert(float4 v:POSITION) : SV_POSITION {
v2f o;
o.position = UnityObjectToClipPos (v);
return o;
}
fixed4 frag(v2f i) : SV_Target {
float2 uv = -1.0 + 2.0*i.position.xy/ _ScreenParams.xy;
uv.x *= _ScreenParams.x/ _ScreenParams.y ;
fixed4 outColour = fixed4(0.8+0.2*uv.y,0.8+0.2*uv.y,0.8+0.2*uv.y,1);
for (int i = 0; i < 40; i++) {
float pha = sin(float(i)*546.13+1.0)*0.5 + 0.5;
float siz = pow( sin(float(i)*651.74+5.0)*0.5 + 0.5, 4.0 );
float pox = sin(float(i)*321.55+4.1);
float rad = 0.1 + 0.5*siz;
float2 pos = float2( pox, -1.0-rad + (2.0+2.0*rad)*fmod(pha+0.1*_Time.y*(0.2+0.8*siz),1.0));
float dis = length(uv-pos);
float3 col = lerp( float3(0.94,0.3,0.0), float3(0.1,0.4,0.8), 0.5+0.5*sin(float(i)*1.2+1.9));
col+= 8.0*smoothstep( rad*0.95, rad, dis );
float f = length(uv-pos)/rad;
f = sqrt(clamp(1.0-f*f,0.0,1.0));
outColour.rgb -= col.zyx *(1.0-smoothstep( rad*0.95, rad, dis )) * f;
}
outColour *= sqrt(1.5-0.5*length(uv));
return outColour;
}
ENDCG
}
}
}
复刻结束,展示效果:
ShaderToy-Bubbles效果:

Unity-Bubbles效果

github完整项目地址:
https://github.com/zld126126/MyUnity/tree/main/MyShaderToy/Assets/MyExamples/Bubbles
|