File: matrix-rain.effect

package info (click to toggle)
obs-retro-effects 1.0.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,984 kB
  • sloc: ansic: 7,150; sh: 153; makefile: 27; cpp: 16
file content (129 lines) | stat: -rw-r--r-- 4,316 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "noise-functions.effect"

// Curve for fade off
// Sliders for bloom:  bloom radius, intensity, and threshold

// Ability for user to make their own font texture
// Source Sampling for colors
// Angle of attack

#define EPS 1.e-6
uniform float4x4 ViewProj;               // No input
uniform texture2d image;                 // No input
uniform texture2d font_image;            // Dropdown
uniform float2 uv_size;                  // No input
uniform float2 font_texture_size;        // Calculated from dd
uniform float font_texture_num_chars;    // Calculated from dd
uniform float scale;                     // INPUT
uniform float noise_shift;               // INPUT
uniform float local_time;                // Comes from time/calcuated
uniform bool colorize;                   // INPUT
uniform float4 text_color;               // INPUT
uniform float4 background_color;         // INPUT
uniform float min_brightness;
uniform float max_brightness;
uniform float min_fade_value;
uniform float active_rain_brightness;
uniform float fade_distance;

sampler_state textureSampler{
    Filter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

float gray(float3 col)
{
	// Standard RGB to luminance calculation
	return col.r * 0.299 + col.g * 0.587 + col.b * 0.114;
}

struct VertData
{
	float4 pos : POSITION;
	float2 uv : TEXCOORD0;
};

VertData mainTransform(VertData v_in)
{
	v_in.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
	return v_in;
}

float4 mainImage(VertData v_in) : TARGET
{
	float char_height = font_texture_size.y;
	float char_width = font_texture_size.x / font_texture_num_chars;

	float2 coord = v_in.uv * uv_size;

	// UV Coordinate of center of box where character will go.
	float2 uv = float2(floor(coord.x / char_width / scale) * char_width * scale, floor(coord.y / char_height / scale) * char_height * scale) / uv_size.xy;
	float char_noise = hash31(float3(uv * uv_size + float2(noise_shift,  0.0), 1.0));
	float rotation_speed = hash31(float3(uv * uv_size, 10.0));
	
	float noise_shift_u = floor(noise_shift / char_width / scale) * char_width * scale / uv_size.x;
	float2 sub_pos = float2(frac(coord.x / scale / char_width), frac(coord.y / scale / char_height));

	float2 noise = whiteNoise2D((uv - float2(noise_shift_u, 0.0)) * float2(uv_size.x, 1), 12345u);
	//float2 noise = hash32(float3(uv - float2(noise_shift_u, 0.0) * float2(uv_size.x, 1), 0.0));
	
	float rain_speed = (1.0 + noise.x * 7.0);
	float rain_phase = noise.y;

	float t = local_time;
	float rainY = frac(t / rain_speed);

	float rainY_px = rainY * uv_size.y;
	float rain_uv = (floor(rainY_px / char_height / scale) * char_height * scale)/uv_size.y;
	float rain = abs(uv.y - rain_uv) < 0.002 ? 1.0 : 0.0;
	float rain_scale = 1.0;

	if (uv.y >= rain_uv)
	{
		rain_scale = uv.y - rain_uv;
	}
	else
	{
		rain_scale = 1.0 - (rain_uv - uv.y);
	}

	rain_scale = rain_scale / fade_distance - (1.0 / fade_distance - 1.0);
	
	rain_scale = rain_scale * (1.0 - min_fade_value) + min_fade_value;
	rotation_speed = rotation_speed * (9.0 * (rain) + 1.0);

	
	float4 col = image.Sample(textureSampler, uv);
	if (col.a < EPS)
	{
		return float4(0.0, 0.0, 0.0, 0.0);
	}

	float g = min(gray(col.rgb), 0.99);

	// g -> [0, 1]
	// range -> [0.2, 0.8]
	rain_scale *= (g / (max_brightness - min_brightness) + min_brightness);
	float char_uv = fmod((floor(char_noise * float(font_texture_num_chars)) + (rotation_speed * local_time - frac(rotation_speed * local_time))), font_texture_num_chars) / float(font_texture_num_chars);

	float2 sampleUv = float2(char_uv, 0.0) + float2(1.0 / float(font_texture_num_chars), 1.0) * sub_pos;

	float4 cha = font_image.Sample(textureSampler, sampleUv);
	cha = float4(1.0 - cha.r, 1.0 - cha.g, 1.0 - cha.b, 1.0 - gray(cha.rgb));
	float4 pixel = colorize ? float4(col.rgb / max(col.r, max(col.g, col.b)), col.a) : text_color;
	pixel = rain > 0.5 ? (pixel * (1.0 - active_rain_brightness) + float4(1.0, 1.0, 1.0, pixel.a) * active_rain_brightness) : pixel;
	rain_scale = rain > 0.5 ? 1.0 : rain_scale;
	return cha * rain_scale * pixel + (1.0 - cha * rain_scale) * background_color;
	//return cha * (float4(rain_scale, rain_scale, rain_scale, 1.0) * pixel) + (1.0 - cha) * background_color;
}

technique Draw
{
	pass
	{
		vertex_shader = mainTransform(v_in);
		pixel_shader = mainImage(v_in);
	}
}