VOGONS


.fx Shader Requirements

Topic actions

First post, by Yushatak

User metadata
Rank Member
Rank
Member

With the versions of DOSBox patched to use shaders when rendering in DirectX mode, I keep finding shaders that I'd like to use that refuse to function with DOSBox.

Ex. I've wanted CRT emulation in DOSBox for a while now, and I recently came across some shaders that do just that. I wanted to try them out, but when I dropped them in there, DOSBox complained about the formatting. I realized it had an XML header and footer, so I removed them. I then tried again, and it tossed errors about variable declarations being "unexpected" and such. I realize that some variables and function names need to be rewritten to conform to the standard set for DOSBox shaders, but what exactly needs to be done? What are the input variables, what is the main function name, is there any special outputs? Etc..

Anybody have a clue? 😖

Here's the shader I've been trying to get to work, needs variable name changes, but I don't know to what..

        uniform sampler2D rubyTexture;
uniform vec2 rubyInputSize;
uniform vec2 rubyOutputSize;
uniform vec2 rubyTextureSize;

#define TEX2D(c) texture2D(rubyTexture,(c))
#define PI 3.141592653589
#define phase 0.0
#define gamma 2.7

#define distortion 0.2

vec2 barrelDistortion(vec2 coord) {
vec2 cc = coord*rubyTextureSize/rubyInputSize - 0.5;
float dist = dot(cc, cc);
return coord + (cc * (dist + distortion * dist * dist) * distortion)*rubyInputSize/rubyTextureSize;
}

void main()
{
vec2 xy = barrelDistortion(gl_TexCoord[0].xy);

vec2 one = 1.0/rubyTextureSize;


vec2 uv_ratio = fract(xy*rubyTextureSize);
xy.x = floor(xy.x/one.x)*one.x;


vec4 col, col2;

vec4 coeffs = vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
coeffs = mix((sin(PI * coeffs) * sin(PI * coeffs / 2.0)) / (coeffs * coeffs), vec4(1.0), lessThan(abs(coeffs), vec4(0.01)));
coeffs = coeffs / (coeffs.x+coeffs.y+coeffs.z+coeffs.w);

col = clamp(coeffs.x * TEX2D(xy + vec2(-one.x,0.0)) + coeffs.y * TEX2D(xy) + coeffs.z * TEX2D(xy + vec2(one.x, 0.0)) + coeffs.w * TEX2D(xy + vec2(2.0 * one.x, 0.0)),0.0,1.0);
col2 = clamp(coeffs.x * TEX2D(xy + vec2(-one.x,one.y)) + coeffs.y * TEX2D(xy + vec2(0.0, one.y)) + coeffs.z * TEX2D(xy + one) + coeffs.w * TEX2D(xy + vec2(2.0 * one.x, one.y)),0.0,1.0);
col = pow(col, vec4(gamma));
col2 = pow(col2, vec4(gamma));

vec4 wid = 2.0 + 2.0 * pow(col, vec4(4.0));
vec4 weights = vec4(uv_ratio.y/0.3);
weights = 0.51*exp(-pow(weights*sqrt(2.0/wid),wid))/0.3/(0.6+0.2*wid);
wid = 2.0 + 2.0 * pow(col2,vec4(4.0));
vec4 weights2 = vec4((1.0-uv_ratio.y)/0.3);
weights2 = 0.51*exp(-pow(weights2*sqrt(2.0/wid),wid))/0.3/(0.6+0.2*wid);

vec4 mcol = vec4(1.0);
if ( mod(gl_TexCoord[0].x*rubyOutputSize.x*rubyTextureSize.x/rubyInputSize.x,2.0) < 1.0)
mcol.g = 0.7;
else
mcol.rb = vec2(0.7);

gl_FragColor = pow(mcol*(col * weights + col2 * weights2), vec4(1.0/2.2));
}

Reply 1 of 9, by Yushatak

User metadata
Rank Member
Rank
Member

Some progress...

        #include "scaling.inc"
string name : NAME = "CRT1x";
float scaling : SCALING = 1.0;
string combineTechnique : COMBINETECHNIQUE = "CRT1x";
float2 TexCoord : TEXCOORD0;

#define TEX2D(c) texture2D(SourceSampler,(c))
#define PI 3.141592653589
#define phase 0.0
#define gamma 2.7

#define distortion 0.2


void main()
{
float2 xy = TexCoord[0] + (TexCoord[0]*TexelSize/SourceDims - 0.5 * (dot(TexCoord[0]*TexelSize/SourceDims - 0.5, TexCoord[0]*TexelSize/SourceDims - 0.5) + distortion * dot(TexCoord[0]*TexelSize/SourceDims - 0.5, TexCoord[0]*TexelSize/SourceDims - 0.5) * dot(TexCoord[0]*TexelSize/SourceDims - 0.5, TexCoord[0]*TexelSize/SourceDims - 0.5)) * distortion)*SourceDims/TexelSize;


float2 one = 1.0/TexelSize;


float2 uv_ratio = frac(xy*TexelSize);
xy.x = floor(xy.x/one.x)*one.x;


float4 col, col2;
float4 coeffs = float4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
coeffs = mix((sin(PI * coeffs) * sin(PI * coeffs / 2.0)) / (coeffs * coeffs), float4(1.0), lessThan(abs(coeffs), float4(0.01)));
coeffs = coeffs / (coeffs.x+coeffs.y+coeffs.z+coeffs.w);

col = clamp(coeffs.x * TEX2D(xy + float2(-one.x,0.0)) + coeffs.y * TEX2D(xy) + coeffs.z * TEX2D(xy + float2(one.x, 0.0)) + coeffs.w * TEX2D(xy + float2(2.0 * one.x, 0.0)),0.0,1.0);
col2 = clamp(coeffs.x * TEX2D(xy + float2(-one.x,one.y)) + coeffs.y * TEX2D(xy + float2(0.0, one.y)) + coeffs.z * TEX2D(xy + one) + coeffs.w * TEX2D(xy + float2(2.0 * one.x, one.y)),0.0,1.0);
col = pow(col, float4(gamma));
col2 = pow(col2, float4(gamma));

float4 wid = 2.0 + 2.0 * pow(col, float4(4.0));
float4 weights = float4(uv_ratio.y/0.3);
weights = 0.51*exp(-pow(weights*sqrt(2.0/wid),wid))/0.3/(0.6+0.2*wid);
wid = 2.0 + 2.0 * pow(col2,float4(4.0));
float4 weights2 = float4((1.0-uv_ratio.y)/0.3);
weights2 = 0.51*exp(-pow(weights2*sqrt(2.0/wid),wid))/0.3/(0.6+0.2*wid);

float4 mcol = float4(1.0);
if ( mod(TexCoord[0].x*SourceDims.x*TexelSize.x/SourceDims.x,2.0) < 1.0)
mcol.g = 0.7;
else
mcol.rb = float2(0.7);

gl_FragColor = pow(mcol*(col * weights + col2 * weights2), float4(1.0/2.2));
}

technique CRT1x
{
pass P0
{
VertexShader = compile vs_2_0 main();
}
}

Current Error:
Line 30, incorrect number of arguments to numeric-type contstructor.

Edit: This is a bruteforce attack on shader language, btw. I know neither GLSL nor HLSL, just applying general progamming theory/experience with Google as supplement..

Reply 2 of 9, by Yushatak

User metadata
Rank Member
Rank
Member

Defeated that line.

        #include "scaling.inc"
string name : NAME = "CRT1x";
float scaling : SCALING = 1.0;
string combineTechnique : COMBINETECHNIQUE = "CRT1x";
float2 TexCoord : TEXCOORD0;

#define TEX2D(c) texture2D(SourceSampler,(c))
#define PI 3.141592653589
#define phase 0.0
#define gamma 2.7

#define distortion 0.2


void main()
{
float2 xy = TexCoord[0] + (TexCoord[0]*TexelSize/SourceDims - 0.5 * (dot(TexCoord[0]*TexelSize/SourceDims - 0.5, TexCoord[0]*TexelSize/SourceDims - 0.5) + distortion * dot(TexCoord[0]*TexelSize/SourceDims - 0.5, TexCoord[0]*TexelSize/SourceDims - 0.5) * dot(TexCoord[0]*TexelSize/SourceDims - 0.5, TexCoord[0]*TexelSize/SourceDims - 0.5)) * distortion)*SourceDims/TexelSize;


float2 one = 1.0/TexelSize;


float2 uv_ratio = frac(xy*TexelSize);
xy.x = floor(xy.x/one.x)*one.x;


float4 col, col2;
float4 coeffs = float4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
coeffs = ( 1.0 - (abs(coeffs) < float4(0.01,0.01,0.01,0.01)) )* ((sin(PI * coeffs) * sin(PI * coeffs / 2.0)) / (coeffs * coeffs)) + (abs(coeffs) < float4(0.01,0.01,0.01,0.01)) * float4(1.0,1.0,1.0,1.0);

coeffs = coeffs / (coeffs.x+coeffs.y+coeffs.z+coeffs.w);

col = clamp(coeffs.x * TEX2D(xy + float2(-one.x,0.0)) + coeffs.y * TEX2D(xy) + coeffs.z * TEX2D(xy + float2(one.x, 0.0)) + coeffs.w * TEX2D(xy + float2(2.0 * one.x, 0.0)),0.0,1.0);
col2 = clamp(coeffs.x * TEX2D(xy + float2(-one.x,one.y)) + coeffs.y * TEX2D(xy + float2(0.0, one.y)) + coeffs.z * TEX2D(xy + one) + coeffs.w * TEX2D(xy + float2(2.0 * one.x, one.y)),0.0,1.0);
col = pow(col, float4(gamma));
col2 = pow(col2, float4(gamma));

float4 wid = 2.0 + 2.0 * pow(col, float4(4.0));
float4 weights = float4(uv_ratio.y/0.3);
weights = 0.51*exp(-pow(weights*sqrt(2.0/wid),wid))/0.3/(0.6+0.2*wid);
wid = 2.0 + 2.0 * pow(col2,float4(4.0));
float4 weights2 = float4((1.0-uv_ratio.y)/0.3);
weights2 = 0.51*exp(-pow(weights2*sqrt(2.0/wid),wid))/0.3/(0.6+0.2*wid);

float4 mcol = float4(1.0);
if ( mod(TexCoord[0].x*SourceDims.x*TexelSize.x/SourceDims.x,2.0) < 1.0)
mcol.g = 0.7;
else
mcol.rb = float2(0.7);

gl_FragColor = pow(mcol*(col * weights + col2 * weights2), float4(1.0/2.2));
}

technique CRT1x
{
pass P0
{
VertexShader = compile vs_2_0 main();
}
}

New Error:
Line 33, Constructors only defined for numeric base types.

Reply 3 of 9, by Yushatak

User metadata
Rank Member
Rank
Member
        #include "scaling.inc"
string name : NAME = "CRT1x";
float scaling : SCALING = 1.0;
string combineTechnique : COMBINETECHNIQUE = "CRT1x";
float2 TexCoord : TEXCOORD0;

#define tex2D(c) texture2D(SourceSampler,(c))
#define PI 3.141592653589
#define phase 0.0
#define gamma 2.7

#define distortion 0.2


void main()
{
float2 xy = TexCoord[0] + (TexCoord[0]*TexelSize/SourceDims - 0.5 * (dot(TexCoord[0]*TexelSize/SourceDims - 0.5, TexCoord[0]*TexelSize/SourceDims - 0.5) + distortion * dot(TexCoord[0]*TexelSize/SourceDims - 0.5, TexCoord[0]*TexelSize/SourceDims - 0.5) * dot(TexCoord[0]*TexelSize/SourceDims - 0.5, TexCoord[0]*TexelSize/SourceDims - 0.5)) * distortion)*SourceDims/TexelSize;


float2 one = 1.0/TexelSize;


float2 uv_ratio = frac(xy*TexelSize);
xy.x = floor(xy.x/one.x)*one.x;


float4 coeffs = float4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);
coeffs = ( 1.0 - (abs(coeffs) < float4(0.01,0.01,0.01,0.01)) )* ((sin(PI * coeffs) * sin(PI * coeffs / 2.0)) / (coeffs * coeffs)) + (abs(coeffs) < float4(0.01,0.01,0.01,0.01)) * float4(1.0,1.0,1.0,1.0);
coeffs = coeffs / (coeffs.x+coeffs.y+coeffs.z+coeffs.w);

float4 col, col2;
col=clamp((coeffs.x * tex2D(xy + float2(-one.x,0.0)) + coeffs.y * tex2D(xy) + coeffs.z * tex2D(xy + float2(one.x, 0.0)) + coeffs.w * tex2D(xy + float2(2.0 * one.x, 0.0))),0.0,1.0);
col2 = clamp((coeffs.x * tex2D(xy + float2(-one.x,one.y)) + coeffs.y * tex2D(xy + float2(0.0, one.y)) + coeffs.z * tex2D(xy + one) + coeffs.w * tex2D(xy + float2(2.0 * one.x, one.y))),0.0,1.0);
col = pow(col, float4(gamma));
col2 = pow(col2, float4(gamma));

float4 wid = 2.0 + 2.0 * pow(col, float4(4.0));
float4 weights = float4(uv_ratio.y/0.3);
weights = 0.51*exp(-pow(weights*sqrt(2.0/wid),wid))/0.3/(0.6+0.2*wid);
wid = 2.0 + 2.0 * pow(col2,float4(4.0));
float4 weights2 = float4((1.0-uv_ratio.y)/0.3);
weights2 = 0.51*exp(-pow(weights2*sqrt(2.0/wid),wid))/0.3/(0.6+0.2*wid);

float4 mcol = float4(1.0);
if ( mod(TexCoord[0].x*SourceDims.x*TexelSize.x/SourceDims.x,2.0) < 1.0)
mcol.g = 0.7;
else
mcol.rb = float2(0.7);

gl_FragColor = pow(mcol*(col * weights + col2 * weights2), float4(1.0/2.2));
}

technique CRT1x
{
pass P0
{
PixelShader = compile ps_2_0 main();
}
}

I'm lost. Can't fix this error... I know it's something simple, but I just don't get it.

c1u7o.png

Something to do with "#define tex2D(c) texture2D(SourceSampler,(c))"? If I remove it it complains a bit..

Reply 5 of 9, by Yushatak

User metadata
Rank Member
Rank
Member

Tried that. Putting tex2D results into variables makes no difference, and removing the define produces:

"cannot implicitly convert from 'const float2' to 'const sampler2D'. (line 32)

I'm afraid I don't know how to EXplicitly convert these.. I come from a world called Python where types just poof into one another at will when it's convenient.

I presumed due to my ignorance that the define was intended to deal with that.

Reply 6 of 9, by gulikoza

User metadata
Rank Oldbie
Rank
Oldbie

If you remove the define, you call real tex2D function which requires 2 parameters - sampler and coordinates. You are only passing the coordinates.

I'm not even sure HLSL (the directx shading language) has texture2D() function, I cannot find any reference to it (GLSL on the other hand - the OpenGL shading language - has it), the texture sampling function is named tex2D.

So...try replacing all tex2D(c) with tex2D(sampler, c). If you still get the "constructors only defined for numeric base types" error, save all the texture samples to a variable and use that.

HLSL is running on the GPU. GPUs are quite specific and limited and that has to be taken into account. I assume you cannot mix arithmetic and texture operations in a single statement that's why you need to first save the texture lookup data and later use it. But you might run out of registers if there's too much samples...

http://www.si-gamer.net/gulikoza

Reply 7 of 9, by gulikoza

User metadata
Rank Oldbie
Rank
Oldbie

Further more...it seems you are indeed porting a GLSL program to HLSL. HLSL does not have uniform and vecX types, I just noticed from the original program. Also there is no main() function in HLSL. Please take a look at some existing .fx file and try to do something similar.

http://www.si-gamer.net/gulikoza

Reply 8 of 9, by Yushatak

User metadata
Rank Member
Rank
Member

msdn.microsoft.com/en-us/library/ff471376(v=vs.85).aspx

I've been using this as reference, and it does indeed have a tex2d function.

Good call on it requiring two parameters, I will try that..

As for vecX types, I blindly replaced them all with floatX types. I'm not sure what effect that will have, but afaik it will let me at least bypass the problem and get the shader into a functional state.

Reply 9 of 9, by gulikoza

User metadata
Rank Oldbie
Rank
Oldbie
Yushatak wrote:

As for vecX types, I blindly replaced them all with floatX types.

That seems fine 😀

http://www.si-gamer.net/gulikoza