Team Ai
Apppublic

broadfield-dev/stack-overflow-game

sourceHugging Faceupdated 4mo agoView on Hugging Face
0likes
TrinitronPipeline.js191 linesDownload Raw Back to pipelines
1import Phaser from 'phaser';2 3const fragShader = `4precision mediump float;5 6uniform sampler2D uMainSampler;7uniform vec2 resolution;8uniform float time;9 10varying vec2 outTexCoord;11 12#define PI 3.1415926535913 14vec4 permute(vec4 t) {15  return mod(((t * 34.0) + 1.0) * t, 289.0);16}17 18float noise3d(vec3 p) {19  vec3 a = floor(p);20  vec3 d = p - a;21  d = d * d * (3.0 - 2.0 * d);22 23  vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0);24  vec4 k1 = permute(b.xyxy);25  vec4 k2 = permute(k1.xyxy + b.zzww);26 27  vec4 c = k2 + a.zzzz;28  vec4 k3 = permute(c);29  vec4 k4 = permute(c + 1.0);30 31  vec4 o1 = fract(k3 * (1.0 / 41.0));32  vec4 o2 = fract(k4 * (1.0 / 41.0));33 34  vec4 o3_interp_z = o2 * d.z + o1 * (1.0 - d.z);35  vec2 o4_interp_xy = o3_interp_z.yw * d.x + o3_interp_z.xz * (1.0 - d.x);36 37  return o4_interp_xy.y * d.y + o4_interp_xy.x * (1.0 - d.y);38}39 40void main() {41  float brightness = 2.5;42  float red_balance = 1.0;43  float green_balance = 0.85;44  float blue_balance = 1.0;45 46  float phosphorWidth = 2.50;47  float phosphorHeight = 4.50;48  float internalHorizontalGap = 1.0;49  float columnGap = 0.2;50  float verticalCellGap = 0.2;51  float phosphorPower = 0.9;52 53  float cell_noise_variation_amount = 0.025;54  float cell_noise_scale_xy = 240.0;55  float cell_noise_speed = 24.0;56  float curvature_amount = 0.0;57 58  vec2 fragCoord = gl_FragCoord.xy;59  vec2 uv = outTexCoord;60  vec2 centered_uv_output = uv - 0.5;61  float r = length(centered_uv_output);62  float distort_factor = 1.0 + curvature_amount * r * r;63  vec2 centered_uv_source = centered_uv_output * distort_factor;64  vec2 source_uv = centered_uv_source + 0.5;65  vec2 fragCoord_warped = source_uv * resolution;66 67  bool is_on_original_flat_screen = source_uv.x >= 0.0 && source_uv.x <= 1.0 &&68                                   source_uv.y >= 0.0 && source_uv.y <= 1.0;69 70  if (!is_on_original_flat_screen) {71    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);72    return;73  }74 75  float fullCellWidth = 3.0 * phosphorWidth + 3.0 * internalHorizontalGap + columnGap;76  float fullRowHeight = phosphorHeight + verticalCellGap;77 78  float logical_cell_index_x = floor(fragCoord_warped.x / fullCellWidth);79  float shift_y_offset = 0.0;80  81  if (mod(logical_cell_index_x, 2.0) != 0.0) {82    shift_y_offset = fullRowHeight / 2.0;83  }84  85  float effective_y_warped = fragCoord_warped.y + shift_y_offset;86  float logical_row_index = floor(effective_y_warped / fullRowHeight);87 88  float uv_cell_x = mod(fragCoord_warped.x, fullCellWidth);89  if (uv_cell_x < 0.0) {90    uv_cell_x += fullCellWidth;91  }92  93  float uv_row_y = mod(effective_y_warped, fullRowHeight);94  if (uv_row_y < 0.0) {95    uv_row_y += fullRowHeight;96  }97 98  vec3 video_color = texture2D(uMainSampler, source_uv).rgb;99  video_color.r *= red_balance;100  video_color.g *= green_balance;101  video_color.b *= blue_balance;102 103  vec3 final_color = vec3(0.0);104  bool in_column_gap = uv_cell_x >= (3.0 * phosphorWidth + 3.0 * internalHorizontalGap);105  bool in_vertical_gap = uv_row_y >= phosphorHeight;106 107  if (!in_column_gap && !in_vertical_gap) {108    float uv_cell_x_within_block = uv_cell_x;109    vec3 phosphor_base_color = vec3(0.0);110    float video_component_intensity = 0.0;111    float current_phosphor_startX_in_block = -1.0;112    float current_x_tracker = 0.0;113 114    if (uv_cell_x_within_block >= current_x_tracker && uv_cell_x_within_block < current_x_tracker + phosphorWidth) {115      phosphor_base_color = vec3(1.0, 0.0, 0.0);116      video_component_intensity = video_color.r;117      current_phosphor_startX_in_block = current_x_tracker;118    }119    current_x_tracker += phosphorWidth + internalHorizontalGap;120 121    if (uv_cell_x_within_block >= current_x_tracker && uv_cell_x_within_block < current_x_tracker + phosphorWidth) {122      phosphor_base_color = vec3(0.0, 1.0, 0.0);123      video_component_intensity = video_color.g;124      current_phosphor_startX_in_block = current_x_tracker;125    }126    current_x_tracker += phosphorWidth + internalHorizontalGap;127 128    if (uv_cell_x_within_block >= current_x_tracker && uv_cell_x_within_block < current_x_tracker + phosphorWidth) {129      phosphor_base_color = vec3(0.0, 0.0, 1.0);130      video_component_intensity = video_color.b;131      current_phosphor_startX_in_block = current_x_tracker;132    }133 134    if (current_phosphor_startX_in_block >= 0.0) {135      float x_in_phosphor = (uv_cell_x_within_block - current_phosphor_startX_in_block) / phosphorWidth;136      float horizontal_intensity_factor = pow(sin(x_in_phosphor * PI), phosphorPower);137      float y_in_phosphor_band = uv_row_y / phosphorHeight;138      float vertical_intensity_factor = (phosphorHeight > 0.0) ? pow(sin(y_in_phosphor_band * PI), phosphorPower) : 1.0;139      float total_intensity_factor = horizontal_intensity_factor * vertical_intensity_factor;140      final_color = phosphor_base_color * video_component_intensity * total_intensity_factor;141    }142  }143 144  vec3 noise_pos = vec3(logical_cell_index_x * cell_noise_scale_xy,145                        logical_row_index * cell_noise_scale_xy,146                        time * cell_noise_speed);147 148  vec3 cell_noise_rgb;149  cell_noise_rgb.r = noise3d(noise_pos);150  cell_noise_rgb.g = noise3d(noise_pos + vec3(19.0, 0.0, 0.0));151  cell_noise_rgb.b = noise3d(noise_pos + vec3(0.0, 13.0, 0.0));152  cell_noise_rgb = cell_noise_rgb * 2.0 - 1.0;153  final_color += cell_noise_rgb * cell_noise_variation_amount;154 155  final_color *= brightness;156  float edge_darken_strength = 0.1;157  float vignette_factor = 1.0 - dot(centered_uv_output, centered_uv_output) * edge_darken_strength * 2.0;158  vignette_factor = clamp(vignette_factor, 0.0, 1.0);159  final_color *= vignette_factor;160 161  final_color = clamp(final_color, 0.0, 1.0);162  gl_FragColor = vec4(final_color, 1.0);163}164`;165 166export default class TrinitronPipeline extends Phaser.Renderer.WebGL.Pipelines.PostFXPipeline {167  constructor(game) {168    super({169      name: 'TrinitronPipeline',170      game: game,171      renderTarget: true,172      fragShader: fragShader,173      uniforms: [174        'uMainSampler',175        'resolution',176        'time'177      ]178    });179  }180 181  onPreRender() {182    // Use the actual canvas display size (after scaling), not the game resolution183    const canvas = this.game.canvas;184    const displayWidth = canvas.width;185    const displayHeight = canvas.height;186    this.set2f('resolution', displayWidth, displayHeight);187    this.set1f('time', this.game.loop.time / 1000);188  }189}190 191