View Single Post
Old 10 September 2021, 12:24   #38
kokoko3k
Registered User
 
Join Date: Nov 2020
Location: italy
Posts: 23
Ok Photon, check this out.
I made a modification to the shader that allows you to "invert" the logic of the "darklines" feature.
Darklines were meant to draw less bright lines across the screen in "real monitor" coordinates; that means that they do not depend on the amiga resolution.
In the past the shader only allowed you to draw "one darkline every #DARKLINES_PERIOD".
Now you can pass a negative number to DARKLINES_PERIOD to invert the logic, so that if you set:
DARKLINES_PERIOD = -4.0
you'll have 3 less bright lines and a full bright line.
To recap, shader parameters that affect that "feature" are:
Code:
#define DO_DARKLINES           true  //Draw dark screenlines
#define DARKLINES_PERIOD       -4.0  //positive: Draw one darkline every # pixels
                                     //negative: Draw #num darklines and one standard line
#define DARKLINES_TRANSPARENCY 0.3   //0.0 to 1.0 from opaque to totally transparent
#define DRKLN_OVERWHITE        0.9   //how much darklines should affect bright colors
As already stated, this will:
* break compatibility with fs-uae zoom function
* strictly requires the real monitor resolution being an integer multiple of the amiga resolution.




Also note that i've disabled any scanline smoothing/glowing, because they do not make sense for your use-case; if you want thin scanlines and big gaps, there is just no room to smooth them; smoothing them would just produce the very same effect you seem to dislike.


A pre-configured shader with everything disabled apart from what you want follows:

Code:
<?xml version="1.0" encoding="UTF-8"?>

<shader language="GLSL">



<fragment scale="1.0" filter="linear"><![CDATA[
    #define DO_SCANLINES	false	//(true)	enable scanlines
    #define s1 				0.01	//(1.00)		even scanlines opacity
    #define s2				1.0	//(0.01)		odd scanlines opacity

	uniform sampler2D rubyTexture;
    void main(void) {
		//Use a vec4 for the color, so that even the alpha channel will be
		//'scanlined' this will come handy later to understand if a line is
		//a scanline or not. (see the bloom function)
        vec4 pixel = texture2D(rubyTexture, gl_TexCoord[0].xy);
        if ( DO_SCANLINES ) {
            if (mod(gl_FragCoord.y, 2.0) < 1.0) {
                    pixel *= s1;
            } else {
                    pixel *= s2;
            }
        }
        gl_FragColor = pixel;
    }

]]></fragment>

<fragment filter="linear"><![CDATA[
	
	#define DO_IN_GLOW		false			//(true)	Input signal glow, disables FIX_SCANLINES
	#define IN_GLOW_ADD		0.0				//0.0		0.0-1.0 glow overflows from the scanlines and image becomes sharper
	#define in_glow_w		2.0			//(1.5)		Input signal blur/glow width tightness
	#define in_glow_h		2.0			//(1.5)		Input signal blur/glow height tightness
	#define in_glow_power	0.5             //(1.35)	Input signal glow strength
	#define in_glow_gamma	1.0				//(5.0)		1.0-9.0, The higher,  the less the glow on dark colors, use integers.
	
	#define FIX_SCANLINES	false			//(true)	Mitigate dephasing when FS-UAE scales the texture
											//          WW: it only works when is true and DO_IN_GLOW is false


	#define DO_RGB_MASK		false			//(true)	Draw rgb mask
	// RGB mask:       R     G     B
    #define m1 vec3 ( 1.0 , 0.0 , 0.0 )    //col 1
    #define m2 vec3 ( 0.0 , 1.0 , 0.0 )    //col 2
    #define m3 vec3 ( 0.0 , 0.0 , 1.0  )   //col 3

	#define VMASK_OVERWHITE			1.0		//how much vmask should affect bright colors
	#define DRKLN_OVERWHITE			1.0		//how much darklines should affect bright colors
	
	#define DO_DARKLINES			true	//(false)	Draw dark screenlines
	#define DO_DARKLINES_VOFFSET    false   //(true)	When drawind darklines, offset them by triads
	#define DARKLINES_PERIOD		-4.0	//(4.0)		// for positive numbers: Draw one darkline every # pixels
														// for negative numbers: Draw #num darklines and one standard line
	#define DARKLINES_TRANSPARENCY	0.7		//(0.4)		0.0 to 1.0 from opaque to totally transparent
	#define FIX_FOR_INTEL			true	//1.0		There must be a weird bug into the intel shader compiler
														//which leads to absymal performance when doing 
														//halo after darklines.
														//use 1.0 to fix.
	
	#define DO_HALO	   false			  //(true)		Halation on/off
	#define halo_w     0.5            //(0.5)		Halo width tightness
	#define halo_h     0.5            //(0.5)		Halo height tightness
	#define halo_power 0.6            //(1.1)		Halo strength
	#define halo_gamma 3.0            //(5.0)		1.0-9.0 The higher, the less the halo on dark colors, use integers.

													//conflicts with real scanlines and autozoom.

	#define DO_BLOOM	  		false	//(true)	Blooming
	#define bloom_directions	16.0		//16.0		BLOOM DIRECTIONS More is better but slower)
	#define bloom_quality		2.0		//2.0		BLOOM QUALITY 4.0 - More is better but slower
	#define bloom_size			5.0		//5.0		BLOOM SIZE (Radius)
	#define bloom_gamma			2.0		//3.0		1.0-9.0 integer: restrict bloom to bright colors
	#define bloom_mix			0.1		//0.2		BLOOM final mix 
	#define bloom_over_scanline false	//true		Set it false to spare some gpu cycles if you disabled scanlines in the first fragment.

	#define DO_ALT_BLANK		false	//false     Show/blank odd/even fields alternately.
                                                    //to emulate short persistence of a CRT display. 
                                                    //Requires vsync and 50/100/150hz modeline and halves brightness.
	
	#define DO_COLOR_CORRECTION		false	//(true) 	Do (RGB) gamma correction
	#define GAMMA					1.7		//1.5		Global Gamma correction, the higher, the darker.
	#define cc vec3(0.46 ,0.45 , 0.44)		//(0.46,0.45,0.44) r,g,b, gamma correction values
	#define saturation				1.1		//1.0    Saturation modifier, 1.0 is neutral saturation.

/*****************************************************************************/	
	#define eps 1e-8
	uniform int rubyFrameCount ;
	uniform sampler2D rubyTexture;
	uniform vec2 rubyTextureSize;
	uniform vec2 rubyOutputSize ;
	uniform vec2 rubyOrigInputSize;

	vec3 int_pow3(vec3 v, float fpow){
		if ( fpow == 1.0 ) { return v; };
		if ( fpow == 2.0 ) { return v*v; }; 
		if ( fpow == 3.0 ) { return v*v*v; }; 
		if ( fpow == 4.0 ) { return v*v*v*v; }; 
		if ( fpow == 5.0 ) { return v*v*v*v*v; }; 
		if ( fpow == 6.0 ) { return v*v*v*v*v*v; }; 
		if ( fpow == 7.0 ) { return v*v*v*v*v*v*v; }; 
		if ( fpow == 8.0 ) { return v*v*v*v*v*v*v*v; }; 
		if ( fpow == 9.0 ) { return v*v*v*v*v*v*v*v*v; }; 
	}

	float int_pow(float v, float fpow){
		if ( fpow == 1.0 ) { return v; };
		if ( fpow == 2.0 ) { return v*v; }; 
		if ( fpow == 3.0 ) { return v*v*v; }; 
		if ( fpow == 4.0 ) { return v*v*v*v; }; 
		if ( fpow == 5.0 ) { return v*v*v*v*v; }; 
		if ( fpow == 6.0 ) { return v*v*v*v*v*v; }; 
		if ( fpow == 7.0 ) { return v*v*v*v*v*v*v; }; 
		if ( fpow == 8.0 ) { return v*v*v*v*v*v*v*v; }; 
		if ( fpow == 9.0 ) { return v*v*v*v*v*v*v*v*v; }; 
	}
	
	vec3 pixel_glow(float my_glowpix, float my_glowpixy, float my_glow, float glow_gamma) {
		// Calculating texel coordinates
			vec2 size     = rubyTextureSize;
			vec2 inv_size = 1.0/rubyTextureSize;
			vec2 OGL2Pos = gl_TexCoord[0].xy * size  - vec2(0.5,0.5);
			vec2 fp = fract(OGL2Pos);
			vec2 dx = vec2(inv_size.x,0.0);
			vec2 dy = vec2(0.0, inv_size.y);
			vec2 pC4 = floor(OGL2Pos) * inv_size + 0.5*inv_size;    

			vec2 x2 = 2.0*dx; vec2 x3 = 3.0*dx;
			vec2 y2 = 2.0*dy;

			float wl3 = 2.0 + fp.x; wl3*=wl3; wl3 = exp2(-my_glowpix*wl3);
			float wl2 = 1.0 + fp.x; wl2*=wl2; wl2 = exp2(-my_glowpix*wl2);
			float wl1 =       fp.x; wl1*=wl1; wl1 = exp2(-my_glowpix*wl1);
			float wr1 = 1.0 - fp.x; wr1*=wr1; wr1 = exp2(-my_glowpix*wr1);
			float wr2 = 2.0 - fp.x; wr2*=wr2; wr2 = exp2(-my_glowpix*wr2);
			float wr3 = 3.0 - fp.x; wr3*=wr3; wr3 = exp2(-my_glowpix*wr3);    
			
			float wt = 1.0/(wl3+wl2+wl1+wr1+wr2+wr3);

			vec3 l3 = texture2D(rubyTexture, pC4 -x2 ).xyz;
			vec3 l2 = texture2D(rubyTexture, pC4 -dx ).xyz;
			vec3 l1 = texture2D(rubyTexture, pC4     ).xyz;
			vec3 r1 = texture2D(rubyTexture, pC4 +dx ).xyz;
			vec3 r2 = texture2D(rubyTexture, pC4 +x2 ).xyz;
			vec3 r3 = texture2D(rubyTexture, pC4 +x3 ).xyz;
			l3=int_pow3(l3,glow_gamma); l2=int_pow3(l2,glow_gamma); l1=int_pow3(l1,glow_gamma); 
			r1=int_pow3(r1,glow_gamma); r2=int_pow3(r2,glow_gamma); r3=int_pow3(r3,glow_gamma); 

			vec3 t1 = (l3*wl3 + l2*wl2 + l1*wl1 + r1*wr1 + r2*wr2 + r3*wr3)*wt;

			l3 = texture2D(rubyTexture, pC4 -x2 -dy).xyz;
			l2 = texture2D(rubyTexture, pC4 -dx -dy).xyz;
			l1 = texture2D(rubyTexture, pC4     -dy).xyz;
			r1 = texture2D(rubyTexture, pC4 +dx -dy).xyz;
			r2 = texture2D(rubyTexture, pC4 +x2 -dy).xyz;
			r3 = texture2D(rubyTexture, pC4 +x3 -dy).xyz;
			l3=int_pow3(l3,glow_gamma); l2=int_pow3(l2,glow_gamma); l1=int_pow3(l1,glow_gamma); 
			r1=int_pow3(r1,glow_gamma); r2=int_pow3(r2,glow_gamma); r3=int_pow3(r3,glow_gamma); 

			vec3 t2 = (l3*wl3 + l2*wl2 + l1*wl1 + r1*wr1 + r2*wr2 + r3*wr3)*wt;    

			l3 = texture2D(rubyTexture, pC4 -x2 +dy).xyz;
			l2 = texture2D(rubyTexture, pC4 -dx +dy).xyz;
			l1 = texture2D(rubyTexture, pC4     +dy).xyz;
			r1 = texture2D(rubyTexture, pC4 +dx +dy).xyz;
			r2 = texture2D(rubyTexture, pC4 +x2 +dy).xyz;
			r3 = texture2D(rubyTexture, pC4 +x3 +dy).xyz;
			l3=int_pow3(l3,glow_gamma); l2=int_pow3(l2,glow_gamma); l1=int_pow3(l1,glow_gamma); 
			r1=int_pow3(r1,glow_gamma); r2=int_pow3(r2,glow_gamma); r3=int_pow3(r3,glow_gamma); 

			vec3 b1 = (l3*wl3 + l2*wl2 + l1*wl1 + r1*wr1 + r2*wr2 + r3*wr3)*wt;

			l3 = texture2D(rubyTexture, pC4 -x2 +y2).xyz;
			l2 = texture2D(rubyTexture, pC4 -dx +y2).xyz;
			l1 = texture2D(rubyTexture, pC4     +y2).xyz;
			r1 = texture2D(rubyTexture, pC4 +dx +y2).xyz;
			r2 = texture2D(rubyTexture, pC4 +x2 +y2).xyz;
			r3 = texture2D(rubyTexture, pC4 +x3 +y2).xyz;
			l3=int_pow3(l3,glow_gamma); l2=int_pow3(l2,glow_gamma); l1=int_pow3(l1,glow_gamma); 
			r1=int_pow3(r1,glow_gamma); r2=int_pow3(r2,glow_gamma); r3=int_pow3(r3,glow_gamma); 

			vec3 b2 = (l3*wl3 + l2*wl2 + l1*wl1 + r1*wr1 + r2*wr2 + r3*wr3)*wt;    

			wl2 = 1.0 + fp.y; wl2*=wl2; wl2 = exp2(-my_glowpixy*wl2);
			wl1 =       fp.y; wl1*=wl1; wl1 = exp2(-my_glowpixy*wl1);
			wr1 = 1.0 - fp.y; wr1*=wr1; wr1 = exp2(-my_glowpixy*wr1);
			wr2 = 2.0 - fp.y; wr2*=wr2; wr2 = exp2(-my_glowpixy*wr2);

			wt = 1.0/(wl2+wl1+wr1+wr2);    

			vec3 Bloom = (t2*wl2 + t1*wl1 + b1*wr1 + b2*wr2)*wt;
			return Bloom*my_glow;
	}
	vec3 pixel_vmask(vec3 source,vec3 lm1,vec3 lm2,vec3 lm3, vec3 white_reference,float over_white) {
		float col = float(int(gl_FragCoord.x));
		vec3 pixel_out;
		vec3 vmasked;
		
		if (int(mod(col, 3.0)) < 1) {
			vmasked = lm1*source;
		}
		else if (int(mod(col, 3.0)) < 2) {
			vmasked = lm2*source;
		}
		else {
			vmasked = lm3*source;
		}
		if (over_white == 1.0) {
			return vmasked;
		} else {
			float whiteness=(white_reference.r+white_reference.g+white_reference.b)/3.0;
			whiteness-=over_white;
			whiteness=min(whiteness,1.0);
			whiteness=max(whiteness,0.0);
			return mix(vmasked,source,whiteness);
		}
	}

vec3 blur(float Directions, float Quality, float Size) {
	vec2 iResolution = rubyTextureSize;
	float Pi = 6.28318530718; // Pi*2
	vec2 Radius = Size/iResolution.xy;
	//vec2 uv = vec2(gl_FragCoord.xy / iResolution);
	vec2 uv = gl_TexCoord[0].xy;
		
	vec3 color = texture2D(rubyTexture, uv).rgb;
	float steps=0.0;
	for( float d=0.0; d<Pi; d+=Pi/Directions) {
		for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality) {
			color += texture2D( rubyTexture, uv+vec2(cos(d),sin(d))*Radius*i).rgb;		
			steps+=1.0;
        }
    }	
	color /= steps; //(Quality * Directions - 15.0);


	return color;
}
	
	vec3 bloom(float Directions, float Quality, float Size,float fbloom_gamma,bool over_scanline) {
		float Pi = 6.28318530718; // Pi*2
		vec2 Radius = Size/rubyTextureSize.xy;
		vec2 uv = gl_TexCoord[0].xy;
		float steps=0.0;
		vec4 lookup=vec4(0.0,0.0,0.0,0.0);
		vec3 color=vec3(0.0,0.0,0.0);
		for( float d=0.0; d<Pi; d+=Pi/Directions) {
			for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality) {
				//lookup texel around
				lookup = texture2D( rubyTexture, uv+vec2(cos(d),sin(d))*Radius*i);
				if (over_scanline) {
					color +=int_pow3(lookup.rgb,fbloom_gamma) / (int_pow(lookup.a,fbloom_gamma)+0.00001);
				} else {
					color +=int_pow3(lookup.rgb,fbloom_gamma);
				}
				steps+=1.0;
			}
		}	
		color = color/steps; //(Quality * Directions - 15.0);

		return color;
	}

	vec3 pixel_darklines(vec3 source,float darkline_every, float darkline_trans, bool do_offset, vec3 white_reference,float over_white) {
		vec3 pixel_out=source;
		float col_2 =  gl_FragCoord.x;
		float line_2 = gl_FragCoord.y;

		float fDarkline_part_w=3.0 ;             //Triads width, float type
		float fDarkline_part_w_x2 = 6.0 ;        //Triads width, float type, *2
		int iDarkline_part_w = 3 ;               //Triads width, integer type (3 pixels unless changing m1,m2,m3 datatype
		
		if (over_white != 1.0) {
			//less effect on bright colors.
			float whiteness=(white_reference.r+white_reference.g+white_reference.b)/3.0;
			darkline_trans+=(whiteness-over_white);
			darkline_trans=max(darkline_trans,0.0);
			darkline_trans=min(darkline_trans,1.0);
		}
		
		if (do_offset) { 
			int hmask_shape_offset = int (darkline_every/2.0) + 1 ;
			if  (int(mod(line_2, darkline_every)) == 1) {
				if (int(mod(col_2, fDarkline_part_w_x2)) < iDarkline_part_w) {
					pixel_out =  pixel_out * darkline_trans;
				}
			} else if  (int(mod(line_2, darkline_every)) == hmask_shape_offset ) {
				// DRAW WITH OFFSET:
				col_2+=fDarkline_part_w;
				if ((int(mod(col_2, fDarkline_part_w_x2))) < iDarkline_part_w) {
					pixel_out =  pixel_out * darkline_trans;
				}
			}
		} else {
			if ( darkline_every >= 0.0) {
				if  (int(mod(line_2, darkline_every)) == 1) {
					pixel_out =  pixel_out * darkline_trans;
				}
			}
			
			if ( darkline_every < 0.0) {
				if  (int(mod(line_2, abs(darkline_every)       )) != 1) {
					pixel_out =  pixel_out * darkline_trans;
				}
			}
			
				
		}
		
		return pixel_out;
	}

	
vec3 blur5(vec2 uv, vec2 resolution, vec2 direction) {
  vec3 color = vec3(0.0);
  vec2 off1 = vec2(1.3333333333333333) * direction;
  color += texture2D(rubyTexture, uv).rgb * 0.29411764705882354;
  color += texture2D(rubyTexture, uv + (off1 / resolution)).rgb * 0.35294117647058826;
  color += texture2D(rubyTexture, uv - (off1 / resolution)).rgb * 0.35294117647058826;
  return color; 
}


vec3 fix_scanlines(float radius) {
	vec2 uv = gl_TexCoord[0].xy;
	vec2 direction=vec2(0.0,1.0);
	vec3 color=vec3(0.0);
	direction*=radius;
	color=blur5(uv,rubyTextureSize.xy,direction);
	return color;
}
	
	
vec3 pixel_alternate(vec3 source) {
	float line = gl_FragCoord.y;
	vec3 pixel_out = source;
	if  (int(mod(float(rubyFrameCount),2.0  )) == 1) {
		if  (int(mod(line,2.0  )) == 1) {
			pixel_out=vec3(0.0,0.0,0.0) ; 
		}
	} else {
		if  (int(mod(line,2.0  )) == 0) {
			pixel_out=vec3(0.0,0.0,0.0) ; 
		}
	}
	return pixel_out;
}
	

    void main(void) {
		vec3 pixel_in = texture2D(rubyTexture, gl_TexCoord[0].xy).rgb; 
		vec3 pixel_out = pixel_in;
		vec3 haloed = pixel_in;
		vec3 glowed = pixel_in;
		vec3 bloomed = pixel_in;

		if (DO_IN_GLOW) { 
			/* Input signal is blurred and glows.
			glow power versus blur power is defined by IN_GLOW_ADD.
			this allows the rgb vmask to light up on the black scanline.
			*/
			glowed = pixel_glow(in_glow_w,in_glow_h,in_glow_power,in_glow_gamma);
			if (IN_GLOW_ADD>0.0) {
				pixel_out =mix(glowed,glowed+pixel_out,IN_GLOW_ADD);
			} else {
				pixel_out =glowed;
			}
		} else if (FIX_SCANLINES) { 
			pixel_out=fix_scanlines(0.2); 	//try from 0.1 to 0.3
		} 

		
		if (DO_RGB_MASK) { 
			pixel_out = pixel_vmask(pixel_out,m1,m2,m3,pixel_in,VMASK_OVERWHITE);
		}

		if (DO_DARKLINES && DO_HALO && FIX_FOR_INTEL) {
			haloed = pixel_glow(halo_w,halo_h,halo_power,halo_gamma);
			pixel_out+=haloed; //yes i know, 
			pixel_out-=haloed; //but still...
		}
		
		
		if (DO_DARKLINES) {
			pixel_out = pixel_darklines(pixel_out,DARKLINES_PERIOD,DARKLINES_TRANSPARENCY,DO_DARKLINES_VOFFSET,pixel_in,DRKLN_OVERWHITE);
		}

		if (DO_HALO) { 
			haloed = pixel_glow(halo_w,halo_h,halo_power,halo_gamma);
			pixel_out +=haloed;
		}

		if (DO_BLOOM) {
			bloomed = bloom(bloom_directions,bloom_quality,bloom_size,bloom_gamma,bloom_over_scanline);
			pixel_out = (pixel_out * (1.0-bloom_mix) ) + ( bloomed*bloom_mix);
		}

		if (DO_COLOR_CORRECTION) {
			pixel_out = pow(pixel_out,cc*GAMMA);
		}

		if (DO_ALT_BLANK) {
			pixel_out = pixel_alternate(pixel_out);
		}
		
		if (!(saturation == 1.0)) {
			float l = length(pixel_out);
			pixel_out = normalize(pow(pixel_out + vec3(eps,eps,eps), vec3(saturation,saturation,saturation)))*l;
		}

		gl_FragColor = vec4(pixel_out,1.0);
    }
]]></fragment>
    

    


</shader>

PS: Your posted images is scaled by a factor of 3x and is not 1080p as you requested (?), the repeating pattern i see is indeed bright,dark,dark, while what i posted is bright,dark,dark,dark (4x zoom, 1080p)

Last edited by kokoko3k; 12 September 2021 at 16:07.
kokoko3k is offline  
 
Page generated in 0.04747 seconds with 11 queries