GLSL Shaders in .vsh format?

Are you sure you’re editing/loading the correct file? There’s not really any way that it could be skipping that line and still loading the last couple of lines to the extent that it wouldn’t error out without a semicolon.

For separating into its own pass, you can look at our dotmask.cg shader, which is exactly that.

I am sure that I am loading the right file :smiley: … The shadowmask lines are the last lines in the fsh code. So it could be possible that everything prior this lines is loaded, but those last lines not… still strange that there is no error prompt.

If I make a second pass, with the dotmask.cg shader, there is a error prompt. By second pass, I am assuming to create a second .vsh and .fsh file and use a “glsl_shader_mame1 D:\GAMESTATION\MAME\MAME_0160_64\glsl\dotmask” (only example) inside the mame.ini.

It is really difficult, if you dont know what error is there other than “GLSL loading mame bitmap shader 1 failed”… really miss some debugging tool :frowning:

Yeah, it’s pretty much impossible to work on shaders (or any code, really) without meaningful debug info. Surely it prints the real error somewhere…

There’s no way it’s stopping before that line because the very last line is the one that actually tells the shader what to do (‘return’ in the main fragment function of a Cg shader and 'gl_fragCoord = ’ in GLSL).

If that line won’t cause an error, can you make it error elsewhere in the file? I’m still suspicious that you’re working on a different file from the one it’s loading, which is nothing to be ashamed of. I’ve done it a million times. “wtf? why is it still giving that error?? oh wait…”

ok… i found out the error… trivial off course :smiley: … my first attempt, was a linux derivant of the crt-geom shader. The linux version missed the slotmask in the code, but i didnt notice it. Because the linux version contained way more than just two files, i.e. additional idx16_lut.fsh and rgb32_lut.fsh files, i wanted to start from scratch. After you told me how to do the vsh and fsh files, i renamed the linux-version with a underscore at the end of the name ( crt-geom_rgb32_dir_.fsh ) , but off course this wasnt enough and MAME used always this version, instead of the one, i was currently working :smiley: .

ok, so far so good… we can adress the problem straight to these two lines:

vec3 dotMaskWeights = mix( vec3(1.0, 0.7, 1.0), vec3(0.7, 1.0, 0.7), floor(mod(mod_factor, 2.0)) );

mul_res *= dotMaskWeights;

I guess, thats why they where removed in the linux-version :smiley:

I tried changing: mul_res *= dotMaskWeights; to: mul_res = mul(mul_res, dotMaskWeights); Or just using one line at a time… all with no luck. The error lies in those two lines, thats for sure. By removing them, all went fine.

Ok, I’m guessing it’s choking on the mod_factor variable, which is supposed to be defined in the vertex. Try replacing it with whatever the MAME equiv of this is: texCoord.x * IN.texture_size.x * IN.output_size.x / IN.video_size.x That is, maybe it’s not pulling it from the vertex properly, so just put it directly into the fragment.

If that doesn’t get it working, I don’t think we can get any further without proper error messages.

I need some good source for MAME equivalents… I cant find any useful docs regarding MAME and OpenGL.

of this line: mod_factor = texCoord.x * rubyTextureSize.x * rubyOutputSize.x / rubyInputSize.x;

the only NOT knowing equivalent (at least for me) would be the “rubyOutputSize” …

All other parameters, are also used elsewhere in the code, so if they would be wrong, the shader wouldnt work. The conversion of that line, would be like this at the moment:

mod_factor = texCoord.x * color_texture_pow2_sz.x * rubyOutputSize.x / color_texture_sz.x;

Still missing, would be the “rubyOutputSize.x” and its only used in that line. I dont know where to search for this. So yeah, you are right with “it’s choking on the mod_factor variable” , Really desperate here :frowning: .

I really dont know, why they even changed stuff like this… I always thought OpenGL is multiplatform and same across the different OS´s. How can someone convert something, if stuff is missing or not the same?? WTF… Even the splitting of the vsh and fsh files is really annoying… MAME should be renamed to NTSC (N.ever T.he S.ame C.ode). It could be easy, but no, we make it complicated and undocumented :frowning: .

Alright, one more thing to try: replace mod_factor in the fragment with gl_FragCoord.x

It all hangs only on this “rubyOutputSize.x” thingy… code works now (but with no difference) , even with mod_factor and dotmask, as long as I keep out “rubyOutputSize.x” .

so i need a replacement for this:

uniform vec2 rubyOutputSize;

and this:

mod_factor = texCoord.x * color_texture_pow2_sz.x * rubyOutputSize.x / color_texture_sz.x;

these are the only places, where “rubyOutputSize.x” stuff is placed and both lines are in the vertex part (or vsh file)

PS: Just tried, with leaving those “rubyOutputSize” as is… no error prompt, but no slotmask either :frowning:

Ok, if I get rid of the mod_factor stuff (and, thus, all of the OutputSize, etc. stuff, too) entirely and replace it with gl_FragCoord.x, it works fine here (not in MAME, but in a GLSL shader IDE).

Ok, shall I delete everything mod_factor related ??? Because I have two lines in the vertex part, where mod_factor is included:

varying float mod_factor;

and

mod_factor = texCoord.x * color_texture_pow2_sz.x * rubyOutputSize.x / color_texture_sz.x;

And in the fragment part, there are also two lines:

varying float mod_factor;

and

vec3 dotMaskWeights = mix( vec3(1.0, 0.7, 1.0), vec3(0.7, 1.0, 0.7), floor(mod(mod_factor, 2.0)) );

So i replace the whole lines with gl_FragCoord.x or only the term mod_factor ???

Dude, you are awesome… it worked. So I only kept the line:

vec3 dotMaskWeights = mix( vec3(1.0, 0.7, 1.0), vec3(0.7, 1.0, 0.7), floor(mod(gl_FragCoord.x, 2.0)) );

It works now, but the dotmask is barely visible… how I can make the mask more visible?

And it doesnt work on vertical games, so I guess it needs to be rotated for them. How would I do this?

Anyway, first a very BIIIIIGGG THANNNKS … You made one person in the world really happy now :slight_smile:

PS: I got that solved with the vertical alignment… and I am ashamed that I even asked… off course it is “gl_FragCoord.y”

There are a couple of options. You can change the 1.0s and 0.7s to a bigger difference, such as 1.3 and 0.4 (just make sure they add up to 2.0 so it all balances out), and/or you can try making it larger by multiplying gl_FragCoord by something <1.0, like 0.5. Tbh, rather than sticking with gl_FragCoord, you might be better off just playing around with something that ties it to the resolution, like texCoord.x * color_texture_pow2_sz.x or whatever works, as I believe gl_FragCoord is going to stay the same size whether you have it fullscreen on a 4K TV or windowed at 640x480…

Thanks for your advices, they really helped me. Multiplying gl_FragCoord by something <1.0, worked only good with 0.5, as there was ugly color shifting with other values. Tried to replace gl_FragCoord, with something like texCoord.x * color_texture_pow2_sz.x, but same here… it didnt looked so well. Today, I will not have much time to prove if gl_FragCoord dont tie with resolution… with my first tests, it was hard to tell… I will need a deep screenshot photoshop comparison to be safe.

Also trying to achieve some bilinear filtering or blur, prior the crt-geom processing. I allready have a shader, but it blurs way, way too much and I dont know how to reduce it properly. Everything I tried, didnt reduced it equally on X,Y cord. So I guess, it is not the right way :wink: . Maybe you have some hint for me? :slight_smile: I attached you my Bilinear-shader.

What is this .LUT stuff? I have those in the linux part, but they dont do anything, if i use them with windows… at least I think so. It makes no difference for me, if its there or not.

I would like to credit you for helping me, if we put this shader into the next release of UIFX, is this ok for you? any special wishes?

cheers u-man

LUT stands for “lookup texture,” so if it’s referencing one, there should be an external image file that it’s pulling from. That bilinear shader looks pretty crazy to me insfoar as regular bilinear scaling should be essentially “free” on any hardware. Doing it manually like this is likely to be super-slow, particularly with the branching if statements.

Generally for blurs, you want to break them into 2 passes: one for vertical and one for horizontal. Gaussian blurs look nice and are super-simple to code. You can look at my bigblur-horiz and bigblur-vert shaders in common-shaders/borders/resources for examples. They can be very resource-intensive at large sizes, though, so you would want to run them at, say, 1x scale and then let your crt shader do the scaling from there.

Don’t worry about crediting me. I’m happy to help :slight_smile:

Long time, no hear… :slight_smile: … I tried to seperate the four main parts of the shader: Curvature, Corner, Scanlines and Dotmask. Something like the cgwg-CRT-deconstructed.shader, but I fail at the scanlines. The four parts are bounded or sticked together in a way, that i cant remove the scanlines part. It would be nice to have the parts seperated, so users could try them on different shaders and maybe “construct” new versions.

Although I found out, that the tilt feature, doesnt work on every vertical game.

i.e., if you use this values with Donkey Kong, then the screen will be tilted into the correct direction:

// tilt angle in radians // (behavior might be a bit wrong if both components are nonzero) const vec2 angle = vec2(-0.15,0.0);

but if you try the same values with lets say Time Pilot, then the screen will tilt into the wrong direction (just the opposite). If you correct the line with a positive value like: const vec2 angle = vec2(0.15,0.0); then it will not work with Donkey Kong anymore. I really wonder, why is this tilt option behaving like this and if there is a solution for this? I didnt find errors, if I use the tilt option on horizontal games. My guess is, that it has to do, with the axis where the tilt is happening.

Thats all for now… maybe you have a clue :slight_smile: , cheers u-man

PS: http://mame32fx.altervista.org/home.htm

:smiley: :wink:

Hello Hunter K., i need to bump this thread again.

While the CRT-geom shader is working well on my setup, i have frequent postings of users, where the CRT-geom shader just delivers a black screen with audio. To have a picture again, the #define CURVATURE parameter needs to be out-commented with two //. I would really like to have some debugger-tool for opengl, because its hard to find the cause of the problem here, especially with a setup, that dont have to deal with that “bug”. I guess it is a “transform” problem, but “transform” is related to so many operations, nearly impossible for me to find the cause of this “bug”.

All things mentioned in my #35 post, are still actual :frowning: . It would be very useful to have a “deconstructed” version. I hope you can help me out Hunter K. :wink:

Greets, u-man

You could try putting a simple curvature shader into a separate pass and just always commenting out the curvature function:

It’s simple enough that you could pretty easily merge it into crt-geom if you want it to stay single-pass.

First, a big thanks to you … Hunter K. , my dude who solves the problems :smiley: . I just want to confirm, that it worked. I managed to include your “new” curvature to replace the “old” one. It has some downsides, i.e. you cant use the Tilt function anymore. I can live with this, at least there is a solution for the very view people that had a problem with our old CRT-geom shader. We can distribute this version as a fix now :wink: , thanks to you :slight_smile: .

I still have some questions, for my next steps. I guess this is the halation part from the CRT-geom shader:

uniform sampler2D mpass_texture; uniform vec2 color_texture_pow2_sz; uniform vec2 color_texture_sz; uniform vec2 rubyOutputSize;

#define CRTgamma 2.5 #define display_gamma 2.2 #define TEX2D© pow(texture2D(mpass_texture, ©), vec4(CRTgamma))

void main() { vec2 xy = gl_TexCoord[0].st; float oney = 1.0/color_texture_pow2_sz.y;

            float wid = 2.0;

            float c1 = exp(-1.0/wid/wid);
            float c2 = exp(-4.0/wid/wid);
            float c3 = exp(-9.0/wid/wid);
            float c4 = exp(-16.0/wid/wid);
            float norm = 1.0 / (1.0 + 2.0*(c1+c2+c3+c4));

            vec4 sum = vec4(0.0);

            sum += TEX2D(xy + vec2(0.0, -4.0 * oney)) * vec4(c4);
            sum += TEX2D(xy + vec2(0.0, -3.0 * oney)) * vec4(c3);
            sum += TEX2D(xy + vec2(0.0, -2.0 * oney)) * vec4(c2);
            sum += TEX2D(xy + vec2(0.0, -1.0 * oney)) * vec4(c1);
            sum += TEX2D(xy);
            sum += TEX2D(xy + vec2(0.0, +1.0 * oney)) * vec4(c1);
            sum += TEX2D(xy + vec2(0.0, +2.0 * oney)) * vec4(c2);
            sum += TEX2D(xy + vec2(0.0, +3.0 * oney)) * vec4(c3);
            sum += TEX2D(xy + vec2(0.0, +4.0 * oney)) * vec4(c4);

            gl_FragColor = pow(sum*vec4(norm),vec4(1.0/display_gamma));
    }

I managed to run this code in a seperate shader, but i am not able to include it into the CRT-geom shader. The seperate shader creates some kind of a blurry image, thats all, but I guess this is the part of a halation process, which blends this result with the final image to create the halation. How I can do this properly?

… and thank you so much for your help so far, I would not come so far without it :slight_smile:

You’re not going to want to do halation in a single pass, if that’s what you’re after. Those blurs look terrible and are very slow unless you bust them out into separate passes. You’ll also need the ability to reference output from previous specific passes for it to work, which I don’t know if your MAME variant has. Also, those passes are just simple gaussian blurs, which is fine, but most people doing proper bloom/HDR include a brightness-threshold (commonly called a bright pass) first to isolate just the really bright stuff ([url=]this shader from maister’s “glow” does this step), which then gets blurred and added to the final image.

So, you would have the bright pass, followed by a horizontal blur pass and a vertical blur pass that run in order referencing the one before, followed by the crt effect pass that references the original frame, and then a final frame that adds the output of the crt effect pass with the output of the last blurring pass. If you want it to look exactly like cgwg’s version, just leave out the bright pass bit.