stream-render-farm/render-farm-calculator.html

279 lines
8.7 KiB
HTML
Raw Normal View History

2026-07-18 21:32:55 +02:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Render Farm Throughput Calculator • stream.4ort.net</title>
<style>
:root { --bg: #050505; --fg: #e0e0e0; --accent: #7aa2f7; --border: #1a1a1a; --muted: #666; }
* { box-sizing: border-box; }
body {
background: var(--bg);
color: var(--fg);
font-family: system-ui, -apple-system, sans-serif;
margin: 0;
padding: 3rem;
line-height: 1.6;
}
.container { max-width: 980px; margin: 0 auto; }
header {
border-left: 3px solid var(--accent);
padding-left: 2rem;
margin-bottom: 3rem;
}
h1 {
font-size: 2.8rem;
letter-spacing: -0.05em;
margin: 0 0 0.5rem 0;
line-height: 1.1;
}
.subtitle {
font-size: 1rem;
opacity: 0.7;
margin-bottom: 1rem;
font-family: monospace;
}
.tool-section {
background: rgba(26, 26, 26, 0.3);
border: 1px solid var(--border);
padding: 2rem;
border-radius: 4px;
margin: 2rem 0;
}
.input-group {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
align-items: baseline;
margin-bottom: 1rem;
}
label {
font-family: monospace;
font-size: 0.9rem;
opacity: 0.8;
}
input[type="number"] {
background: var(--bg);
border: 1px solid var(--border);
color: var(--fg);
padding: 0.5rem 1rem;
font-family: monospace;
font-size: 1rem;
width: 100%;
border-radius: 2px;
}
input[type="number"]:focus {
outline: none;
border-color: var(--accent);
}
button {
background: var(--accent);
color: var(--bg);
border: none;
padding: 0.75rem 2rem;
font-family: monospace;
font-size: 1rem;
font-weight: bold;
cursor: pointer;
border-radius: 2px;
transition: all 0.15s ease;
}
button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(122, 162, 247, 0.3);
}
.results {
margin-top: 2rem;
padding-top: 2rem;
border-top: 1px solid var(--border);
}
.result-row {
display: flex;
justify-content: space-between;
padding: 0.75rem 0;
border-bottom: 1px dashed var(--border);
font-family: monospace;
}
.result-row:last-child { border-bottom: none; }
.result-label { opacity: 0.7; }
.result-value { font-weight: bold; color: var(--accent); }
.formula-box {
background: rgba(122, 162, 247, 0.05);
border: 1px solid var(--accent);
padding: 1.5rem;
margin: 2rem 0;
font-family: monospace;
font-size: 0.9rem;
}
.formula-box h3 {
margin-top: 0;
color: var(--accent);
font-size: 1rem;
margin-bottom: 1rem;
}
.citation {
font-size: 0.75rem;
opacity: 0.5;
margin-top: 1rem;
font-family: monospace;
}
nav.nav {
margin-top: 3rem;
padding-top: 2rem;
border-top: 1px solid var(--border);
font-size: 0.85rem;
opacity: 0.6;
}
nav.nav a {
color: var(--accent);
text-decoration: none;
margin-right: 1.5rem;
}
.error {
color: #ff6b6b;
font-family: monospace;
font-size: 0.85rem;
margin-top: 1rem;
}
</style>
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<div class="container">
<header>
<h1>RENDER FARM THROUGHPUT CALCULATOR</h1>
<div class="subtitle">Q382597 // Q7798498 — COMPUTE CAPACITY PLANNING ENGINE</div>
<p>Compute total frames rendered per hour given node count, GPU throughput, and scene complexity. Grounded in Wikidata definitions of render farm architecture and throughput rate.</p>
</header>
<div class="formula-box">
<h3>CORE FORMULA</h3>
<p><strong>T = N × (F ÷ S) × 3600</strong></p>
<p style="margin-top: 1rem; opacity: 0.8;">Where:<br>
T = Total frames per hour<br>
N = Number of nodes in cluster<br>
F = Frames per second per GPU (base throughput)<br>
S = Scene complexity factor (1.0 = reference scene)<br>
3600 = Seconds per hour</p>
</div>
<div class="tool-section">
<h3 style="color: var(--accent); margin-top: 0;">INPUT PARAMETERS</h3>
<div class="input-group">
<label for="nodes">NODE COUNT (N)</label>
<input type="number" id="nodes" placeholder="e.g., 64" min="1" step="1">
</div>
<div class="input-group">
<label for="fps_per_gpu">FPS PER GPU (F)</label>
<input type="number" id="fps_per_gpu" placeholder="e.g., 24" min="0.1" step="0.1">
</div>
<div class="input-group">
<label for="complexity">SCENE FACTOR (S)</label>
<input type="number" id="complexity" placeholder="e.g., 2.5" min="0.1" step="0.1" value="1.0">
</div>
<button onclick="calculateThroughput()">COMPUTE THROUGHPUT</button>
<div id="error-msg" class="error"></div>
</div>
<div class="results" id="results" style="display: none;">
<h3 style="color: var(--accent);">CALCULATED OUTPUT</h3>
<div class="result-row">
<span class="result-label">FRAMES PER HOUR</span>
<span class="result-value" id="frames-per-hour">-</span>
</div>
<div class="result-row">
<span class="result-label">SECONDS PER FRAME</span>
<span class="result-value" id="seconds-per-frame">-</span>
</div>
<div class="result-row">
<span class="result-label">MINUTES PER FRAME</span>
<span class="result-value" id="minutes-per-frame">-</span>
</div>
<div class="result-row">
<span class="result-label">HOURLY THROUGHPUT (T⁻¹)</span>
<span class="result-value" id="hourly-rate">-</span>
</div>
<div class="result-row">
<span class="result-label">EST. RENDER TIME FOR 1-HOUR SEQUENCE</span>
<span class="result-value" id="sequence-time">-</span>
</div>
</div>
<div class="citation">
SOURCE: Wikidata Q382597 (render_farm), Q7798498 (throughput) — CC0<br>
DATA: render-farm-calculator.json | ARCHITECTURE: render-farm-architecture.html | SPEC: render-farm-spec.html
</div>
<nav class="nav">
<a href="index.html">INDEX</a>
<a href="render-farm-architecture.html">ARCHITECTURE</a>
<a href="render-farm-spec.html">SPECIFICATION</a>
<a href="throughput-q7798498.html">THROUGHPUT</a>
<a href="recovery-protocol.html">RECOVERY</a>
</nav>
</div>
<script>
function calculateThroughput() {
const errorMsg = document.getElementById('error-msg');
const resultsDiv = document.getElementById('results');
errorMsg.textContent = '';
resultsDiv.style.display = 'none';
const N = parseFloat(document.getElementById('nodes').value);
const F = parseFloat(document.getElementById('fps_per_gpu').value);
const S = parseFloat(document.getElementById('complexity').value);
if (!N || N <= 0) {
errorMsg.textContent = 'ERROR: Node count must be positive integer.';
return;
}
if (!F || F <= 0) {
errorMsg.textContent = 'ERROR: FPS per GPU must be positive.';
return;
}
if (!S || S <= 0) {
errorMsg.textContent = 'ERROR: Scene complexity factor must be positive.';
return;
}
// Core calculation: T = N × (F ÷ S) × 3600
const effectiveFPSPerNode = F / S;
const totalFPS = N * effectiveFPSPerNode;
const framesPerHour = totalFPS * 3600;
// Time per frame in seconds
const secondsPerFrame = S / F;
const minutesPerFrame = secondsPerFrame / 60;
// Hourly throughput rate (T⁻¹ dimension)
const hourlyRate = framesPerHour;
// Estimate for 1-hour sequence (assuming 24fps output = 86400 frames)
const sequenceFrames = 86400; // 24 fps × 3600 seconds
const sequenceHours = sequenceFrames / framesPerHour;
const sequenceMinutes = sequenceHours * 60;
document.getElementById('frames-per-hour').textContent = framesPerHour.toPrecision(6) + ' fr/hr';
document.getElementById('seconds-per-frame').textContent = secondsPerFrame.toFixed(4) + ' s';
document.getElementById('minutes-per-frame').textContent = minutesPerFrame.toFixed(6) + ' min';
document.getElementById('hourly-rate').textContent = hourlyRate.toPrecision(6) + ' T⁻¹';
document.getElementById('sequence-time').textContent = `${sequenceHours.toFixed(2)} hr (${sequenceMinutes.toFixed(1)} min)`;
resultsDiv.style.display = 'block';
}
</script>
</body>
</html>