Registriert seit: 22. Okt 2012
267 Beiträge
|
AW: Eigener Firemonkey TEffect Shader
23. Mai 2018, 12:41
Danke,
das hatte ich in der Form auch schon:
Code:
Texture2D GTexture : register(t0);
SamplerState s0 : register(s0);
float4 p0 : register(c0);
float4 p1 : register(c1);
#define screen_size float2(p0[0],p0[1])
#define hardScan float(p0[2])
#define hardPix float(p0[3])
#define warp float2(p1[0], p1[1])
// Amount of shadow mask.
#define maskDark float (p1[2])
#define maskLight float (p1[3])
// sRGB to Linear.
// Assuing using sRGB typed textures this should not be needed.
float ToLinear1(float c){return(c<=0.04045)?c/12.92:pow(abs((c+0.055)/1.055),2.4);}
float3 ToLinear(float3 c){return float3(ToLinear1(c.r),ToLinear1(c.g),ToLinear1(c.b));}
// Linear to sRGB.
// Assuing using sRGB typed textures this should not be needed.
float ToSrgb1(float c){return(c<0.0031308?c*12.92:1.055*pow(abs(c),0.41666)-0.055);}
float3 ToSrgb(float3 c){return float3(ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
// Nearest emulated sample given floating point position and texel offset.
// Also zero's off screen.
float3 Fetch(float2 pos,float2 off){
//pos=(floor(pos*screen_size+off)+float2(0.5,0.5))/screen_size;
if (max(abs(pos.x-0.5), abs(pos.y-0.5)) > 0.5) { return float3(0.0, 0.0, 0.0);}
return ToLinear(1.2 * GTexture.Sample(s0,pos).rgb);}
// Distance in emulated pixels to nearest texel.
float2 Dist(float2 pos){return -((pos-floor(pos))-float2(0.5, 0.5));}
// 1D Gaussian.
float Gaus(float pos,float scale){return exp2(scale*pos*pos);}
// 3-tap Gaussian filter along horz line.
// 3-tap Gaussian filter along horz line.
float3 Horz3(float2 pos,float off){
float3 b=Fetch(pos,float2(-1.0,off));
float3 c=Fetch(pos,float2( 0.0,off));
float3 d=Fetch(pos,float2( 1.0,off));
float dst=Dist(pos).x;
// Convert distance to weight.
float scale=hardPix;
float wb=Gaus(dst-1.0,scale);
float wc=Gaus(dst+0.0,scale);
float wd=Gaus(dst+1.0,scale);
// Return filtered sample.
return (b*wb+c*wc+d*wd)/(wb+wc+wd);}
// 5-tap Gaussian filter along horz line.
float3 Horz5(float2 pos,float off){
float3 a=Fetch(pos,float2(-2.0,off));
float3 b=Fetch(pos,float2(-1.0,off));
float3 c=Fetch(pos,float2( 0.0,off));
float3 d=Fetch(pos,float2( 1.0,off));
float3 e=Fetch(pos,float2( 2.0,off));
float dst=Dist(pos).x;
// Convert distance to weight.
float scale=hardPix;
float wa=Gaus(dst-2.0,scale);
float wb=Gaus(dst-1.0,scale);
float wc=Gaus(dst+0.0,scale);
float wd=Gaus(dst+1.0,scale);
float we=Gaus(dst+2.0,scale);
// Return filtered sample.
return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);}
// Return scanline weight.
float Scan(float2 pos,float off){
float dst=Dist(pos).y;
return Gaus(dst+off,hardScan);}
// Allow nearest three lines to effect pixel.
float3 Tri(float2 pos){
float3 a=Horz3(pos,-1.0);
float3 b=Horz5(pos, 0.0);
float3 c=Horz3(pos, 1.0);
float wa=Scan(pos,-1.0);
float wb=Scan(pos, 0.0);
float wc=Scan(pos, 1.0);
return a*wa+b*wb+c*wc;}
// Distortion of scanlines, and end of screen alpha.
float2 Warp(float2 pos){
pos=pos*2.0-1.0;
pos*=float2(1.0+(pos.y*pos.y)*warp.x,1.0+(pos.x*pos.x)*warp.y);
return pos*0.5+0.5;}
// Shadow mask.
float3 Mask(float2 pos){
pos.x+=pos.y*3.0;
float3 mask=float3(maskDark,maskDark,maskDark);
pos.x=frac(pos.x/6.0);
if(pos.x<0.333)mask.r=maskLight;
else if(pos.x<0.666)mask.g=maskLight;
else mask.b=maskLight;
return mask;
}
float4 main(float2 tex: TEXCOORD) : SV_TARGET
{
float2 pos = tex*screen_size;
tex = Warp(tex);
float4 color;
color.rgb = ToSrgb(Tri(tex)*Mask(pos));
return float4(color.r, color.g, color.b, 1);
}
Nachtrag: Der Shader oben scheint zu gehen, aber die Werte in dem Register sind alle 0.
Ich übergebe bei DX9 die Werte so:
[TContextShaderVariable.Create('Input', TContextShaderVariableKind.Texture, 0, 0),
TContextShaderVariable.Create('C0', TContextShaderVariableKind.Float, 0, 1),
TContextShaderVariable.Create('C1', TContextShaderVariableKind.Float, 1, 1)]
und genauso bei DX11. Das scheint aber nicht ganz korrekt, zumindest glaube ich das.
Ist auch nicht korrekt:
, [TContextShaderVariable.Create('Input', TContextShaderVariableKind.Texture, 0, 0),
TContextShaderVariable.Create('C0', TContextShaderVariableKind.Float, 0, 16),
TContextShaderVariable.Create('C1', TContextShaderVariableKind.Float, 16, 16)]
),
Damit gehts
Geändert von CHackbart (23. Mai 2018 um 13:06 Uhr)
|