diff --git a/docs/Airbrush/Airbrush.mdx b/docs/Airbrush/Airbrush.mdx index cda4a36..6230391 100644 --- a/docs/Airbrush/Airbrush.mdx +++ b/docs/Airbrush/Airbrush.mdx @@ -40,7 +40,7 @@ its alpha value $\Alpha(\pmb p)$ is equal to blend all the alpha values $\Alpha_ The $\pmb d_i$ is the vector from stamp $i$ and the current pixel. $$ -\Alpha(\pmb p) = 1-\prod_{i=1}^n \left(1-\Alpha_s(\pmb d_i)\right) +\Alpha(\Game) = 1-\prod_{i=1}^n \left(1-\Alpha_s(\pmb d_i)\right) $$ We define "alpha density" value, denoted with small alpha $\alpha$. @@ -51,14 +51,14 @@ Hopefully, the notations remind you of the probability density and probability v Replace the $\Alpha_s(\pmb d_i)$ and we get: $$ -\Alpha(\pmb p) = 1-\prod_{i=1}^n (1-\alpha_s(\pmb d_i) \Delta L) +\Alpha(\bm p) = 1-\prod_{i=1}^n (1-\alpha_s(\bm d_i) \Delta L) $$ So, given any $\alpha_s(\pmb d_i)$ function, we can calculate the stamp strokes' continuous form by substituting the function into the formula. We reuse the old local coordinate, originating at $p_0$, and X and Y axes align to the tangent and normal direction. -So, $\pmb p = (x, y)$ and $\pmb d_i = (x - l_i, y)$ in the coordinate. +So, $\bm p = (x, y)$ and $\bm d_i = (x - l_i, y)$ in the coordinate. The $l_i$ is the X position of stamp i. As $n\rightarrow \infty$ and $\Delta L \rightarrow 0$, and apply [product integral](https://en.wikipedia.org/wiki/Product_integral) (Volterra Integral) on the formula. @@ -72,7 +72,7 @@ But the dot is transparent, and we need to know the alpha value associated with ## Special Alpha Density To get a clearer comprehension of the theory, let's examine a special case. Consider the alpha density value is a constant, -indicating that a stamp stroke's footprint is a consistently transparent dot, defined by the function +indicating that a stamp stroke's footprint is a transparent dot, defined by the function $$ \alpha_s(d) = \begin{cases} @@ -89,7 +89,7 @@ $$ \Alpha(x, y) = 1 - \exp\left(-\int_{d \le R} \alpha_c dl -\int_{d > R} 0 dl \right) $$ -The second integral does not contribute to the expression and can be omitted for simplicity. +The second integral does not contribute to the expression and can be omitted. The first integral $\int_{d \le R}$ represents the integral over the segment of the edge that stamps can cover the current pixel. The segment is marked with thick solid line in the figure below. diff --git a/docs/Basics/Stamp/Stamp.mdx b/docs/Basics/Stamp/Stamp.mdx index 776ec44..5f42b35 100644 --- a/docs/Basics/Stamp/Stamp.mdx +++ b/docs/Basics/Stamp/Stamp.mdx @@ -59,7 +59,7 @@ The distances represent the cumulative length of the edges, and we calculated th By using one of them, the whole rendering process is GPU-accelerated. The best tutorial about parallel prefix sum I've ever found is this free course - [High Performance Computing](https://www.udacity.com/course/high-performance-computing--ud281) by Prof. Rich Vuduc. + [High Performance Computing](https://www.udacity.com/catalog/all/any-price/any-school/any-skill/any-difficulty/any-duration/any-type/relevance/page-1?searchValue=High%20Performance%20Computing) by Prof. Rich Vuduc. The course introduces prefix sum in Lesson 6. @@ -100,16 +100,18 @@ $$ It's not hard to derive $r(x)$ from the figure below. $$ -r(x) = \frac{x}{L}r_1 + \left(1-\frac{x}{L}\right)r_0 +r(x) = \left(1-\frac{x}{L}\right)r_0 + \frac{x}{L}r_1 = r_0 - \cos\theta x $$ $L$ is the length of the current edge. ![xradius](./stamp-xradius.png) By replacing $r(x)$, we get a quadratic equation $ax^2 + bx + c = 0$: $$ -a = 1 - \cos^2\theta; -b = - 2 * (r_0\cos\theta + x_p); -c = x_p^2 + y_p^2 - r_0^2 +\begin{align} +a &= 1 - \cos^2\theta \\ +b &= - 2(r_0\cos\theta + x_p) \\ +c &= x_p^2 + y_p^2 - r_0^2 +\end{align} $$ Remind that $\cos\theta = (r_0 - r_1)/L$. diff --git a/docs/Basics/Stamp/stampRound.frag b/docs/Basics/Stamp/stampRound.frag index cd3babd..9604fed 100644 --- a/docs/Basics/Stamp/stampRound.frag +++ b/docs/Basics/Stamp/stampRound.frag @@ -68,7 +68,7 @@ void main() { vec2 textureCoordinate = (pToCurrStamp/currStampRadius + 1.0)/2.0; // uv coordinate vec4 sampledColor = texture(footprint, textureCoordinate); - // The alpha compositing function, https://en.wikipedia.org/wiki/Alpha_compositing + // The alpha compositing function, wiki: https://en.wikipedia.org/wiki/Alpha_compositing vec4 color; color.a = sampledColor.a + currColor.a * (1.0 - sampledColor.a); color.rgb = (sampledColor.rgb * sampledColor.a + currColor.rgb * currColor.a * (1.0 - sampledColor.a))/color.a; diff --git a/docs/Basics/Stamp/stampRound.vert b/docs/Basics/Stamp/stampRound.vert index 2683732..cd8098e 100644 --- a/docs/Basics/Stamp/stampRound.vert +++ b/docs/Basics/Stamp/stampRound.vert @@ -31,6 +31,7 @@ void main(){ l0 = length0; l1 = length1; + // ----------There's nothing new underneath------------- float cosTheta = (r0 - r1)/distance(p0, p1); if(abs(cosTheta) >= 1.0) return; diff --git a/docs/Proportional-Interval-Stamp/Proportional-Interval-Stamp.mdx b/docs/Proportional-Interval-Stamp/Proportional-Interval-Stamp.mdx index d25e7b5..2b0e7a6 100644 --- a/docs/Proportional-Interval-Stamp/Proportional-Interval-Stamp.mdx +++ b/docs/Proportional-Interval-Stamp/Proportional-Interval-Stamp.mdx @@ -19,10 +19,9 @@ This content is under construction and not peer-reviewed. Learn it under your ow -
-© 2024 Shen Ciao. All rights reserved on this webpage. +© 2024 Shen Ciao. All rights reserved on this webpage (until Shen publishes the paper). Unauthorized use and/or duplication of this material without express and written permission from this site’s author and/or owner is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given to Shen Ciao with appropriate and specific direction to the original content. @@ -31,7 +30,7 @@ Excerpts and links may be used, provided that full and clear credit is given to ::: -## Introduction to stamp patterns +## Stamp patterns ### Fixed interval In the [Stamp](../Basics/Stamp) section, we learned stamp brush and methods to render it. @@ -168,14 +167,59 @@ To overcome this, we need to eliminate this dependency while maintaining the app It's a significant challenge and will require some calculus to solve it. ## Theory -We want the interval to be proportional to radius. -Let's define this in a calculus way! - -Given a polyline and pick one of its edges, cut the edge into infinite small segments with length $\Delta L$. -Each segment has its local coordinate $x$, and we know its radius $r(x) = r_0 - \cos\theta x$. -Within a small segment, define the stamp interval as $\eta r(x)$. -So the number of stamps $\Delta n$ in this segment is $\frac{\Delta L}{\eta r(x)}$. -Sum $\Delta n$ over the edge, we get the number of stamps $n(x)$ on this edge; -sum the number on all edges, we get the count of stamps on the polyline. -So we have the stamp number $n$ grows along the polyline. -Every time this $n$ value hits an integer, we stamp on that point. \ No newline at end of file +Given a polyline, pick one of its edges and divide it into infinitely small segments of length $\Delta x$. +We reuse the old local coordinate system, so each segment has its local coordinate $x$, +and we already know the radius at a segment $r(x) = r_0 - \cos\theta x$. + +![small segment](./small-segment.png) + +We need the stamp interval to be proportional to radius. +Therefore, for each segment, define the stamp interval as $\eta r(x)$. +To find the number of stamps $\Delta N$ in a segment, divide the length by the interval: + +$$ +\Delta n = \frac{\Delta x}{\eta r(x)} +$$ + +To find the number of stamps $\Delta n$ over the edge, we need to integrate $\Delta n$ from 0 to x. + +$$ +n(x) = \int_0^{x} \frac{dx}{\eta r(x)} +$$ + +Given $r(x) = r_0 - \cos\theta x$, we substitute this into the integral and get: + +$$ +\tag{1} n(x) = \frac{1}{\eta \cos\theta} \ln(r_0 - \cos\theta x) \bigg|_0^x = \frac{1}{\eta \cos\theta} \ln (1 - \frac{\cos\theta x}{r_0}) +$$ + +Exchange the dependent and independent variable in formula (1) and get: + +$$ +\tag{2} x(n) = \frac{r_0}{\cos\theta}(1 - e^{\eta\cos\theta n}) +$$ + +As $x = L$, we know the total stamp number on the edge, remind that $\cos\theta L = r_0-r_1$: + +$$ +\tag{3} n(L) = \frac{1}{\eta \cos\theta}\ln \frac{r_0}{r_1} +$$ + +Soon we will use the formula (1)(2)(3) in our code. + +![store](store-n.png) + +How do we place footprint on the polyline? +Imagine a point starts from the first vertex and moves along the polyline. +The stamp number to the first vertex grows with its movement. +Every time the number hits an integer, we place a footprint at this point. + +Remind the figure below in the Stamp section. +Given a point or pixel, we calculate a range on the edge that can cover the point. +We label the two roots with $x_1$ and $x_2$. + +![locate stamp](./locate-stamp.png) + +With the stamp number of each edge $n(L)$, we can prefix sum $n(L)$ the number of stamps from each vertex to the first vertex. +We will store the number into each vertex. +For the current edge, we use $n_0$ and $n_1$ to indicate the stamp number at vertex0 and vertex1. diff --git a/docs/Proportional-Interval-Stamp/locate-stamp.png b/docs/Proportional-Interval-Stamp/locate-stamp.png new file mode 100644 index 0000000..aafedef Binary files /dev/null and b/docs/Proportional-Interval-Stamp/locate-stamp.png differ diff --git a/docs/Proportional-Interval-Stamp/small-segment.png b/docs/Proportional-Interval-Stamp/small-segment.png new file mode 100644 index 0000000..ad33daf Binary files /dev/null and b/docs/Proportional-Interval-Stamp/small-segment.png differ diff --git a/docs/Proportional-Interval-Stamp/store-n.png b/docs/Proportional-Interval-Stamp/store-n.png new file mode 100644 index 0000000..d7254c4 Binary files /dev/null and b/docs/Proportional-Interval-Stamp/store-n.png differ diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 2061a65..dc3d1be 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -96,18 +96,18 @@ export default { hideable: true, }, }, - stylesheets: [ - { - href: 'https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css', - type: 'text/css', - integrity: - 'sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM', - crossorigin: 'anonymous', - }, - ], }, plugins: [ 'raw-loaders', ], + stylesheets: [ + { + href: 'https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css', + type: 'text/css', + integrity: + 'sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM', + crossorigin: 'anonymous', + }, + ], trailingSlash : true } satisfies Config; diff --git a/src/css/custom.css b/src/css/custom.css index edd972d..c3bf21e 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -31,18 +31,10 @@ --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } -.katex-html{ - display: none -} - span.katex-mathml{ font-size: 18px; } -span.katex-display math{ - padding-bottom: 0.7em; -} - figcaption{ text-after-overflow: 0; padding-bottom: 0.0em;