TOC: Of Effects and Shaders
Back: Multiple Textures
Next: Vertexshader Preparations
As promised in Neighbouring Pixels here is how to chain the horizonal and vertical blurs in a way to achieve a perfectly smooth blur in both directions.
The ouput of renderer Pass 1 is taken as a texture whose resolution is set to correspond to the original image. This texture is taken as input to the vertical blurring effect in Pass 2. Like this you can chain any number of effects.
Using this technique you can of course also create effects that take the output they create back via a texture input, thus creating a feedback.
An example for such an application would be Cellular Automata the most popular of which is John Horton Conway's "Game of Life".
Rather than a game it is actually more a simulation based on a grid of cells (much like pixels of a texture) that can either be dead (black) or alive (white). The simulations result is essentially a black texture with some white pixels. Using the result as a starting point for the next generation of the simulation creats a feedback and lets the simulation run forever. Of course this needs an initial state to start from which is realized in this example using the mouse to add living cells, see the according patch in of-effects-and-shaders
The Game of Life has 3 simple rules:
So in the pixelshader for every pixel we have to count its living neighbours and decide according to the rules if the pixel will live or be dead in the next generation.
float2 PixelSize; float4 PS(vs2ps In): COLOR { //sample the current pixel float4 center = tex2D(Samp, In.TexCd); //prepare pixel offsets for x and y float2 offX = float2 (PixelSize.x, 0); float2 offY = float2 (0, PixelSize.y); //sample neighbours and add up their states float alive = 0; alive += tex2D(Samp, In.TexCd - offY).r; alive += tex2D(Samp, In.TexCd - offY - offX).r; alive += tex2D(Samp, In.TexCd - offY + offX).r; alive += tex2D(Samp, In.TexCd + offY).r; alive += tex2D(Samp, In.TexCd + offY - offX).r; alive += tex2D(Samp, In.TexCd + offY + offX).r; alive += tex2D(Samp, In.TexCd - offX).r; alive += tex2D(Samp, In.TexCd + offX).r; //a dead cell with exactly three live neighbors becomes a live cell (birth). if (center.r == 0 && alive == 3) { center.rgb = 1; } //a live cell with two or three live neighbors stays alive (survival). else if (center.r == 1 && (alive == 3 || alive == 2)) { center.rgb = 1; } //in all other cases, a cell dies or remains dead (overcrowding or loneliness). else { center.rgb = 0; } return center; }
Another important thing to notice in the effect are the sampler state settings:
sampler Samp = sampler_state //sampler for doing the texture-lookup { Texture = (Tex); //apply a texture to the sampler MipFilter = NONE; //sampler states MinFilter = POINT; MagFilter = POINT; };
Note how all the filtering is disabled. This allows the truely working with unique pixels and not letting the graphiccard interpolate between pixels which would make no sense in this application where a pixel must only be black or white, but no shade gray.
anonymous user login
~6d ago
~6d ago
~7d ago
~20d ago
~1mth ago
~1mth ago
~1mth ago
~1mth ago
~1mth ago
~1mth ago