Skip to content

Commit

Permalink
Add clock_digital_led.shader
Browse files Browse the repository at this point in the history
  • Loading branch information
exeldro committed Jan 14, 2025
1 parent 8ff1d7b commit b73e2e8
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 8 deletions.
176 changes: 176 additions & 0 deletions data/examples/clock_digital_led.shader
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// based on https://www.shadertoy.com/view/MdfGzf
// cmarangu has linked all 7 segments in his comments
// https://www.shadertoy.com/view/3dtSRj

#ifndef OPENGL
#define mod(x,y) (x - y * floor(x / y))
#endif

uniform int timeMode<
string label = "Time mode";
string widget_type = "select";
int option_0_value = 0;
string option_0_label = "Time";
int option_1_value = 1;
string option_1_label = "Enable duration";
int option_2_value = 2;
string option_2_label = "Active duration";
int option_3_value = 3;
string option_3_label = "Show duration";
int option_4_value = 4;
string option_4_label = "Load duration";
> = 0;

uniform bool showMatrix = false;
uniform bool showOff = false;
uniform bool ampm = false;
uniform float4 ledColor = {1.0,0,0,1.0};
uniform int offsetHours = 0;
uniform int offsetSeconds = 0;

float segment(float2 uv, bool On)
{
if (!On && !showOff)
return 0.0;

float seg = (1.0-smoothstep(0.08,0.09+float(On)*0.02,abs(uv.x)))*
(1.0-smoothstep(0.46,0.47+float(On)*0.02,abs(uv.y)+abs(uv.x)));

//Fiddle with lights and matrix
//uv.x += sin(elapsed_time*60.0*6.26)/14.0;
//uv.y += cos(elapsed_time*60.0*6.26)/14.0;

//led like brightness
if (On){
seg *= (1.0-length(uv*float2(3.8,0.9)));//-sin(elapsed_time*25.0*6.26)*0.04;
} else {
seg *= -(0.05+length(uv*float2(0.2,0.1)));
}
return seg;
}

float sevenSegment(float2 uv,int num)
{
float seg= 0.0;
seg += segment(uv.yx+float2(-1.0, 0.0),num!=-1 && num!=1 && num!=4 );
seg += segment(uv.xy+float2(-0.5,-0.5),num!=-1 && num!=1 && num!=2 && num!=3 && num!=7);
seg += segment(uv.xy+float2( 0.5,-0.5),num!=-1 && num!=5 && num!=6 );
seg += segment(uv.yx+float2( 0.0, 0.0),num!=-1 && num!=0 && num!=1 && num!=7 );
seg += segment(uv.xy+float2(-0.5, 0.5),num==0 || num==2 || num==6 || num==8 );
seg += segment(uv.xy+float2( 0.5, 0.5),num!=-1 && num!=2 );
seg += segment(uv.yx+float2( 1.0, 0.0),num!=-1 && num!=1 && num!=4 && num!=7 );

return seg;
}

float showNum(float2 uv,int nr, bool zeroTrim)
{
//Speed optimization, leave if pixel is not in segment
if (abs(uv.x)>1.5 || abs(uv.y)>1.2)
return 0.0;

float seg= 0.0;
if (uv.x>0.0)
{
nr /= 10;
if (nr==0 && zeroTrim)
nr = -1;
seg += sevenSegment(uv+float2(-0.75,0.0),nr);
} else {
seg += sevenSegment(uv+float2( 0.75,0.0),int(mod(float(nr),10.0)));
}

return seg;
}

float dots(float2 uv)
{
float seg = 0.0;
uv.y -= 0.5;
seg += (1.0-smoothstep(0.11,0.13,length(uv))) * (1.0-length(uv)*2.0);
uv.y += 1.0;
seg += (1.0-smoothstep(0.11,0.13,length(uv))) * (1.0-length(uv)*2.0);
return seg;
}

float4 mainImage(VertData v_in) : TARGET
{
float2 uv = ((float2(v_in.uv.x, 1.0-v_in.uv.y) * uv_size).xy-0.5*uv_size) /
min(uv_size.x,uv_size.y);

if (uv_size.x>uv_size.y)
{
uv *= 6.0;
}
else
{
uv *= 12.0;
}

uv.x *= -1.0;
uv.x += uv.y/12.0;
//wobble
//uv.x += sin(uv.y*3.0+elapsed_time*14.0)/25.0;
//uv.y += cos(uv.x*3.0+elapsed_time*14.0)/25.0;
uv.x += 3.5;
float seg = 0.0;

float timeSecs = 0.0;
if(timeMode == 0){
timeSecs = local_time;
}else if(timeMode == 1){
timeSecs = elapsed_time_enable;
}else if(timeMode == 2){
timeSecs = elapsed_time_active;
}else if(timeMode == 3){
timeSecs = elapsed_time_show;
}else if(timeMode == 4){
timeSecs = elapsed_time_start;
}
timeSecs += offsetSeconds + offsetHours*3600;
if(timeSecs < 0)
timeSecs = 0.9999-timeSecs;
seg += showNum(uv,int(mod(timeSecs,60.0)),false);

timeSecs = floor(timeSecs/60.0);

uv.x -= 1.75;

seg += dots(uv);

uv.x -= 1.75;

seg += showNum(uv,int(mod(timeSecs,60.0)),false);

timeSecs = floor(timeSecs/60.0);
if (ampm)
{
if (timeSecs > 12.0)
timeSecs = mod(timeSecs,12.0);
}else if (timeSecs > 24.0) {
timeSecs = mod(timeSecs,24.0);
}

uv.x -= 1.75;

seg += dots(uv);

uv.x -= 1.75;
seg += showNum(uv,int(mod(timeSecs,60.0)),true);

if (seg==0.0){
return image.Sample(textureSampler, v_in.uv);
}
// matrix over segment
if (showMatrix)
{
seg *= 0.8+0.2*smoothstep(0.02,0.04,mod(uv.y+uv.x,0.06025));
//seg *= 0.8+0.2*smoothstep(0.02,0.04,mod(uv.y-uv.x,0.06025));
}
if (seg<0.0)
{
seg = -seg;;
return float4(seg,seg,seg,1.0);
}
return float4(ledColor.rgb * seg, ledColor.a);
}
27 changes: 19 additions & 8 deletions obs-shaderfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ uniform float elapsed_time_show;\n\
uniform float elapsed_time_active;\n\
uniform float elapsed_time_enable;\n\
uniform int loops;\n\
uniform float loop_second;\n\
uniform float local_time;\n\
\n\
sampler_state textureSampler{\n\
Expand Down Expand Up @@ -184,6 +185,7 @@ struct shader_filter_data {
gs_eparam_t *param_elapsed_time_active;
gs_eparam_t *param_elapsed_time_enable;
gs_eparam_t *param_loops;
gs_eparam_t *param_loop_second;
gs_eparam_t *param_local_time;
gs_eparam_t *param_rand_f;
gs_eparam_t *param_rand_instance_f;
Expand Down Expand Up @@ -307,6 +309,7 @@ static void shader_filter_clear_params(struct shader_filter_data *filter)
filter->param_rand_activation_f = NULL;
filter->param_rand_instance_f = NULL;
filter->param_loops = NULL;
filter->param_loop_second = NULL;
filter->param_local_time = NULL;
filter->param_image = NULL;
filter->param_image_a = NULL;
Expand Down Expand Up @@ -513,6 +516,8 @@ static void shader_filter_reload_effect(struct shader_filter_data *filter)
filter->param_rand_instance_f = param;
} else if (strcmp(info.name, "loops") == 0) {
filter->param_loops = param;
} else if (strcmp(info.name, "loop_second") == 0) {
filter->param_loop_second = param;
} else if (strcmp(info.name, "local_time") == 0) {
filter->param_local_time = param;
} else if (strcmp(info.name, "ViewProj") == 0) {
Expand Down Expand Up @@ -2495,8 +2500,8 @@ static void shader_filter_tick(void *data, float seconds)
}
filter->elapsed_time += seconds;
filter->elapsed_time_loop += seconds;
if (filter->elapsed_time_loop > 1.) {
filter->elapsed_time_loop -= 1.;
if (filter->elapsed_time_loop > 1.0f) {
filter->elapsed_time_loop -= 1.0f;

// Loops
filter->loops += 1;
Expand All @@ -2509,6 +2514,16 @@ static void shader_filter_tick(void *data, float seconds)
if (filter->enabled)
filter->shader_enable_time = filter->elapsed_time;
}
if (obs_source_enabled(filter->context) && obs_source_active(obs_filter_get_parent(filter->context))) {
filter->shader_active_time += seconds;
} else {
filter->shader_active_time = 0.0f;
}
if (obs_source_enabled(filter->context) && obs_source_showing(obs_filter_get_parent(filter->context))) {
filter->shader_show_time += seconds;
} else {
filter->shader_show_time = 0.0f;
}

// undecided between this and "rand_float(1);"
filter->rand_f = (float)((double)rand_interval(0, 10000) / (double)10000);
Expand Down Expand Up @@ -2620,10 +2635,10 @@ void shader_filter_set_effect_params(struct shader_filter_data *filter)
gs_effect_set_float(filter->param_elapsed_time_start, filter->elapsed_time - filter->shader_start_time);
}
if (filter->param_elapsed_time_show != NULL) {
gs_effect_set_float(filter->param_elapsed_time_show, filter->elapsed_time - filter->shader_show_time);
gs_effect_set_float(filter->param_elapsed_time_show, filter->shader_show_time);
}
if (filter->param_elapsed_time_active != NULL) {
gs_effect_set_float(filter->param_elapsed_time_active, filter->elapsed_time - filter->shader_active_time);
gs_effect_set_float(filter->param_elapsed_time_active, filter->shader_active_time);
}
if (filter->param_elapsed_time_enable != NULL) {
gs_effect_set_float(filter->param_elapsed_time_enable, filter->elapsed_time - filter->shader_enable_time);
Expand Down Expand Up @@ -2834,8 +2849,6 @@ void shader_filter_param_source_action(void *data, void (*action)(obs_source_t *

void shader_filter_activate(void *data)
{
struct shader_filter_data *filter = data;
filter->shader_active_time = filter->elapsed_time;
shader_filter_param_source_action(data, obs_source_inc_active);
}

Expand All @@ -2846,8 +2859,6 @@ void shader_filter_deactivate(void *data)

void shader_filter_show(void *data)
{
struct shader_filter_data *filter = data;
filter->shader_show_time = filter->elapsed_time;
shader_filter_param_source_action(data, obs_source_inc_showing);
}

Expand Down

0 comments on commit b73e2e8

Please sign in to comment.