cb/assets/effect/snow/雪.effect
2025-12-24 16:21:14 +08:00

113 lines
2.5 KiB
Plaintext

// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
CCEffect %{
techniques:
- passes:
- vert: vs
frag: fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
texture: { value: white }
alphaThreshold: { value: 0.5 }
}%
CCProgram vs %{
precision highp float;
#include <cc-global>
#include <cc-local>
in vec3 a_position;
in vec4 a_color;
out vec4 v_color;
#if USE_TEXTURE
in vec2 a_uv0;
out vec2 v_uv0;
#endif
void main () {
vec4 pos = vec4(a_position, 1);
#if CC_USE_MODEL
pos = cc_matViewProj * cc_matWorld * pos;
#else
pos = cc_matViewProj * pos;
#endif
#if USE_TEXTURE
v_uv0 = a_uv0;
#endif
v_color = a_color;
gl_Position = pos;
}
}%
CCProgram fs %{
precision highp float;
#include <alpha-test>
#include <texture>
#include <cc-global>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D texture;
#endif
#define LAYERS 20
#define DEPTH .4
#define WIDTH .3
#define SPEED .3
#define DRIFT .2
#define DRIFT_PROBABILITY 0.6
#define iTime cc_time.x
void main () {
const mat3 p = mat3(13.323122,23.5112,21.71123,21.1212,28.7312,11.9312,21.8112,14.7212,61.3934);
vec2 uv = 500./1000. + vec2(1.,1.)*gl_FragCoord.xy / 1000.;
vec3 acc = vec3(0.0);
float dof = 5.*sin(iTime*.1);
for (int i=0;i<LAYERS;i++) {
float fi = float(i);
vec2 q = uv*(1.+fi*DEPTH);
// 根据概率决定雪花是否斜向飘落
float shouldDrift = step(DRIFT_PROBABILITY, fract(fi * 7.238917));
float driftAmount = shouldDrift * DRIFT * sin(iTime * 0.5 + fi * 1.5) * (1.0 + 0.5 * sin(fi * 3.7));
q += vec2(q.y*(WIDTH*mod(fi*7.238917,1.)-WIDTH*.5) + driftAmount, SPEED*iTime/(1.+fi*DEPTH*.03));
vec3 n = vec3(floor(q),31.189+fi);
vec3 m = floor(n)*.00001 + fract(n);
vec3 mp = (31415.9+m)/fract(p*m);
vec3 r = fract(mp);
vec2 s = abs(mod(q,1.)-.5+.9*r.xy-.45);
// 调整雪花大小范围,增加最小雪花尺寸
s += .008*abs(2.*fract(8.*q.yx)-1.);
float d = .5*max(s.x-s.y,s.x+s.y)+max(s.x,s.y)-.01;
float edge = .004+.04*min(.5*abs(fi-5.-dof),1.);
// 调整雪花大小变化范围,提高最小值
float sizeVariation = 0.9 + 0.3 * sin(fi * 2.1);
acc += vec3(smoothstep(edge,-edge,d)*(r.x/(1.+.02*fi*DEPTH)*sizeVariation));
}
float a = 0.;
if(acc.r+acc.g+acc.b>0.3){
a = acc.r+acc.g+acc.b;
}
gl_FragColor = vec4(vec3(acc*5.),a);
// gl_FragColor = o;
}
}%