"Optical Stream " shader(.effect)

一个Optical Stream 效果
使用cocos creator 3.10 版本
output

CCEffect %{
	  techniques: 
    - 
      passes: 
        - 
          vert: sprite-vs:vert
          frag: sprite-fs:frag
          depthStencilState: 
            depthTest: false
            depthWrite: false
          blendState: 
            targets: 
              - 
                blend: true
                blendSrc: src_alpha
                blendDst: one_minus_src_alpha
                blendDstAlpha: one_minus_src_alpha
          rasterizerState: 
            cullMode: none
          properties: 
            iResolution: 
              value: 
                - 960
                - 640
            iMouse: 
              value: 
                - 0.5
                - 0.5
                - 0.5
                - 0.5
            alphaThreshold: 
              value: 0.5

}%

CCProgram sprite-vs %{
	precision highp float;
	#include <cc-global>
	#if USE_LOCAL
	  #include <cc-local>
	#endif
	#if SAMPLE_FROM_RT
	  #include <common>
	#endif
	in vec3 a_position;
	in vec2 a_texCoord;
	in vec4 a_color;
  
	out vec4 color;
	out vec2 uv0;
  
	vec4 vert () {
	  vec4 pos = vec4(a_position, 1);
  
	  #if USE_LOCAL
		pos = cc_matWorld * pos;
	  #endif
  
	  #if USE_PIXEL_ALIGNMENT
		pos = cc_matView * pos;
		pos.xyz = floor(pos.xyz);
		pos = cc_matProj * pos;
	  #else
		pos = cc_matViewProj * pos;
	  #endif
  
	  uv0 = a_texCoord;
	  #if SAMPLE_FROM_RT
		CC_HANDLE_RT_SAMPLE_FLIP(uv0);
	  #endif
	  color = a_color;
  
	  return pos;
	}
}%

CCProgram sprite-fs %{
	precision highp float;
	#include <embedded-alpha>
	#include <alpha-test>
	#include <cc-global>
  
	in vec4 color;
  
	#if USE_TEXTURE
	  in vec2 uv0;
	  #pragma builtin(local)
	  layout(set = 2, binding = 10) uniform sampler2D cc_spriteTexture;
	#endif

	uniform Uniforms {
			vec4 iMouse;
	vec2 iResolution;

  	};
	
	const float PI = 3.1415926;
	vec3 rgb2hsv(vec3 hsv)
	{
		vec4 t = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
		vec3 p = abs(fract(vec3(hsv.x) + t.xyz) * 6.0 - vec3(t.w));
		return hsv.z * mix(vec3(t.x), clamp(p - vec3(t.x), 0.0, 1.0), hsv.y);
	}
	mat2 rotate(float a)
	{
		float s = sin(a);
		float c = cos(a);
		return mat2(
			c, -s,
			s, c
		);
	}
	float rand(vec4 co)
	{
		return fract(sin(dot(co, vec4(12.9898, 78.233, 15.2358, 29.23851))) * 43758.5453);
	}
	float groundDist(vec3 pos)
	{
		pos.y += sin(pos.z * 0.2 + pos.x + cc_time[0] * 10.0) * 0.5;
		pos.x = mod(pos.x, 4.0) - 2.0;
		return length(pos.yx);
	}
	float particleDist(vec3 pos)
	{
		pos += cross(sin(pos * 0.05 + cc_time[0]), cos(pos * 0.05 + cc_time[0])) * 3.0;
		pos.z += cc_time[0] * 200.0;
		vec3 id = floor(pos / 16.0);
		pos = mod(pos, 16.0) - 8.0;
		pos += vec3(rand(vec4(id, 0.0)), rand(vec4(id, 1.0)), rand(vec4(id, 2.0))) * 10.0 - 5.0;
		return max(length(pos.yx), abs(pos.z) - 2.0);
	}
	float skyDist(vec3 pos)
	{
		pos.z += cc_time[0] * 50.0;
		vec3 id = floor(pos / 50.0);
		vec3 t = cc_time[0] * vec3(0.0125, 0.25, 0.5);
		vec3 a = vec3(rand(vec4(id, floor(t.x))), rand(vec4(id + 10.0, floor(t.y))), rand(vec4(id + 20.0, floor(t.z))));
		vec3 b = vec3(rand(vec4(id, floor(t.x + 1.0))), rand(vec4(id + 10.0, floor(t.y + 1.0))), rand(vec4(id + 20.0, floor(t.z + 1.0))));
		vec3 c = mix(a, b, pow(fract(t), vec3(1.0 / 4.0)));
		float s = sign(mod(id.x + id.y + id.z + 0.5, 2.0) - 1.0);
		vec3 u = cc_time[0] / 3.0 + vec3(1.0, 2.0, 3.0) / 3.0;
		vec3 d = floor(u);
		vec3 e = floor(u + 1.0);
		vec3 f = mix(d, e, pow(fract(u), vec3(1.0 / 8.0)));
		pos = mod(pos, 50.0) - 25.0;
		for (int i = 0; i < 3; ++i)
		{
			pos.yz = rotate(f.x * PI / 2.0 * s) * pos.yz;
			pos.xz = rotate(f.y * PI / 2.0 * s) * pos.xz;
			pos.xy = rotate(f.z * PI / 2.0 * s) * pos.xy;
			pos = abs(pos);
			pos -= (c * 12.0);
			pos *= 2.0;
			if (pos.x > pos.z) pos.xz = pos.zx;
			if (pos.y > pos.z) pos.yz = pos.zy;
			if (pos.x < pos.y) pos.xy = pos.yx;
		}
		return length(pos.xz) / 8.0;
	}
	float dist(vec3 pos)
	{
		float d = 3.402823466E+38;
		d = min(d, groundDist(pos));
		d = min(d, skyDist(pos));
		return d;
	}
	vec3 calcNormal(vec3 pos)
	{
		vec2 ep = vec2(0.001, 0.0);
		return normalize(vec3(
			dist(pos + ep.xyy) - dist(pos - ep.xyy),
			dist(pos + ep.yxy) - dist(pos - ep.yxy),
			dist(pos + ep.yyx) - dist(pos - ep.yyx)
		));
	}
	vec3 calcColor(vec3 pos)
	{
		return rgb2hsv(vec3(pos.x * 0.04 + cc_time[0], 1, 1));
	}
	vec3 march(vec3 pos, vec3 dir)
	{
		vec3 color = vec3(0.0, 0.0, 0.0);
		for (int i = 0; i < 32; ++i)
		{
			float d = dist(pos);
			pos += dir * d * 0.9;
			color += max(vec3(0.0), 0.02 / d * calcColor(pos));
		}
		return color;
	}
	vec3 marchParticle(vec3 pos, vec3 dir)
	{
		vec3 color = vec3(0.0, 0.0, 0.0);
		for (int i = 0; i < 32; ++i)
		{
			float d = particleDist(pos);
			pos += dir * d * 0.9;
			color += max(vec3(0.0), 0.005 / d * vec3(1.0, 1.0, 1.0));
		}
		return color;
	}
	vec4 frag() 
	{
		vec4 ssr_frag_out;
		vec2 p = (gl_FragCoord.xy * 2.0 - iResolution.xy) / iResolution.y;
		vec3 pos = vec3(0, 0.0, -10);
		vec3 dir = normalize(vec3(p, 1.0));
		dir.yz = rotate(-0.5) * dir.yz;
		pos.yz = rotate(-0.5) * pos.yz;
		dir.xz = rotate(sin(cc_time[0]) * 0.3) * dir.xz;
		pos.xz = rotate(sin(cc_time[0]) * 0.3) * pos.xz;
		dir.xy = rotate(0.1 + sin(cc_time[0] * 0.7) * 0.1) * dir.xy;
		pos.xy = rotate(0.1 + sin(cc_time[0] * 0.7) * 0.1) * pos.xy;
		vec3 color = vec3(0, 0, 0) * length(p.xy) * sin(cc_time[0] * 10.0);
		color += march(pos, dir);
		color += marchParticle(pos, dir);
		ssr_frag_out = vec4(color, 1.0);

			return ssr_frag_out;
	}
  }%

链接

1赞