AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Eigener Firemonkey TEffect Shader

Ein Thema von CHackbart · begonnen am 23. Mai 2018 · letzter Beitrag vom 26. Mai 2018
 
CHackbart

Registriert seit: 22. Okt 2012
267 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
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz