Einzelnen Beitrag anzeigen

CHackbart

Registriert seit: 22. Okt 2012
260 Beiträge
 
#3

AW: Eigener Firemonkey TEffect Shader

  Alt 23. Mai 2018, 11: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 12:06 Uhr)
  Mit Zitat antworten Zitat