The core of `bin/gen-other-html.sh` code that converts entry non-README.md into HTML has been moved into a new tool: `bin/othermd2html.sh`. The `bin/othermd2html.sh` tool will be useful to the `bin/cvt-submission.sh` tool that is under development. Added info about `bin/othermd2html.sh` to `bin/README.md`. Changed `bin/gen-other-html.sh` VERSION from "1.4.1 2024-08-18" to "1.5 2024-08-27". HTML produced by `bin/gen-other-html.sh` now uses a "jump to" mid-bar test now shows the `YYYY/dir/index.html` link text (with `YYYY/dir/` added). Performed `make gen_other_html` to accomplish the above and to test under macOS. Performed `make gen_top_html` to accomplish the above and to test under macOS.
867 lines
31 KiB
HTML
867 lines
31 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||
<!-- START: two lines up starts content from: inc/top.default.html -->
|
||
|
||
<!-- END: this line ends content from: inc/top.default.html -->
|
||
<!-- START: this line starts content from: inc/head.default.html -->
|
||
|
||
<head>
|
||
<link rel="stylesheet" href="../../../ioccc.css">
|
||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" rel="stylesheet">
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||
<title>The International Obfuscated C Code Contest</title>
|
||
<link rel="icon" type="image/x-icon" href="../../../favicon.ico">
|
||
<meta name="description" content="example.md for 2013/hou">
|
||
<meta name="keywords" content="IOCCC, 2013/hou, example.md">
|
||
</head>
|
||
|
||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
|
||
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
|
||
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
|
||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||
|
||
<!-- END: this line ends content from: inc/head.default.html -->
|
||
|
||
<!-- -->
|
||
<!-- This web page was formed via the tool: bin/gen-other-html.sh -->
|
||
<!-- The content of main section of this web page came from: 2013/hou/doc/example.md -->
|
||
<!-- -->
|
||
|
||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||
<!-- !!! Do not modify this web page, instead modify the file: 2013/hou/doc/example.md !!! -->
|
||
<!-- !!! Do not modify this web page, instead modify the file: 2013/hou/doc/example.md !!! -->
|
||
<!-- !!! Do not modify this web page, instead modify the file: 2013/hou/doc/example.md !!! -->
|
||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||
|
||
<!-- Markdown content was converted into HTML via the tool: bin/md2html.sh -->
|
||
|
||
<!-- START: this line starts content from: inc/body.default.html -->
|
||
|
||
<body>
|
||
|
||
<!-- END: this line ends content from: inc/body.default.html -->
|
||
<!-- START: this line starts content from: inc/topbar.default.html -->
|
||
|
||
<div class="theader">
|
||
<nav class="topbar">
|
||
<div class="container">
|
||
<div class="logo">
|
||
<a href="../../../index.html" class="logo-link">
|
||
IOCCC
|
||
</a>
|
||
</div>
|
||
|
||
<div class="topbar-items">
|
||
<div class="item">
|
||
<span class="item-header">
|
||
Entries
|
||
</span>
|
||
|
||
<div class="sub-item">
|
||
<div class="outfit-font">
|
||
<a href="../../../years.html" class="sub-item-link">
|
||
Winning Entries
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../authors.html" class="sub-item-link">
|
||
Winning Authors
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../location.html" class="sub-item-link">
|
||
Location of winning authors
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../bugs.html" class="sub-item-link">
|
||
Bugs and (mis)features
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="item">
|
||
<span class="item-header">
|
||
Status
|
||
</span>
|
||
|
||
<div class="sub-item">
|
||
<div class="outfit-font">
|
||
<a href="../../../news.html" class="sub-item-link">
|
||
IOCCC News
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../status.html" class="sub-item-link">
|
||
Contest status
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../next/index.html" class="sub-item-link">
|
||
Rules and Guidelines
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="item">
|
||
<span class="item-header">
|
||
FAQ
|
||
</span>
|
||
|
||
<div class="sub-item">
|
||
<div class="outfit-font">
|
||
<a href="../../../faq.html" class="sub-item-link">
|
||
FAQ
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../faq.html#submit" class="sub-item-link">
|
||
How to enter the IOCCC
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../faq.html#fix_an_entry" class="sub-item-link">
|
||
Fixing IOCCC entries
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../faq.html#fix_web_site" class="sub-item-link">
|
||
Fixing the website
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../faq.html#fix_author" class="sub-item-link">
|
||
Updating author info
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="item">
|
||
<span class="item-header">
|
||
About
|
||
</span>
|
||
|
||
<div class="sub-item">
|
||
<div class="outfit-font">
|
||
<a href="../../../index.html" class="sub-item-link">
|
||
IOCCC Home
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../judges.html" class="sub-item-link">
|
||
The IOCCC Judges
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../contact.html" class="sub-item-link">
|
||
Contacting the IOCCC
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../SECURITY.html" class="sub-item-link">
|
||
IOCCC Security Policy
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../thanks-for-help.html" class="sub-item-link">
|
||
Thanks for the help
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../../markdown.html" class="sub-item-link">
|
||
IOCCC markdown guidelines
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="header-mobile-menu">
|
||
<noscript>
|
||
<a href="../../../nojs-menu.html" class="topbar-js-label">
|
||
Please Enable JavaScript
|
||
</a>
|
||
</noscript>
|
||
|
||
<button id="header-open-menu-button" class="topbar-mobile-menu">
|
||
<img
|
||
src="../../../png/hamburger-icon-open.png"
|
||
alt="hamburger style menu icon - open state"
|
||
width=48
|
||
height=48>
|
||
</button>
|
||
|
||
<button id="header-close-menu-button" class="hide-content">
|
||
<img
|
||
src="../../../png/hamburger-icon-closed.png"
|
||
alt="hamburger style menu icon - closed state"
|
||
width=48
|
||
height=48>
|
||
</button>
|
||
|
||
<div id="mobile-menu-panel" class="hide-content">
|
||
<div class="mobile-menu-container">
|
||
|
||
<div class="mobile-menu-wrapper">
|
||
<div class="mobile-menu-item">
|
||
Entries
|
||
</div>
|
||
<div class="mobile-submenu-wrapper">
|
||
|
||
<a class="mobile-submenu-item" href="../../../years.html">
|
||
Winning Entries
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../authors.html">
|
||
Authors of winning IOCCC entries
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../location.html">
|
||
Location of authors
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../bugs.html">
|
||
Bugs and (mis)features
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mobile-menu-wrapper">
|
||
|
||
<div class="mobile-menu-item">
|
||
Status
|
||
</div>
|
||
<div class="mobile-submenu-wrapper">
|
||
|
||
<a class="mobile-submenu-item" href="../../../status.html">
|
||
Contest status
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../next/index.html">
|
||
Rules and Guidelines
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../news.html">
|
||
IOCCC News
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mobile-menu-wrapper">
|
||
<div class="mobile-menu-item">
|
||
FAQ
|
||
</div>
|
||
<div class="mobile-submenu-wrapper">
|
||
|
||
<a class="mobile-submenu-item" href="../../../faq.html">
|
||
Frequently Asked Questions
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../faq.html#submit">
|
||
How to enter the IOCCC
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../faq.html#fix_an_entry">
|
||
Fixing IOCCC entries
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../faq.html#fix_web_site">
|
||
Fixing the website
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../faq.html#fix_author">
|
||
Fixing author info
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mobile-menu-wrapper">
|
||
<div class="mobile-menu-item">
|
||
About
|
||
</div>
|
||
<div class="mobile-submenu-wrapper">
|
||
|
||
<a class="mobile-submenu-item" href="../../../index.html">
|
||
IOCCC Home
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../judges.html">
|
||
The IOCCC Judges
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../contact.html">
|
||
Contacting the IOCCC
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../../thanks-for-help.html">
|
||
Thanks for the help
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<script>
|
||
var headerOpenMenuButton = document.getElementById("header-open-menu-button");
|
||
var headerCloseMenuButton = document.getElementById("header-close-menu-button");
|
||
var mobileMenuPanel = document.getElementById("mobile-menu-panel");
|
||
|
||
headerOpenMenuButton.addEventListener("click", () => {
|
||
headerOpenMenuButton.classList.remove("topbar-mobile-menu");
|
||
headerOpenMenuButton.classList.add("hide-content");
|
||
|
||
headerCloseMenuButton.classList.remove("hide-content");
|
||
headerCloseMenuButton.classList.add("topbar-mobile-menu");
|
||
|
||
mobileMenuPanel.classList.remove("hide-content");
|
||
mobileMenuPanel.classList.add("topbar-mobile-panel");
|
||
});
|
||
|
||
headerCloseMenuButton.addEventListener("click", () => {
|
||
headerCloseMenuButton.classList.remove("topbar-mobile-menu");
|
||
headerCloseMenuButton.classList.add("hide-content");
|
||
|
||
mobileMenuPanel.classList.add("hide-content");
|
||
mobileMenuPanel.classList.remove("topbar-mobile-panel");
|
||
|
||
headerOpenMenuButton.classList.add("topbar-mobile-menu");
|
||
headerOpenMenuButton.classList.remove("hide-content");
|
||
});
|
||
</script>
|
||
|
||
<!-- END: this line ends content from: inc/topbar.default.html -->
|
||
<!-- START: this line starts content from: inc/header.default.html -->
|
||
|
||
<div class="header">
|
||
<a href="../../../2011/zucker/index.html">
|
||
<img src="../../../png/ioccc.png"
|
||
alt="IOCCC image by Matt Zucker"
|
||
width=300
|
||
height=110>
|
||
</a>
|
||
<h1>The International Obfuscated C Code Contest</h1>
|
||
<h2>example.html for 2013/hou</h2>
|
||
</div>
|
||
|
||
<!-- END: this line ends content from: inc/header.default.html -->
|
||
<!-- START: this line starts content from: inc/navbar.up2index.html -->
|
||
|
||
<div class="navbar">
|
||
<a class="Left" href="../index.html">↑ jump to 2013/hou/index.html ↑</a>
|
||
<a class="Right" href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2013%2Fhou%2Fdoc%2Fexample.html">✓</a>
|
||
</div>
|
||
|
||
<!-- END: this line ends content from: inc/navbar.up2index.html -->
|
||
<!-- START: this line starts content from: inc/before-content.default.html -->
|
||
|
||
<div class="content" id="content">
|
||
|
||
<!-- END: this line ends content from: inc/before-content.default.html -->
|
||
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||
|
||
<!-- BEFORE: 1st line of markdown file: 2013/hou/doc/example.md -->
|
||
<p># Scene format documentation</p>
|
||
<p>The file must be encoded in UTF-8 as the BOF marker indicates.</p>
|
||
<p>You can directly feed it to the renderer. If you’re wondering about what the following code block does, that’s why:)</p>
|
||
<pre><code> @|?|?z#
|
||
@|||?z&
|
||
>?Sedvf
|
||
??Tdeu#
|
||
>>Tdeui
|
||
??Tdmmf
|
||
??[[euf
|
||
?}?Oq}e
|
||
?}?Oqqf
|
||
v}?|q}e
|
||
v}?|qqf
|
||
?Sj|?{f
|
||
?Tjk?{e
|
||
FF?Oqq$
|
||
RR?Oqq$
|
||
^^?Oqq$
|
||
jj?Oqq$
|
||
vv?|qq$
|
||
IOBMqqe
|
||
U]BMqqe
|
||
aiBMqqe
|
||
muBMqqe
|
||
EEEJpp%
|
||
QQEJpp%
|
||
]]EJpp%
|
||
iiEJpp%
|
||
uuEJpp%
|
||
ZnY|{|e
|
||
[mZ|\{\{#
|
||
[mZ|||f
|
||
kkdr\{\{\%
|
||
lkdr\{\{></code></pre>
|
||
<h2 id="basic-structure">Basic structure</h2>
|
||
<p>A scene file begins with arbitrary binary data, followed by several shader
|
||
functions.</p>
|
||
<p>Shader functions are declared using a one-character name followed by a <code>]</code>
|
||
character. There are some special function names, which will be explained below.</p>
|
||
<p>The language used to write shader functions is very simple. Basically, you write
|
||
a sequence of assignment statements like this:</p>
|
||
<pre><code> A=A+D
|
||
B=B+E</code></pre>
|
||
<p>Namely, you write a one-character variable name, an equal sign (<code>=</code>), followed
|
||
by an expression (made of operators and one-character variable names, of
|
||
course).</p>
|
||
<h2 id="expressions">Expressions</h2>
|
||
<p>The shader language supports seven operators, listed highest priority first:</p>
|
||
<pre><code> */+-<#:</code></pre>
|
||
<p><code>*/+-<</code> each mean what they mean in C, but the priority part is a bit different.
|
||
Basically, <code>*</code> has higher priority than <code>/</code>, so <code>A/4*4</code> actually computes
|
||
<code>A/(4*4)</code>. And you can’t write <code>(A/4)*4</code> – brackets are not supported. As an
|
||
advice, keep your expressions simple :) If you really needs to write something
|
||
like <code>C=(A/4)*4</code>, write instead:</p>
|
||
<pre><code> B=A/4+
|
||
C=B*4</code></pre>
|
||
<p>The <code>#</code> operator acts somewhat like the C <code>?:</code>. It returns one of its two
|
||
operands based on, what else, the value of variable <code>#</code>. When <code>#</code> is true, <code>#</code>
|
||
returns its second operand.</p>
|
||
<p>The <code>:</code> operator calls built-in functions. The first operand is the function id and the second is the parameter. Here is a list of functions:</p>
|
||
<pre><code> 0:x = the x-th byte of the scene file
|
||
1:x = sin(x*PI)
|
||
2:x = atan2(x,#)/PI
|
||
3:x = sqrt(max(x,0))
|
||
4:x = floor(x)
|
||
5:x = the next number in the (allegedly random) number sequence, can't be called in volume shaders
|
||
6:x = value of the variable (char)(120+x)
|
||
7:x = write #'s value to the variable (char)(120+x)</code></pre>
|
||
<p>Contrary to popular belief, the language itself doesn’t support numerical
|
||
constants. Any character sitting between operators is a variable. When you see
|
||
1/2, it’s in fact dividing the variable 1’s value by the variable 2’s value. For
|
||
everyone’s convenience, though, in the beginning every variable is initialized
|
||
to its ASCII code minus 48. As long as you don’t write something like <code>3=1+1</code>,
|
||
you can use single digit numbers as, well, single digit numbers. If you need
|
||
something like <code>1920</code> or <code>0.73</code>, you need to compute it yourself. And yes, all
|
||
variables store floating point values.</p>
|
||
<p>If a character appears as the first character of any <code>argv</code>, it goes to zero.
|
||
This includes the scene filename. If you name your scene <code>1.scene</code>, well, good
|
||
luck with <code>1=0</code>!</p>
|
||
<p>You can terminate a statement using any character that isn’t an operator, be it
|
||
<code>\n</code> or <code>;</code>. But you must put in one and only one character. Put in two (e.g.
|
||
the Windows <code>\r\n</code>), and it terminates your function. Also, the first statement
|
||
must begin immediately after <code>]</code>.</p>
|
||
<p>When a function terminates, the interpreter calls the next function specified by
|
||
variable <code>R</code>. If you want to call function <code>n</code>, just write somewhere:</p>
|
||
<pre><code> R=n</code></pre>
|
||
<p>providing you have left <code>n</code> at its initial value. If you want to actually return
|
||
to the renderer, put in <code>R=0</code>.</p>
|
||
<p>As you may have noticed, you can put in all kinds of stuff between functions,
|
||
like this comment.</p>
|
||
<h2 id="how-the-____-do-i-render-an-image-with-shaders">How the ____ do I render an image with shaders?</h2>
|
||
<p>Basically, you define a geometry using volume shaders, define a camera using a
|
||
camera shader, and define light sources and surface reflectance properties using
|
||
material shaders.</p>
|
||
<h3 id="continue-to-the-comments-before-function-a">Continue to the comments before function A</h3>
|
||
<pre><code> //As an (optional) assignment, figure out what function 'n' does. And why there is a plus sign at every EOL except the last.
|
||
n]#=1+
|
||
x=X+1/2+
|
||
d=0:U;d=d-n;U=U+1;A=d<x;#=#*A+
|
||
d=0:U;d=d-n;U=U+1;A=x<d+1;#=#*A+
|
||
x=Y+1/2+
|
||
d=0:U;d=d-n;U=U+1;A=d<x;#=#*A+
|
||
d=0:U;d=d-n;U=U+1;A=x<d+1;#=#*A+
|
||
x=Z+1/2+
|
||
d=0:U;d=d-n;U=U+1;A=d<x;#=#*A+
|
||
d=0:U;d=d-n;U=U+1;A=x<d+1;#=#*A+
|
||
d=0:U;d=d-n;U=U+1+
|
||
U=U+2+
|
||
C=C#d+3*9+
|
||
#=d+
|
||
R=0#n</code></pre>
|
||
<hr style="width:10%;text-align:left;margin-left:0">
|
||
<p>The function <code>A</code> initializes global settings:</p>
|
||
<pre><code> G -- Image width, in pixels
|
||
H -- Image height, in pixels
|
||
I -- Perturbation probability
|
||
J -- Camera ray stratification probability</code></pre>
|
||
<p>If you have used a MLT renderer before, you probably know what <code>I</code> and <code>J</code> does.
|
||
If you don’t, well, use the same value as the default scene. Everything
|
||
converges just fine under suboptimal settings, just a little slower. Generally,
|
||
use a higher value for <code>I</code> if your scene is primarily illuminated by some
|
||
indirect source.</p>
|
||
<p><code>A</code> also serves as the geometry shader for volume 0. The scene geometry is made
|
||
of up to 32 volumes, each with 64x64x64 cells. The volume 0 is the ‘top level’
|
||
volume where the camera goes. Each cell of a volume can be empty, filled with a
|
||
material, or another volume. The roundish characters in
|
||
<a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2013/hou/old_default.scene">old_default.scene</a> and the carpet on the floor in this
|
||
file are examples where a cell is defined to another volume. Materials will be
|
||
explained later.</p>
|
||
<p>The volume shader for the i-th volume is named as the (i+1)-th capital letter.
|
||
Each volume shader is invoked once for each cell. The cell coordinates (0..63)
|
||
are given as inputs in variable <code>x</code>,<code>y</code>,<code>z</code>, and you’re supposed to return the
|
||
cell content in variable <code>C</code>. To fill it with material <code>i</code>, return <code>64+i</code> in
|
||
<code>C</code>. To fill it with volume <code>i</code>, well, return <code>i</code>. To leave it empty, return
|
||
<code>C=0</code>.</p>
|
||
<p>Before starting to build a scene, it’s better to have a draft sketch handy
|
||
first. Something like:</p>
|
||
<p><img src="draft.png"
|
||
alt="image of the draft sketch of a room with a window"
|
||
width=513 height=487></p>
|
||
<p>Sometimes it’s hard to imagine where something should go without the sketch.
|
||
And you don’t have to stick to your sketch :)</p>
|
||
<p>What motivated my default scene: it was the full moon’s day (a national holiday)
|
||
in China and my parents were planning to renovate their apartment. I rendered
|
||
the image to tell my mom how ridiculous her starry-sky wall paper would look
|
||
like if she used it on every single wall. She ends up using it on just one wall,
|
||
the one facing my bed, to thank me for the effort.</p>
|
||
<h3 id="continue-to-the-comments-before-function-a-1">Continue to the comments before function a</h3>
|
||
<pre><code> //As a bonus, find out what the first line does
|
||
A]#=#-#;"=7:0-p+^;#="+
|
||
R=n+
|
||
G=p*:+
|
||
#=0<B+
|
||
G=G*2#G+
|
||
H=G*3/4+
|
||
I=4/5+
|
||
J=1/2+
|
||
C=p+1+
|
||
U=w+w+w</code></pre>
|
||
<hr style="width:10%;text-align:left;margin-left:0">
|
||
<p>The function <code>a</code> is the camera shader, which, well, generates the camera ray.
|
||
It’s supposed to return the ray in variables <code>UVWXYZ</code> and <code>ABCDEF</code> (that may
|
||
sound like a lot of variables, but it really isn’t that much).</p>
|
||
<p>Here comes some subtlety of <code>PSSMLT</code> (Primary Sample Space Metropolis Light
|
||
Transport, or Kelemen-style MLT). Basically, a <code>PSSMLT</code> renderer gives you an
|
||
(allegedly random) number sequence, and you compute a color out of it. This is
|
||
usually done by generating and tracing rays out of those random numbers. The
|
||
renderer would assemble the colors into an image.</p>
|
||
<p>Remember the function <code>5</code>? Here it comes. The first two “random” numbers have
|
||
special meaning and must specify a point on the image plane <code>[0,1)x[0,1)</code>.
|
||
You’re supposed to transform the image plane to the 3D space, choose a point for
|
||
the camera, and shoot a ray from the camera point to the image plane point, see:</p>
|
||
<p><img src="camera.png"
|
||
alt="image of a sketch showing a light ray from an object (person) thru an image plane pixel to a camera viewpoint"
|
||
width=935 height=632></p>
|
||
<p>.. and the ray direction vector (image plane point - camera point) is <code>(X,Y,Z)</code>. For the
|
||
coordinate space, volume 0 is scaled up 64x here to <code>(0,0,0)-(4096,4096,4096)</code>.</p>
|
||
<p>For a basic camera shader example, check <a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2013/hou/otherroom.scene">otherroom.scene</a>.</p>
|
||
<p>If any ray goes out of volume 0, the renderer crashes. Make sure it doesn’t
|
||
happen. Wall up everything.</p>
|
||
<p>Variables <code>ABCDEF</code> control the color returned from the ray. They will be
|
||
explained in the material shaders part. For now, just put in:</p>
|
||
<pre><code> A=0;B=0;C=0
|
||
D=1;E=1;F=1</code></pre>
|
||
<h3 id="continue-to-the-comments-before-function-1">Continue to the comments before function 1</h3>
|
||
<pre><code> a]R=0+
|
||
X=5:5+
|
||
Y=5:5+
|
||
X=X-1/2+
|
||
Y=Y-1/2+
|
||
x=5:5+
|
||
y=5:5+
|
||
x=x-1/2+
|
||
y=y-1/2+
|
||
x=x*8*7;y=y*8*7+
|
||
X=X*G+
|
||
Y=Y*H+
|
||
Z=H*2/3+
|
||
d=4*;+
|
||
d=d*p/Z+
|
||
X=x+X*d+
|
||
Y=y+Y*d+
|
||
Z=Z*d+
|
||
U=p*p/2-p*2+x+
|
||
V=p*p/2+p*1-y+
|
||
W=p*8+
|
||
A=0;B=0;C=0+
|
||
D=1;E=1;F=1</code></pre>
|
||
<hr style="width:10%;text-align:left;margin-left:0">
|
||
<p>The numbered functions define materials, i.e., surface reflectance properties.
|
||
As the name suggests, the shader simulates ray-surface interaction. It’s done by
|
||
updating <code>UVWXYZABCDEF</code>, of course.</p>
|
||
<p><code>ABCDEF</code> define colors. <code>(A,B,C)</code> is the RGB irradiance ultimately returned to
|
||
the renderer, and <code>(D,E,F)</code> maintain the cumulative RGB reflectance of the
|
||
current ray path. This may sound confusing, but basically, if the surface is a
|
||
light source, you accumulate the current path reflectance <code>(D,E,F)</code>, multiplied
|
||
by the light strength, to <code>(A,B,C)</code>. See shader 6 for an example.</p>
|
||
<p>If you want a colored surface, use its color to modulate <code>(D,E,F)</code>, i.e.
|
||
<code>D=D*red;E=E*green;F=F*blue</code>, easy as that. To get some texturing, compute the
|
||
color procedurally or look up a binary table.</p>
|
||
<p>There’s something subtle about colors. To go along with the trend, the renderer
|
||
follows the practice of linear rendering with a gamma of <code>2</code>. Stripping the
|
||
fancy jargon, that basically means after picking a color in your favorite image
|
||
editing program, you need to convert the RGB values from 0..255 to 0..1, and
|
||
then put here its <em>square</em>. Only after squaring you get your real, lively color
|
||
in the output image, as opposed to something dull and gray. You need to do the
|
||
same if you use a RGB texture. And yes, that is the what the second <code>sqrt(3)</code> in
|
||
<code>a.c</code> is for.</p>
|
||
<p>Going beyond colors, to define a shiny or dull surface one needs more maths, and
|
||
optics. The jargon for this is <code>BRDF</code> (Bidirectional Reflectance Distribution
|
||
Function) importance sampling. Let’s continue to function <code>o</code>.</p>
|
||
<h3 id="continue-to-the-comments-before-function-o">Continue to the comments before function o</h3>
|
||
<pre><code> //This function computes the starred wallpaper
|
||
//Original color: 0.36 0.714285 0.8
|
||
1]R=o+
|
||
d=p*6+
|
||
x=U+W+
|
||
x=4:x/d+
|
||
z=4:V/d+
|
||
#=3*x-4*z+
|
||
y=4:#/5+
|
||
#=#-y*5+
|
||
y=1#0+
|
||
x=x*d+d/2-U+W+
|
||
z=z*d+d/2-V+
|
||
r=3:x*x+z*z+
|
||
#=z+
|
||
u=2:x+
|
||
d=1:u*5+
|
||
d=d*d*d+3/2+
|
||
d=d*p+
|
||
#=r<d+
|
||
#=#*y+
|
||
d=2/5#I+
|
||
D=D*d+
|
||
E=E*4/7+
|
||
d=I#2/5+
|
||
F=F*d</code></pre>
|
||
<hr style="width:10%;text-align:left;margin-left:0">
|
||
<p>Function <code>o</code> defines a diffuse (that is, dull) surface. To define reflectance
|
||
properties like this, one needs to sample an outgoing ray direction, based on
|
||
the incoming direction and the surface normal. It’s called importance sampling,
|
||
because here the probability of each outgoing direction has to be proportional
|
||
to the reflected light strength (i.e., the <code>BRDF</code>) on that direction. For a
|
||
diffuse surface, sample the upper hemisphere with a probability proportional to
|
||
the cosine of the outgoing angle, see <img src="cosine.png"
|
||
alt="image of a sketch of a ray a angle theta from the vertical normal with cosine theta below it"
|
||
width=935 height=632>.</p>
|
||
<p>The incoming direction is in <code>(X,Y,Z)</code> and the hit point is <code>(U,V,W)</code>. The
|
||
outgoing direction is returned in, where else, <code>(X,Y,Z)</code>.</p>
|
||
<p>The surface normal is provided in variables <code>S</code> and <code>T</code>. Since the geometry is
|
||
defined as a bunch of cube-shaped cells, there are only 6 possible normals:
|
||
<code>(±1,0,0) (0,±1,0) (0,0,±1)</code>. Here <code>S</code> is the sign and <code>T</code> is the dimension. If
|
||
you get <code>S=-1</code> and <code>T=1</code>, the normal is <code>(0,-1,0)</code>.</p>
|
||
<p>If you don’t want to redo all the math yourself… this file provides a few simple shader functions:</p>
|
||
<pre><code> o -- Diffuse surface. Do the color thing your self and call R=o
|
||
5 -- Perfect mirror.
|
||
f -- Surface with a Fresnel term. Basically, it resembles a polished surface made from a dielectric material.</code></pre>
|
||
<p>For something more complex like a fluffy carpet, well, you could use a volume to
|
||
directly model the
|
||
<a href="https://en.wikipedia.org/wiki/Mesoscopic_physics">mesoscopic</a> detail. Shader
|
||
<code>D</code> in this file produces a bunch of dense, tiny spikes to simulate a fluffy
|
||
appearance.</p>
|
||
<h3 id="continue-to-the-eof">Continue to the EOF</h3>
|
||
<pre><code> //diffuse ray generation
|
||
o]R=0+
|
||
u=5:5+
|
||
v=5:5+
|
||
v=v*2+
|
||
r=3:u+
|
||
z=1:v+
|
||
y=1:1/2+v+
|
||
z=z*r+
|
||
y=y*r+
|
||
x=3:1-u+
|
||
x=0-x*S+
|
||
X=6:T+
|
||
w=x;x=z;z=y;y=w+
|
||
Y=6:T+
|
||
w=x;x=z;z=y;y=w+
|
||
Z=6:T
|
||
|
||
//reflector
|
||
5]R=0+
|
||
x=1;y=1;z=1+
|
||
#=0-1+
|
||
#=7:T+
|
||
X=x*X;Y=y*Y;Z=z*Z
|
||
|
||
//approximate Fresnel, works better than the real thing when you don't want to tweak the IOR
|
||
f]x=X;y=Y;z=Z+
|
||
r=3:x*x+z*z+y*y+
|
||
d=6:T+
|
||
d=1-d*S/r+
|
||
d=d*d*d+
|
||
#=5:5+
|
||
#=d<#+
|
||
R=5#o+
|
||
d=d#1-d+
|
||
u=1#u+
|
||
v=1#v+
|
||
w=1#w+
|
||
D=D*d*u+
|
||
E=E*d*v+
|
||
F=F*d*w
|
||
|
||
//the handles
|
||
B]R=0+
|
||
#=X<8*3+
|
||
C=3#0
|
||
|
||
C]R=0+
|
||
#=X<8*4+
|
||
C=0#4
|
||
|
||
//red-Fresnel
|
||
2]R=f+
|
||
u=1/2;v=1/9;w=v
|
||
|
||
//white-Fresnel and the full moon
|
||
3]R=f+
|
||
u=7*9/p;v=u;w=v+
|
||
x=3*:+8+
|
||
z=U-x*p+p/2+
|
||
x=V-x*p-p/2+
|
||
r=3:x*x+z*z+
|
||
#=4<r/p+
|
||
D=D*I#D+
|
||
E=E*4/7#E+
|
||
F=F*2/5#F+
|
||
d=1/5#0+
|
||
A=A+D*d+
|
||
B=B+E*d+
|
||
C=C+F*d
|
||
|
||
//handle
|
||
4]R=5+
|
||
D=D*I;E=E*4/7;F=F*2/5
|
||
|
||
//light from the window
|
||
6]R=0+
|
||
#=P+
|
||
d=2#8*2+
|
||
A=A+D*d+
|
||
B=B+E*d+
|
||
C=C+F*d*I+
|
||
P=9
|
||
|
||
//carpet
|
||
7]R=o+
|
||
D=D/7+
|
||
E=E/3+
|
||
F=F/7
|
||
|
||
D]R=0+
|
||
#=8<Y+
|
||
C=0#3+
|
||
#=4:3*X-4*Z+
|
||
y=4:#/7+
|
||
#=#-y*7+
|
||
C=7#C</code></pre>
|
||
<hr style="width:10%;text-align:left;margin-left:0">
|
||
<p>The last line, well, is the output filename. Just remember to throw in two <code>]</code>s
|
||
and don’t put a newline after it.</p>
|
||
<pre><code> ]]example.ppm</code></pre>
|
||
<hr style="width:10%;text-align:left;margin-left:0">
|
||
<p>Jump to: <a href="#">top</a></p>
|
||
<!--
|
||
|
||
Copyright © 1984-2024 by Landon Curt Noll. All Rights Reserved.
|
||
|
||
You are free to share and adapt this file under the terms of this license:
|
||
|
||
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
|
||
|
||
For more information, see:
|
||
|
||
https://creativecommons.org/licenses/by-sa/4.0/
|
||
|
||
-->
|
||
<!-- AFTER: last line of markdown file: 2013/hou/doc/example.md -->
|
||
|
||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||
<!-- START: this line starts content from: inc/after-content.default.html -->
|
||
|
||
</div>
|
||
|
||
<!-- END: this line ends content from: inc/after-content.default.html -->
|
||
<!-- START: this line starts content from: inc/footer.default.html -->
|
||
|
||
<!--
|
||
|
||
Copyright © 1984-2024 by Landon Curt Noll. All Rights Reserved.
|
||
|
||
You are free to share and adapt this file under the terms of this license:
|
||
|
||
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
|
||
|
||
For more information, see:
|
||
|
||
https://creativecommons.org/licenses/by-sa/4.0/
|
||
|
||
-->
|
||
|
||
<div class="footer">
|
||
|
||
<div id="copyright"><h3>Copyright © 1984-2024 by Landon Curt Noll:
|
||
<a href="https://creativecommons.org/faq/#what-does-some-rights-reserved-mean"
|
||
target="_blank"
|
||
rel="license noopener noreferrer">Some Rights Reserved</a></h3>
|
||
<p>
|
||
This work is <b>licensed by Landon Curt Noll</b> under
|
||
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1"
|
||
target="_blank"
|
||
rel="license noopener noreferrer"
|
||
style="display:inline-block;">CC BY-SA 4.0</a></b>.
|
||
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
|
||
src="../../../png/cc.png"
|
||
alt="cc inside circle symbol">
|
||
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
|
||
src="../../../png/by.png"
|
||
alt="person inside circle symbol">
|
||
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
|
||
src="../../../png/sa.png"
|
||
alt="arrow looping back on itself inside circle symbol"><br>
|
||
You should <b>carefully review</b> the
|
||
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/legalcode.en"
|
||
target="_blank"
|
||
rel="license noopener noreferrer">CC BY-SA 4.0 LEGAL CODE</a></b>
|
||
before using the licensed material.<br>
|
||
You may wish to review the
|
||
<b><a href="../../../license.html"
|
||
target="_blank"
|
||
rel="license noopener noreferrer">highlights of some of the key features and terms</a></b>
|
||
of <b>CC BY-SA 4.0</b>.<br>
|
||
</p>
|
||
</div>
|
||
|
||
<div id="coda"><h3>Coda</h3>
|
||
<p>
|
||
<a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2013%2Fhou%2Fdoc%2Fexample.html" rel="nofollow">Nu HTML check this web page</a><br>
|
||
<a href="#top">Jump to top</a> <a href="#content">Jump to Content</a>
|
||
</p>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- END: this line ends content from: inc/footer.default.html -->
|
||
<!-- START: this line starts content from: inc/bottom.default.html -->
|
||
|
||
</body>
|
||
</html>
|
||
|
||
<!-- END: this line ends content from: inc/bottom.default.html -->
|