<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://c4engine.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Eric+Lengyel</id>
	<title>C4 Engine Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://c4engine.com/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Eric+Lengyel"/>
	<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Special:Contributions/Eric_Lengyel"/>
	<updated>2026-04-14T18:54:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Texture_Importer&amp;diff=681</id>
		<title>Texture Importer</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Texture_Importer&amp;diff=681"/>
		<updated>2026-03-19T21:01:22Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: /* Texture Map Import Settings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
Texture maps used by the C4 Engine have the &amp;lt;code&amp;gt;.tex&amp;lt;/code&amp;gt; file extension. These texture map resources are created by importing texture images from a subdirectory of the &amp;lt;code&amp;gt;Import&amp;lt;/code&amp;gt; directory using the Texture Importer tool.&lt;br /&gt;
&lt;br /&gt;
The Texture Importer tool supports &amp;lt;code&amp;gt;.tga&amp;lt;/code&amp;gt; files, which may be in 8-bit grayscale, 16-bit color, 24-bit color, or 32-bit color format, with or without RLE compression.&lt;br /&gt;
&lt;br /&gt;
When a texture is imported, a &amp;lt;code&amp;gt;.cfg&amp;lt;/code&amp;gt; file is created in the same folder as the imported texture, and it contains all of the settings that were applied. This file is recognized the next time the texture is imported and used to populate the Import Texture dialog with the settings that were previously used.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All resources imported into the C4 Engine should be placed in a ''subfolder'' of the Import folder, not directly in the Import folder itself.&lt;br /&gt;
&lt;br /&gt;
== Texture Maps ==&lt;br /&gt;
&lt;br /&gt;
[[File:textureimporter.png|right|frame|'''Figure 1.''' The Texture Map Import dialog.]]&lt;br /&gt;
&lt;br /&gt;
To import a texture, either choose Import Texture from the [[C4 Menu]] or invoke the &amp;lt;code&amp;gt;itexture&amp;lt;/code&amp;gt; [''name''] command in the [[Command Console]]. If the menu command is chosen, or the name is omitted from the console command, then the Texture Importer tool will open an Import Texture dialog that lets you select a &amp;lt;code&amp;gt;.tga&amp;lt;/code&amp;gt; file from a subdirectory of the &amp;lt;code&amp;gt;Import&amp;lt;/code&amp;gt; directory. After selecting an image file to import, the Import dialog is opened with the default settings shown in the following figure. These default settings are usually appropriate for ordinary color texture maps.&lt;br /&gt;
&lt;br /&gt;
=== Texture Map Import Settings ===&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Setting|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{HeadingSetting|'''Texture Format'''}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Texture&amp;amp;nbsp;type'''|Selects the OpenGL texture target for this texture map. It can be one of the following values.&lt;br /&gt;
&lt;br /&gt;
* '''2D''' An ordinary 2D texture whose coordinates lie in the range [0, 1] in both dimensions. The width and height of a 2D texture must be a power of two.&lt;br /&gt;
* '''Rect''' A rectangle texture whose coordinates lie in the range [0, width] and [0, height]. The width and height do not need to be a power of two. The rectangle texture type should not be used for texture maps that are to be used in a 3D setting because they will adversely affect performance when minified. Rectangle textures are primarily used for things like user interface images that appear in a 2D setting.&lt;br /&gt;
* '''Cube''' A cube map texture. [[#Cube Maps|See below]].&lt;br /&gt;
* '''Array 2D''' A texture containing an array of 2D images.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Image&amp;amp;nbsp;format'''|Selects the output pixel format for this texture map. It can be one of the following values.&lt;br /&gt;
&lt;br /&gt;
* '''RGBA Color''' The image has four channels: red, green, blue, and alpha.&lt;br /&gt;
* '''Luminance Alpha''' The image has two channels: grayscale luminance and alpha.&lt;br /&gt;
* '''Luminance''' The image has one grayscale channel, and the alpha is always interpreted to be the maximum value.&lt;br /&gt;
* '''Intensity''' The image has one grayscale channel, and the alpha is always interpreted to be equal to the gray value.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Alpha&amp;amp;nbsp;channel'''|Specifies what kind of information is stored in the alpha channel of the texture. It can be one of the following values. (If alpha channel information is specified, then the TGA file being imported must use a 32-bit format.)&lt;br /&gt;
&lt;br /&gt;
* '''None''' There is no information stored in the alpha channel.&lt;br /&gt;
* '''Transparency''' The alpha channel contains transparency information.&lt;br /&gt;
* '''Gloss''' The alpha channel contains a gloss map. Whenever a texture containing a gloss map in the alpha channel is used in a material, any specularity, environment map, or reflection term is modulated by the gloss map.&lt;br /&gt;
* '''Opacity''' The alpha channel contains an opacity map. Whenever a texture containing an opacity map in the alpha channel is used in a material, the opacity is used to linearly interpolate between the diffuse term and the refraction term.&lt;br /&gt;
* '''Glow''' The alpha channel contains glow intensity values that are used by the glow post-processing effect. This should only be used for emission maps.&lt;br /&gt;
* '''Occlusion''' The alpha channel will contain ambient occlusion information. This can be a precomputed channel, or it can be generated when the texture is imported. See the description of the '''Calculate ambient occlusion in alpha''' box below.&lt;br /&gt;
* '''Parallax''' The alpha channel of the import texture contains a height map from which parallax mapping information should be calculated. This is selected automatically if the '''Generate parallax data''' box is checked. If the alpha channel of a normal map in a material contains parallax information, the parallax mapping is applied during all rendering passes.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''S&amp;amp;nbsp;wrap&amp;amp;nbsp;mode'''&lt;br /&gt;
&lt;br /&gt;
'''T&amp;amp;nbsp;wrap&amp;amp;nbsp;mode'''|Specifies what wrap modes to apply to the texture map. They can each be one of the following values.&lt;br /&gt;
&lt;br /&gt;
* '''Repeat''' The texture is addressed using the &amp;lt;code&amp;gt;GL_REPEAT&amp;lt;/code&amp;gt; wrap mode.&lt;br /&gt;
* '''Clamp''' The texture is addressed using the &amp;lt;code&amp;gt;GL_CLAMP_TO_EDGE&amp;lt;/code&amp;gt; wrap mode. If this mode is not available, the &amp;lt;code&amp;gt;GL_CLAMP&amp;lt;/code&amp;gt; is used instead.&lt;br /&gt;
* '''Clamp to Border''' The texture is addressed using the &amp;lt;code&amp;gt;GL_CLAMP_TO_BORDER&amp;lt;/code&amp;gt; wrap mode.&lt;br /&gt;
* '''Mirror Repeat''' The texture is addressed using the &amp;lt;code&amp;gt;GL_MIRRORED_REPEAT&amp;lt;/code&amp;gt; wrap mode.&lt;br /&gt;
* '''Mirror Clamp''' The texture is addressed using the &amp;lt;code&amp;gt;GL_MIRROR_CLAMP_TO_EDGE&amp;lt;/code&amp;gt; wrap mode.&lt;br /&gt;
* '''Mirror Clamp to Border''' The texture is addressed using the &amp;lt;code&amp;gt;GL_MIRROR_CLAMP_TO_BORDER&amp;lt;/code&amp;gt; wrap mode.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Use&amp;amp;nbsp;block&amp;amp;nbsp;compression'''|The output texture is stored in a hardware-recognized compression format. This should be turned on for almost all texture maps for best performance and memory usage. (This setting is ignored if the image format is not RGBA Color, if the width and height of the image are not both multiples of 4, or if generating a normal map with parallax data.)}}&lt;br /&gt;
|-&lt;br /&gt;
{{HeadingSetting|'''Texture Flags'''}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Disable&amp;amp;nbsp;filtering'''|No filtering is applied to this texture map, and point sampling is used instead.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Disable&amp;amp;nbsp;anisotropic&amp;amp;nbsp;filtering'''|Anisotropic filtering is disabled for this texture map, but ordinary bilinear or trilinear filtering is still applied.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Require&amp;amp;nbsp;high-resolution&amp;amp;nbsp;rendering'''|The texture map is always rendered using the highest resolution available, even if the user has selected a lower-quality option in the Graphics Settings dialog.}}&lt;br /&gt;
|-&lt;br /&gt;
{{HeadingSetting|Map/Channel Generation}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Calculate&amp;amp;nbsp;normal&amp;amp;nbsp;map'''|The import texture is treated as a height map from which a normal map should be calculated. Each height is multiplied by the value specified in the '''Height map scale''' field and used to determine the normal vector at each pixel.&lt;br /&gt;
&lt;br /&gt;
In order to access all features of the engine, normal maps should be created by the Texture Importer tool, and not by external programs. You can still use normal maps generated by external tools, but if you do, then you can't have associated parallax maps, horizon maps, or ambient occlusion maps. External normal maps can still be block compressed, but you must check the '''Treat RGB channels as vector''' box.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Generate&amp;amp;nbsp;parallax&amp;amp;nbsp;data'''|When checked in addition to '''Calculate normal map''', the height in the alpha channel is converted into special parallax data used by the engine. The same height map must be stored in all four channels of the import texture.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Generate&amp;amp;nbsp;horizon&amp;amp;nbsp;maps'''|When checked in addition to '''Calculate normal map''', a separate texture is generated that contains horizon map data. This texture has the same name as the normal map, but with a different suffix. If the name of the normal map ends in &amp;lt;code&amp;gt;-nrml&amp;lt;/code&amp;gt;, then this suffix is changed to &amp;lt;code&amp;gt;-hrzn&amp;lt;/code&amp;gt;. Otherwise the suffix &amp;lt;code&amp;gt;-h&amp;lt;/code&amp;gt; is added to the full name of the normal map (excluding the extension &amp;lt;code&amp;gt;.tex&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
A horizon map is applied to a material when the '''Enable horizon mapping''' box is checked in the [[Material Editor]].}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Calculate&amp;amp;nbsp;ambient&amp;amp;nbsp;occlusion&amp;amp;nbsp;in&amp;amp;nbsp;alpha'''|The heights stored in the alpha channel are scaled by the value specified in the '''Height map scale''' field and used to calculate an ambient occlusion factor that is applied in the ambient rendering pass.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Height&amp;amp;nbsp;map&amp;amp;nbsp;scale'''|Specifies a scale that is applied to all height values. A scale factor of 1.0 corresponds to the width of a single texel in the import texture.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Height&amp;amp;nbsp;map&amp;amp;nbsp;channel'''|Selects a channel to be used as the source of the height map for all calculations.}}&lt;br /&gt;
|-&lt;br /&gt;
{{HeadingSetting|'''Options'''}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Output&amp;amp;nbsp;file&amp;amp;nbsp;name'''|Specifies the name of the texture file that will be created. (It should not include the extension.) This usually does not need to be changed from the default setting.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Calculate&amp;amp;nbsp;mipmap&amp;amp;nbsp;levels'''|All mipmap levels for this texture are calculated and stored in the texture resource. Turning this off for textures that are used in a 3D environment can have a negative effect on performance.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Bleed&amp;amp;nbsp;colors&amp;amp;nbsp;for&amp;amp;nbsp;alpha&amp;amp;nbsp;test'''|Causes texels that would fail the alpha test to pick up the color of the nearest texel that passes the alpha test. This process helps remove borders that can appear when alpha-tested textures are rendered. When this setting is checked, the alpha values in lower-resolution mipmaps are also boosted to prevent fade-out of alpha-tested geometries.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Treat&amp;amp;nbsp;RGB&amp;amp;nbsp;channels&amp;amp;nbsp;as&amp;amp;nbsp;vector'''|Mipmaps are calculated for vector data instead of color data. This is useful if you're importing a precomputed normal map as opposed to calculating a normal map from a height field. This box must be checked in order to get block compression for an externally generated normal map.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Scale&amp;amp;nbsp;texture&amp;amp;nbsp;to&amp;amp;nbsp;half&amp;amp;nbsp;resolution'''|The import texture image is reduced to half size in each direction before being processed.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Scale&amp;amp;nbsp;horizon&amp;amp;nbsp;maps&amp;amp;nbsp;to&amp;amp;nbsp;half&amp;amp;nbsp;resolution'''|The horizon map is generated from an import texture image that has been reduced to half size in each direction. Using this option can usually save a significant amount of memory without a noticeable reduction in rendering quality. (If '''Scale texture to half resolution''' is also checked, then both scales are applied, so the horizon map is only one-quarter the size in each direction.)}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Flip&amp;amp;nbsp;image&amp;amp;nbsp;vertically'''|The import texture image is flipped in the vertical direction before being processed.}}&lt;br /&gt;
|-&lt;br /&gt;
{{HeadingSetting|'''Array Texture'''}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Cell count'''|When the '''Texture type''' is set to '''Array 2D''', the cell count setting specifies how many layers the array texture has. The layers should be stacked vertically in the input image, and the total height divided by the cell count must be an integer.}}&lt;br /&gt;
|-&lt;br /&gt;
{{HeadingSetting|'''Skybox Haze'''}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Haze&amp;amp;nbsp;color'''|When checked, the haze color is applied at the bottom of the texture image with the appropriate warping for use as a skybox texture.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Haze&amp;amp;nbsp;elevation'''|Specifies the relative height to which the haze extends above the horizon. (Ignored if '''Haze color''' is not checked.)}}&lt;br /&gt;
|-&lt;br /&gt;
{{HeadingSetting|'''Cursor Data'''}}&lt;br /&gt;
|-&lt;br /&gt;
{{Setting|'''Image&amp;amp;nbsp;center&amp;amp;nbsp;X'''&lt;br /&gt;
&lt;br /&gt;
'''Image&amp;amp;nbsp;center&amp;amp;nbsp;Y'''|If importing a cursor texture, these settings specify the coordinates, in pixels, where the center, or '''hot spot''', of the cursor is located.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Cube Maps ==&lt;br /&gt;
&lt;br /&gt;
A cube map can be imported by creating a single TGA file that contains all six faces of the cube. Each cube face must be square and have a width that is a power of two. The importer supports the four layouts shown in the following table. Each face must have the correct orientation in order for the cube map to work properly, and these are shown in the figures. The ''z'' axis always represents the up direction, and the direction specified in the center of each face represents the axis that points into the image.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Layout|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow|[[File:Cube_hcross.png]]|'''Horizontal Cross.''' The image should be exactly 4 faces in width and 3 faces in height.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow|[[File:Cube_vcross.png]]|'''Vertical Cross.''' The image should be exactly 3 faces in width and 4 faces in height.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow|[[File:Cube_hstrip.png]]|'''Horizontal Strip.''' The image should be exactly 6 faces in width and 1 face in height.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow|[[File:Cube_vstrip.png]]|'''Vertical Strip.''' The image should be exactly 1 face in width and 6 faces in height.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Normal Maps ==&lt;br /&gt;
&lt;br /&gt;
[[File:normalimporter.png|right|frame|'''Figure 2.''' The Normal Map Import dialog.]]&lt;br /&gt;
&lt;br /&gt;
=== Normal Map Import Settings ===&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Setting|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{HeadingSetting|'''Texture Format'''}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Texture Viewer]]&lt;br /&gt;
* [[Material Editor]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Release_Notes_for_Build_149&amp;diff=680</id>
		<title>Release Notes for Build 149</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Release_Notes_for_Build_149&amp;diff=680"/>
		<updated>2025-12-12T07:14:59Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
'''Release date:''' July 8, 2008&lt;br /&gt;
&lt;br /&gt;
* The graphical scripting system in the engine has been replaced with a far more powerful design that supports variables, loops, and conditional execution. All previously existing scripts will continue to run without modification. Details about the new scripting system are too extensive to include here, but they can be found in the [[Script Editor]] article.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;Function::Execute()&amp;lt;/code&amp;gt; function now takes a pointer to the method that is calling it. This allows the function to set the method's boolean result value in the new scripting system.&lt;br /&gt;
&lt;br /&gt;
* The engine's texture format has been changed in this release. The file extension is still &amp;lt;code&amp;gt;.tex&amp;lt;/code&amp;gt;, and the engine can still read the old format. However, in the next release, the old format will no longer be supported. We have included a conversion utility in this release that will scan your Data folder and convert all &amp;lt;code&amp;gt;.tex&amp;lt;/code&amp;gt; files to the new format automatically. All textures that ship with the engine have already been converted. To use the conversion utility, run the engine and type &amp;lt;code&amp;gt;convtex&amp;lt;/code&amp;gt; in the command console. This will convert all &amp;lt;code&amp;gt;.tex&amp;lt;/code&amp;gt; files in your Data folder to the new format in place. '''Be sure that you have a backup copy of your custom textures before running this utility.'''&lt;br /&gt;
&lt;br /&gt;
* The Texture Viewer tool has been renamed to Texture Tool, and all the code that creates textures of any kind has been moved to this plugin. Generated textures (light projections, shadow maps, environment maps, and ambient spaces) are now made using the &amp;lt;code&amp;gt;gentex&amp;lt;/code&amp;gt; console command.&lt;br /&gt;
&lt;br /&gt;
* The ambient space feature has been replaced with a new rendering method for static volumetric ambient occlusion. Ambient spaces are still placed in zones as they were previously, but now they only encode directional occlusion that modulates the ambient light intensity as opposed to encoding the ambient light intensity itself. More ambient lighting capabilities will be added to near-term future releases.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;SceneImportPlugin&amp;lt;/code&amp;gt; class has been changed slightly so that it's possible for an import plugin to display a dialog before importing a scene. (See the Collada import plugin for an example.) The &amp;lt;code&amp;gt;SceneImportPlugin::ImportGeometry()&amp;lt;/code&amp;gt; function now takes a pointer to the editor window as a parameter, and the importer must call the &amp;lt;code&amp;gt;Editor::ImportScene()&amp;lt;/code&amp;gt; function in order to complete the import.&lt;br /&gt;
&lt;br /&gt;
* The Collada importer now offers the option to attempt to import texture maps while it is importing a scene. When this option is turned on, any qualified diffuse map, normal map, gloss map, or emission map specified in a Collada file will be imported with the Texture Tool using the default settings. A texture map qualifies for import if its path name contains &amp;lt;code&amp;gt;/Import/&amp;lt;/code&amp;gt; so that the importer recognizes it as being in the C4 Import folder. If the Collada file specifies the wrap modes for a texture map, then they are respected when a texture map is automatically imported.&lt;br /&gt;
&lt;br /&gt;
* A Cleanup button has been added to the Material Manager. Clicking this button causes all duplicate materials to be merged into one material. Materials are considered equivalent if they produce the same shaders.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; class has been renamed to the &amp;lt;code&amp;gt;Model&amp;lt;/code&amp;gt; class. To update your code, make the case-sensitive global replacements of Entity to Model and entity to model. This will have the effect of inadvertently changing the word &amp;quot;identity&amp;quot; as well, so you'll need to also make the replacement of dmodel to dentity to clean it up.&lt;br /&gt;
&lt;br /&gt;
* A new toggle button has been added to the World Editor that turns display of models on and off. Models are no longer displayed as a bounding box.&lt;br /&gt;
&lt;br /&gt;
* A model registration now takes one more parameter that specifies the human-readable model name to be displayed in the World Editor.&lt;br /&gt;
&lt;br /&gt;
* A new multi-zone referencing system has been implemented that generalizes some older techniques used in the engine for transition zones and effects that span multiple zones. Most of this system is internal to the engine and not exposed to higher-level code, but there's one new addition that game programmers need to be aware of. Model nodes have always automatically reparented themselves to the zones that contain them as they move around, but now when a model exits a zone, it also attaches a special reference to the zone that survives until the model's bounding volume has completely left the zone. This allows large models to span multiple zones and to be correctly identified by the visibility determination system. The whole thing is automated, so no code needs to be written to take advantage of this feature.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;kEntityAttached&amp;lt;/code&amp;gt; flag, previously used to signify that a model is attached to another model in some way, has been removed from the engine. The Model class now determines whether models are attached to other models automatically.&lt;br /&gt;
&lt;br /&gt;
* Under Windows, the Sound Manager now uses XAudio2 instead of DirectSound. This should be completely transparent to all higher-level code, but you will need to upgrade to the latest version of DirectX. The engine will only compile with the June 2008 DirectX SDK or later.&lt;br /&gt;
&lt;br /&gt;
* The streaming capabilities in the Sound Manager have been generalized so that it's possible to stream sound data from any kind of source. The method for setting up a streaming wave file has changedâ€”see the [[Working with Sound]] article for more information.&lt;br /&gt;
&lt;br /&gt;
* A color scale and bias operation has been added to the post-processing pass. The &amp;lt;code&amp;gt;World::SetFinalColorTransform()&amp;lt;/code&amp;gt; function can be used to specify a scale color S and a bias color B that are applied to the final rendered color C to yield SC + B. The red, green, and blue channels of these colors can be any floating-point values that produce the desired effect. The scale and bias colors only affect rendering of the current world and not the graphical user interface.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;WorldRenderTask()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;InterfaceRenderTask()&amp;lt;/code&amp;gt; functions have been added to the Application class. These functions are called once per frame after the world has been rendered and after the graphical user interface has been rendered, respectively.&lt;br /&gt;
&lt;br /&gt;
* The Display Manager will now allow any window size to be specified by the &amp;lt;code&amp;gt;$displayWidth&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;$displayHeight&amp;lt;/code&amp;gt; variables when running in windowed mode.&lt;br /&gt;
&lt;br /&gt;
* The Node class is now subclassed from Constructable so that custom node types can be defined and properly deserialized. The &amp;lt;code&amp;gt;[http://c4engine.com/docs/System/Constructable_InstallConstructor.html Constructable::InstallConstructor()]&amp;lt;/code&amp;gt; function is used to install a callback function that constructs custom node subclasses.&lt;br /&gt;
&lt;br /&gt;
* Full native support for Xbox 360 controllers under Windows has been added to the Input Manager (using XInput). The demo game code has been updated so that it's possible to play using only the Xbox controller. Better support for DirectInput joysticks has also been added to the Input Manager.&lt;br /&gt;
&lt;br /&gt;
* The movies plugin now allows movies to be played as streams from remote locations. The movie controller and movie panel item now both have check boxes indicating whether the movie name is a URL.&lt;br /&gt;
&lt;br /&gt;
* Movie play position is now synchronized in multiplayer games when new players join.&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Release_Notes_for_Build_116&amp;diff=679</id>
		<title>Release Notes for Build 116</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Release_Notes_for_Build_116&amp;diff=679"/>
		<updated>2025-10-29T04:37:18Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
'''Release date:''' February 28, 2006&lt;br /&gt;
&lt;br /&gt;
* The Get Info dialog in the World Editor has been expanded to include controller and texture mapping settings that used to be shown in separate windows. The Get Info dialog now has multiple tabs, and the Controller tab is always present. Geometries now have tabs for geometry building flags, rendering flags, collision properties, and texturing settings. &lt;br /&gt;
&lt;br /&gt;
* There are now a few additional tabs in the Get Info dialog: General, Properties, and Connectors. The General settings pane allows you to set the name of any node and, for certain types of node, to specify whether it is initially disabled. The Properties pane lets you assign any kind of properties defined by a game to a node. (More about properties below.) The Connectors pane lets you define a list of connectors that can be linked to other nodes. (Connectors are described in the next item.)&lt;br /&gt;
 &lt;br /&gt;
* Implemented a general node connecting interface in the World Editor. There is now a &amp;quot;Select and Connect&amp;quot; tool that causes available connection sites for a node to be displayed along with connectors that point to their targets. Several types of nodes have built-in connectors that can be linked to other nodes for specific purposes, and any node can have an unlimited number of custom connectors defined for it in the Connectors pane of the Get Info dialog. Connectors are identified by a 32-bit (four character) identifier. The built-in connectors are as follows:&lt;br /&gt;
** A zone has two connectors: one called AMBT that connects to an ambient space, and one called FOG that connects to a fog space. &lt;br /&gt;
** A portal has one connector called ZONE that connects to the portal's destination zone. &lt;br /&gt;
** A light has one connector called SHAD that connects to a shadow space. &lt;br /&gt;
** A trigger has one connector called TARG that can connect to any type of node.&lt;br /&gt;
&lt;br /&gt;
* To specify the target of a connector, click on the Select and Connect tool (or press 5) and then select a node for which you want to set an outgoing connection (but don't select the target yet). The available connectors will appear in little boxes containing their identifiers with icons showing what types of node they can be connected to. Click in a box to select a connector, and it will change color and get a thicker outline to indicate that it's selected. Then select the target node and choose Connect Node from the Node menu (or just hit Ctrl-L). You will see a yellowish line with arrowheads pointing from the connector to the center of its target. Connectors from multiple nodes (one connector each) can be selected by using the shift key. This can be useful if, for instance, you want to connect a bunch of zones to the same fog space. (You don't have to use the shift when selecting the zones, but just when selecting the connectors in the zones.) A connector can be broken by selecting it and choosing Unconnect Node from the Node menu (or hitting Ctrl-U).&lt;br /&gt;
&lt;br /&gt;
* There is now a connection marker that can be used simply as a container that holds connectors. This could be useful in cases such as when multiple triggers need to activate the same script. (This replaces the collection node mentioned in the notes for build 112.) &lt;br /&gt;
&lt;br /&gt;
* Added a reference marker node type that lets you reference an external world resource from within a scene graph. In the world editor, the reference marker is represented by a world icon with crosshairs running through it. The position where the crosshairs meet determines where the origin of the external world in placed. The referenced world resource is set in the Get Info box for the reference marker.&lt;br /&gt;
&lt;br /&gt;
* When a world is loaded, reference markers cause external worlds to be brought in as nonpersistent nodes so that they are not saved as part of the referencing world. If the same world is referenced by multiple reference markers, then they share the same object storage; that is, they are instanced. Reference inclusion is ''not'' recursiveâ€”referenced worlds within referenced worlds will not be expanded. This avoids problems with cyclic references, etc.&lt;br /&gt;
&lt;br /&gt;
* There is a toggle button in the World Editor that shows or hides referenced worlds. When it's off, you just see the reference markers. When it's on, you see the reference markers and the instances of the worlds that they reference. Moving or rotating the reference marker also affects the included world (because the included world is attached to the marker as a subtree). You cannot select any part of a referenced world because it doesn't really belong to the world that references it. Changes to referenced worlds must be made in the original file. If you change a referenced world while another world referencing it is also open, you can toggle the referenced world button off and back on again to see the updated version.&lt;br /&gt;
&lt;br /&gt;
* Implemented a general scripting architecture. The scripting system is not based on a scripting language, but is instead designed to execute a tree of operations called methods that can be assembled graphically in the World Editor. A script is assigned to a node by selecting the script controller in the Get Info dialog and then opening the script editor. Details about the script editor can be found on the [[Script Editor]] page.&lt;br /&gt;
&lt;br /&gt;
* A script is normally executed through the activation of the script controller. It is also possible to make a script run immediately upon loading a world by checking a box in the Controller pane of the Get Info dialog.&lt;br /&gt;
&lt;br /&gt;
* By default, a script runs on all machines in a multiplayer game. It can be made to run only on the server, but then each of the script methods must somehow communicate any actions that need to take place on the client machines. This is normally done by sending controller messages from within custom script methods.&lt;br /&gt;
&lt;br /&gt;
* This is only the first version of the scripting system, and additional features will be added in future releases. In particular, conditional execution is script methods is not present, but will be added later. The current scripting system is very extensible because it's possible for the Game Module to define custom script methods, and these appear in the script editor. There is also a new mechanism for accessing controller functionality from within scripts by calling &amp;quot;function&amp;quot; objects, described next.&lt;br /&gt;
&lt;br /&gt;
* Added the ability for controllers to define subclasses of the &amp;lt;code&amp;gt;Function&amp;lt;/code&amp;gt; class that expose various kinds of functionality that can be accessed from a script. There is a script method named &amp;quot;Call Function&amp;quot; that lets you select a function belonging to the controller attached to the method's target node. When you select a function, its configurable settings appear, and these act as the function's parameters. &lt;br /&gt;
&lt;br /&gt;
* Trigger node functionality has been enhanced. A trigger will now call its target controller's &amp;lt;code&amp;gt;Activate()&amp;lt;/code&amp;gt; function whenever it transitions from the unactivated to activated state, and it will call its target controller's &amp;lt;code&amp;gt;Deactivate()&amp;lt;/code&amp;gt; function whenever it transitions from the activated to unactivated state. A trigger can be set to automatically disable itself that first time it is activated, and in this case the &amp;lt;code&amp;gt;Deactivate()&amp;lt;/code&amp;gt; call is not made. It's also possible to specify that a trigger is to be continuously activated as long as an eligible node intersects it, in which case the &amp;lt;code&amp;gt;Activate()&amp;lt;/code&amp;gt; function is called every frame until the trigger is unactivated. &lt;br /&gt;
&lt;br /&gt;
* The Game Module can now define &amp;lt;code&amp;gt;Property&amp;lt;/code&amp;gt; subclasses for whatever reason it needs to, and these can be exposed in the World Editor under the Properties tab of the Get Info dialog. &lt;br /&gt;
&lt;br /&gt;
* Finished implementing the &amp;lt;code&amp;gt;Configurable&amp;lt;/code&amp;gt; base class. Different types of classes that are capable of displaying a configuration interface in the World Editor are subclassed from &amp;lt;code&amp;gt;Configurable&amp;lt;/code&amp;gt;. Currently, the classes that have the configurable functionality are &amp;lt;code&amp;gt;Controller, Property, Method,&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Function&amp;lt;/code&amp;gt;. A configurable class specifies that it has one or more ''settings'' that need to be presented to the user at the appropriate time. There are several types of built-in settings: a boolean (check box) setting, integer/float (slider) settings, a text box, a popup menu, a color box, and a resource picker. New types of settings can be defined by the Game Module. &lt;br /&gt;
&lt;br /&gt;
* Added a movie controller that plays a QuickTime movie into any of the texture map material attributes. The &amp;lt;code&amp;gt;MovieController&amp;lt;/code&amp;gt; class exposes two &amp;lt;code&amp;gt;Function&amp;lt;/code&amp;gt; objects that can be used to play or stop movies from a script. A movie can also be played immediately upon loading a level or it can be played in response to a trigger activating the movie controller. &lt;br /&gt;
&lt;br /&gt;
* Added the &amp;lt;code&amp;gt;MovieElement&amp;lt;/code&amp;gt; class that plays a QuickTime movie into an interface element. &lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt; node has been updated with more complete functionality. Sound sources can now be placed in a world in a dormant state until they are explicitly played. There are two script methods, &amp;quot;Play Sound Source&amp;quot; and &amp;quot;Stop Sound Source&amp;quot; that play/stop a source node connected to the script's owning node.&lt;br /&gt;
 &lt;br /&gt;
* Implemented a particle rendering technique that I call &amp;quot;sprite quads&amp;quot;. This allows the sprite rendering hardware to be used to render an arbitrarily-oriented quad inside a screen-aligned point sprite. The benefit is that only one quarter of the vertex information needs to be transferred to the GPU for each quad. The expense is a small increase in fill, but this can be alpha-tested to avoid the final write. This technique was used with excellent results in a PS3 technology demo, and it works very well on Nvidia hardware. Unfortunately, the OpenGL spec requires that point sprites be entirely clipped if their centers go outside the view frustum. Nvidia has ignored this requirement (which is good), but ATI adheres to it by clipping point sprites in software (which also means they perform the vertex transform in software). This could make the whole sprite quad technique somewhat useless unless an OpenGL extension can be agreed upon to allow point sprites to be clipped as if they were quads. Of course, with the forthcoming geometry shaders, none of this will really matter.&lt;br /&gt;
 &lt;br /&gt;
* Made several improvements to the joystick support in the Input Manager. More to come, including direct access to the Xbox 360 controller data. &lt;br /&gt;
&lt;br /&gt;
* Added the &amp;lt;code&amp;gt;SetMousePosition()&amp;lt;/code&amp;gt; function to the Interface Manager. &lt;br /&gt;
&lt;br /&gt;
* Added a &amp;quot;world time multiplier&amp;quot; to the Time Manager that can be used to control the rate at which time passes in a game world. The multiplier is initially 1.0 and can be changed by calling the &amp;lt;code&amp;gt;TimeMgr::SetWorldTimeMultiplier()&amp;lt;/code&amp;gt; function. The functions &amp;lt;code&amp;gt;TimeMgr::GetDeltaTime()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;TimeMgr::GetFloatDeltaTime()&amp;lt;/code&amp;gt; now return world time, which is the actual time that has passed multiplied by the world time multiplier. You can still get the unaltered actual time that has passed using the new &amp;lt;code&amp;gt;TimeMgr::GetSystemDeltaTime()&amp;lt;/code&amp;gt; and T&amp;lt;code&amp;gt;imeMgr::GetSystemFloatDeltaTime()&amp;lt;/code&amp;gt; functions. &lt;br /&gt;
&lt;br /&gt;
* Removed the &amp;lt;code&amp;gt;GeometryController&amp;lt;/code&amp;gt; class. A controller which can be assigned to a geometry node no longer needs to be subclassed from &amp;lt;code&amp;gt;GeometryController&amp;lt;/code&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
* Settings for the fluid controller and cloth controller can now be accessed in the Controller pane of the Get Info dialog. &lt;br /&gt;
&lt;br /&gt;
* Added the &amp;lt;code&amp;gt;MoveSubtree()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Descendant()&amp;lt;/code&amp;gt; functions to the &amp;lt;code&amp;gt;Tree&amp;lt;/code&amp;gt; class. &lt;br /&gt;
&lt;br /&gt;
* Added the Strong AA check box to the Font Generator tool. This causes partially filled pixels to be weighted more heavily so that small font sizes can be made more clear. &lt;br /&gt;
&lt;br /&gt;
* If the &amp;lt;code&amp;gt;GL_EXT_timer_query&amp;lt;/code&amp;gt; extension is available (currently, only on Nvidia hardware), then the frame rate window will now display a second graph that shows the amount of time spent rendering on the GPU. This shows the actual GPU load regardless of whether vertical sync is on or off, and it can highlight time spikes that happen only on the CPU.&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Release_Notes_for_Version_2.0&amp;diff=678</id>
		<title>Release Notes for Version 2.0</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Release_Notes_for_Version_2.0&amp;diff=678"/>
		<updated>2025-07-25T23:37:12Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
'''Release date:''' May 31, 2010&lt;br /&gt;
&lt;br /&gt;
== Core Engine ==&lt;br /&gt;
&lt;br /&gt;
=== Physics ===&lt;br /&gt;
&lt;br /&gt;
* This release contains the first version of the native C4 physics architecture. The native physics processing is enabled in a particular world by placing a special &amp;quot;physics node&amp;quot; anywhere in the root zone. The physics node has a physics controller attached to it for which global properties such as the acceleration of gravity can be adjusted. If a world does not contain a physics node in its root zone, then the native C4 physics is completely dormant when that world is played. This allows third-party physics libraries to be used with absolutely no extra cost to bypass the native physics.&lt;br /&gt;
&lt;br /&gt;
* A physics object is created by assigning a rigid body controller to a node and creating one or more &amp;quot;shapes&amp;quot; as subnodes of that node. The shapes define the volume occupied by the physics object as seen by the physics simulation, and they are always fixed relative to each other within a single object. Each shape can have a different density, and the engine automatically calculates properties such as the center of mass and the inertia tensor.&lt;br /&gt;
&lt;br /&gt;
* Rigid bodies can be connected by &amp;quot;joints&amp;quot; to other rigid bodies or to the static environment. Six types of joints are currently defined: spherical, universal, discal, revolute, cylindrical, and prismatic.&lt;br /&gt;
&lt;br /&gt;
* A new node type called a &amp;quot;field&amp;quot; has been added to the engine, and it represents a volume inside of which a force can be applied to physics objects. Forces are applied to objects in a field through the extensible &amp;lt;code&amp;gt;[http://c4engine.com/docs/PhysicsMgr/Force.html Force]&amp;lt;/code&amp;gt; class. After a field has been created in the World Editor, a force can be assigned to that field in the Node Info window. In this release, there are two forces built into the engine, a fluid force and a wind force. The fluid force applies buoyancy and drag, and it can be configured to simulate a current. The wind force applies air drag for a wind current. Custom forces can be defined by creating subclasses of &amp;lt;code&amp;gt;Force&amp;lt;/code&amp;gt; and registering them with the engine.&lt;br /&gt;
&lt;br /&gt;
* A basic mover controller is provided by the engine. This controller moves a rigid body from point A to point B (and handles the reverse direction, too) under script control. This controller can be used to implement things like simple elevators.&lt;br /&gt;
&lt;br /&gt;
=== Terrain ===&lt;br /&gt;
&lt;br /&gt;
* The voxel terrain system now includes a seamless geomip level-of-detail algorithm that is the product of a large R&amp;amp;D project at Terathon. (This is now known as the [https://transvoxel.org/ Transvoxel algorithm].) As terrain is edited, the engine automatically creates lower-resolution terrain geometries and arranges all of the terrain geometry nodes in an octree structure. When terrain is rendered, special polygons are inserted along the boundaries between terrain geometries of different resolutions to produce a smooth transition from high-resolution to lower-resolution meshes. Since voxel terrain is inherently volumetric, this kind of linkage between neighboring meshes can get very complicated, and it was necessary to develop a new algorithm to produce a robust result with real-time performance.&lt;br /&gt;
&lt;br /&gt;
* The terrain-specific shading capabilities of the engine have been modified in this release, partially to accommodate the new terrain LOD system. The four six-sided texture cubes used to specify texture palette entries have been replaced by two sets of three textures, with the three entries in each set representing the (a) up direction, (b) down direction, and (c) all horizontal directions.&lt;br /&gt;
&lt;br /&gt;
* Existing terrains need to be converted in order to retain their previous texture settings and blending information. To convert a terrain block, select all of the terrain geometries in the editor and press Ctrl-R to rebuild them. (The easiest way to select all of the terrain geometries is to select one geometry, press Ctrl-Up-Arrow to select the parent block, and then press Ctrl-Down-Arrow to select all of the block's subnodes.) Some texturing capabilities in the previous version do not translate perfectly into the new scheme, so it's possible that parts of the terrain will have textures different from what they had before. In these cases, it will be necessary to manually paint new materials onto those areas to update the textures.&lt;br /&gt;
&lt;br /&gt;
* The Terrain Texture and Terrain Normal shader processes have been extended so that custom blending of terrain materials is possible. By default, these processes fetch colors from both the primary and secondary terrain textures (where each fetch really represents a triplanar texture blend) and then blends them together using the blend data from the terrain mesh. A new setting has been added that lets you turn off blending and only fetch either the primary or secondary texture. You can then blend the textures any way you want. The default blend is given by a linear interpolation of the primary and secondary textures using the blue component of the vertex color as the interpolation parameter.&lt;br /&gt;
&lt;br /&gt;
* The terrain material painting capabilities have been expanded in this release. Materials can now be specified on a per-voxel basis instead of a per-geometry basis, and the per-voxel blending state has been decoupled from the material IDs. There are now two paint brushes in the editor: one that modifies the blend values, and another that only modifies the materials. There is also a check box that enables material replacement when using any of the other terrain tools.&lt;br /&gt;
&lt;br /&gt;
* The engine can now use a special terrain palette texture resource that references a set of separate 2D texture map resources. This allows many different palettes to share textures from a (possibly large) pool of plain 2D texture maps, and it removes the need to store terrain palettes in two different formats for hardware compatibility. When a terrain palette texture map is loaded, it loads all of the texture maps that it references and assembles them into the optimal format for the available hardware.&lt;br /&gt;
&lt;br /&gt;
=== Shaders ===&lt;br /&gt;
&lt;br /&gt;
* A new shader process called Kill Fragment has been added to the engine. This process can accept one or two scalar inputs, and if the first input is less than the second input, then the current fragment is not rendered. If the second input is omitted, then it is assumed to be zero. This process can be used as a substitute for alpha testing when the alpha output needs to be used for something else like transparency, glow, or bloom.&lt;br /&gt;
&lt;br /&gt;
* A new shader process called Magnitude 3D has been added to the engine. This process takes the dot product of an input vector with itself and outputs the square root of the result.&lt;br /&gt;
&lt;br /&gt;
* A new shader process called Front Normal has been added to the engine. This process takes a normal vector as input and negates its ''z'' component if the ''z'' component of the tangent-space light direction is negative. This is useful when rendering two-sided triangles with a normal map because it has the effect of always facing the normal vector to the front with respect to the light direction.&lt;br /&gt;
&lt;br /&gt;
* The second input for the Set if Less Than and Set if Greater Equal shader processes has been made optional. If the second input is omitted, then it is assumed to be zero.&lt;br /&gt;
&lt;br /&gt;
=== Scripts ===&lt;br /&gt;
&lt;br /&gt;
* A new built-in script method called Terminate External Script has been added to the engine. This method causes all instances of a script running on another node to be terminated immediately.&lt;br /&gt;
&lt;br /&gt;
* A new built-in script method called Get Script Time has been added to the engine. This method outputs the time that has elapsed since a script began running.&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* Support for Unicode text rendering and input has been implemented throughout the engine. Strings are always encoded in UTF-8, and thus ordinary ASCII strings are not affected. The String Importer tool will properly handle any text encoded as UTF-8. The Font Generator tool has been rewritten to support the entire Basic Multilingual Plane of the Unicode Standard. See [[Generating a Font]].&lt;br /&gt;
&lt;br /&gt;
* Tablet support has been added to both the Windows and Mac version of C4. Stylus pressure is now taken into consideration when drawing with the terrain sculpting tools.&lt;br /&gt;
&lt;br /&gt;
* A new type of light source called a &amp;quot;Landscape Light&amp;quot; has been added to the engine. This light type is an infinite light that provides large-scale multiresolution shadow mapping capabilities, enabling shadow maps to be used over areas of unlimited size. The engine smoothly transitions from one resolution to another at adjustable distances from the camera.&lt;br /&gt;
&lt;br /&gt;
* A new flag called &amp;quot;Render at infinity&amp;quot; has been added to the Quad Effect. This causes the quad to be rendered infinitely far away in the direction of the quad's local ''z''-axis. This is useful for placing objects in the sky.&lt;br /&gt;
&lt;br /&gt;
* In order to be directly compatible with the new physics system, all velocities pertaining to sounds are now measured in meters per second by default. This applies to &amp;lt;code&amp;gt;Sound&amp;lt;/code&amp;gt; objects, &amp;lt;code&amp;gt;Source&amp;lt;/code&amp;gt; nodes, and the listener.&lt;br /&gt;
&lt;br /&gt;
* The remote portal node and camera panel item now have a minimum detail level setting. When the engine renders through one of these, the minimum detail level specifies the highest LOD that can be rendered for any particular geometry. The default value is 0, meaning that any LOD can be rendered. Setting the value to a higher number means that only LODs with that index or higher (which have lower detail) can be rendered. This is useful for decreasing the amount of processing that takes place when rendering things like reflections and refractions.&lt;br /&gt;
&lt;br /&gt;
* The velocity-depth-gradient buffer used by the motion blur effect has been changed to 16-bit floating-point color. This allows the higher-quality post-processing effect to be applied at any distance from the camera, and it will open up several new possibilities for other types of effects in future releases.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;wire&amp;lt;/code&amp;gt; console command has been extended so that you can specify whether wireframe lines are depth tested. The command &amp;lt;code&amp;gt;wire 2&amp;lt;/code&amp;gt; turns on wireframe with depth testing, the command &amp;lt;code&amp;gt;wire 1&amp;lt;/code&amp;gt; turns on wireframe without depth testing, and the command &amp;lt;code&amp;gt;wire 0&amp;lt;/code&amp;gt; turns off wireframe. The &amp;lt;code&amp;gt;wire&amp;lt;/code&amp;gt; command by itself still toggles the current wireframe state on or off, and depth testing retains it previous state.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;Lock&amp;lt;/code&amp;gt; class has been added to the system utilities. The class implements a read/write lock that can be simultaneously acquired by multiple threads for shared access to some object or acquired by a single thread for exclusive access to the object.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;Model&amp;lt;/code&amp;gt; class no longer owns the root animator assigned to it. The animator tree must be released by the code belonging to the class that creates it.&lt;br /&gt;
&lt;br /&gt;
* Primitive geometries now triangulate disks with a pattern that is more efficient for rasterization. This change affects the disk, cylinder, cone, truncated cone, dome, path tube, and path revolution primitives.&lt;br /&gt;
&lt;br /&gt;
* Resource names in PAK files are no longer case sensitive.&lt;br /&gt;
&lt;br /&gt;
* PAK files now take precedence in reverse lexicographical order. That is, if the same resource appears in the file &amp;lt;code&amp;gt;Patch1.pak&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Patch2.pak&amp;lt;/code&amp;gt;, then the one in &amp;lt;code&amp;gt;Patch2.pak&amp;lt;/code&amp;gt; is guaranteed to be the one that gets loaded.&lt;br /&gt;
&lt;br /&gt;
* Files that are written by the engine, such as config files, the log, and saved games, are now stored in special directories designated by the operating system as places where these kinds of files should be stored. Under Windows, the config files variables.cfg and input.cfg are stored in the user's roaming application data directory, and the C4Log.html file is stored in the user's non-roaming application data directory. Saved games and screenshots are stored in the user's documents directory. In all cases, the files are stored in a subdirectory having the name of the application. Under Mac OS X, all of these files are stored in the &amp;lt;code&amp;gt;~/Library/Application Support/&amp;amp;lt;application name&amp;amp;gt;/&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
* The engine contains a new mechanism that prevents game and plugin modules built for a different target from being loaded by the engine. For example, if the engine has been built for the Optimized target, it will fail to load any modules built for the Debug target. The operating system's dynamic linker won't be able to find a target-specific symbol, and that will cause it to fail and display an error message. The engine will continue running after such a failure, but the module won't be available.&lt;br /&gt;
&lt;br /&gt;
* A new plugin named Logitech has been added to the engine, and it manages devices made by Logitech that are capable of displaying an image on an LCD screen such as the G15 keyboard.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;natural&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;unsigned_natural&amp;lt;/code&amp;gt; types have been renamed to &amp;lt;code&amp;gt;machine_int&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;unsigned_machine_int&amp;lt;/code&amp;gt; so that it's more clear what their purpose is. This is also more consistent with the naming of the &amp;lt;code&amp;gt;machine_address&amp;lt;/code&amp;gt; type. The shorthand &amp;lt;code&amp;gt;machine&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;unsigned_machine&amp;lt;/code&amp;gt; can also be used in a way analogous to using &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;long int&amp;lt;/code&amp;gt; in C. (A &amp;lt;code&amp;gt;machine_int&amp;lt;/code&amp;gt; is an integer at least 32 bits wide, but is wider as necessary for an arithmetic instruction to be executed without an extra sign extension instruction. Currently a &amp;lt;code&amp;gt;machine_int&amp;lt;/code&amp;gt; is 32 bits wide on x86 processors. On 64-bit PowerPC processors, a &amp;lt;code&amp;gt;machine_int&amp;lt;/code&amp;gt; is 64 bits wide.)&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;engine&amp;lt;/code&amp;gt; macro has been renamed to &amp;lt;code&amp;gt;C4API&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;module_export&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;module_import&amp;lt;/code&amp;gt; macros have been renamed to &amp;lt;code&amp;gt;C4MODULEEXPORT&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;C4MODULEIMPORT&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;extras_api&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;movie_api&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;editor_api&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;texture_api&amp;lt;/code&amp;gt; macros have been renamed to &amp;lt;code&amp;gt;C4EXTRASAPI&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;C4MOVIEAPI&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;C4EDITORAPI&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;C4TEXTUREAPI&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* The underlying code for panel items has been replaced with a new hierarchy of &amp;lt;code&amp;gt;Widget&amp;lt;/code&amp;gt; classes. These will be the same classes that will replace the &amp;lt;code&amp;gt;Element&amp;lt;/code&amp;gt; classes in a future version so that ordinary GUIs and panel effects both use the same unified architecture.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
=== World Editor ===&lt;br /&gt;
&lt;br /&gt;
* A new terrain painting tool has been added that creates holes in the terrain mesh. This is useful for creating entrances to structures embedded in the terrain without having to laboriously dig out large caverns. Holes are indicated by a special material ID, so painting an ordinary material over a hole will restore the terrain surface.&lt;br /&gt;
&lt;br /&gt;
* A new terrain sculpting tool called the &amp;quot;Slope brush&amp;quot; has been added that draws conical shapes whose sides are defined by one of several slope functions. The maximum radius of the terrain brushes has also been increased to allow much larger areas of terrain to be sculpted in a single brush stroke.&lt;br /&gt;
&lt;br /&gt;
* A new command called &amp;quot;Optimize Terrain&amp;quot; has been added to the Geometry menu. This command simplifies the selected terrain meshes, removing the tiny and very thin triangles that are commonly produced by the marching cubes algorithm. Triangle counts tend to decrease by about 25% when applying this optimization.&lt;br /&gt;
&lt;br /&gt;
* A new command called &amp;quot;Generate Ambient Occlusion&amp;quot; has been added to the Geometry menu. This command calculates a static per-vertex alpha value that represents the amount of ambient light that reaches the surface at each vertex. In order to be effective, geometries must be tessellated densely enough so that the sample values are close enough together to look good. Terrain naturally has sufficient vertex density, but ambient occlusion data can be generated for any kind of geometry.&lt;br /&gt;
&lt;br /&gt;
* The per-vertex ambient occlusion is not rendered until the new &amp;quot;Use vertex ambient occlusion&amp;quot; flag is set for the materials used on a geometry having ambient occlusion data. The ambient light values are also available to shaders as the alpha component of the vertex color. The shader system automatically accounts for ambient occlusion, so it is not necessary to explicitly perform the occlusion calculation in a shader.&lt;br /&gt;
&lt;br /&gt;
* The reference marker tool has been moved to its own page called &amp;quot;Worlds&amp;quot;, and a list of referenced worlds has been added. The list shows which worlds are referenced by the current world, and selecting one lets you place a reference marker for that world in the scene with a single click. The generic reference marker tool is used to place references to new worlds that had not previously been referenced in the current world.&lt;br /&gt;
&lt;br /&gt;
* A popup menu with several commands pertaining to reference markers is also available in the Worlds page. The Cleanup command removes worlds that are no longer referenced from the world list. (Upon opening an existing world in this version, the Cleanup command can be used to populate the world list with the worlds that are already referenced.) The Select All command can be used to select all reference markers in the scene that refer to the world currently highlighted in the worlds list. The Select Some command can be used to randomly select a given percentage of those reference markers. Finally, the Replace Selected command changes the selected reference markers so that they refer to the currently highlighted world.&lt;br /&gt;
&lt;br /&gt;
* A new page called &amp;quot;Placement&amp;quot; has been added. This page contains some settings that can be applied when new nodes are placed in a scene through the perspective viewport. If placement modifications are enabled, then the new node can be rotated randomly about the &amp;lt;i&amp;gt;z&amp;lt;/i&amp;gt;-axis, aligned to the tangent plane at the placement point, and/or sunk into uneven ground so that the base of the node is automatically moved below the ground surface. These settings are useful for placing foliage on terrain, and more settings will probably be added in future releases.&lt;br /&gt;
&lt;br /&gt;
* An &amp;quot;Occlusion Space&amp;quot; node has been added to the Spaces page. The occlusion space acts like a box-shaped occlusion portal and blocks all nodes behind its outline on the screen from being rendered. Occlusion spaces should be embedded in large solid objects to help with visibility culling. An occlusion space is disabled whenever the camera enters its box volume.&lt;br /&gt;
&lt;br /&gt;
* Viewport caching has been implemented. This provides much better responsiveness when working with large, complex scenes.&lt;br /&gt;
&lt;br /&gt;
* The Node Info window now remembers which tab was last visited, and it will return to that tab by default the next time the Node Info window is opened (if the tab exists for the selected nodes).&lt;br /&gt;
&lt;br /&gt;
* Right-clicking in the perspective viewport now engages the free camera tool. The contextual menu can still be accessed by holding in Control (Command on the Mac) when right-clicking.&lt;br /&gt;
&lt;br /&gt;
* Holding in the Shift key while using the free camera tool now causes the camera speed to be multiplied by 5.&lt;br /&gt;
&lt;br /&gt;
* It is now possible to click on nodes belonging to external models and referenced worlds, and doing so selects the model node or reference marker node to which the clicked-on node belongs. When a model node or reference marker node is selected, geometries belonging to the model or referenced world are drawn with a gray wireframe as well.&lt;br /&gt;
&lt;br /&gt;
* Node types that have no size associated with them, such as markers, models, skyboxes, and physics joints, can now be placed in a world within the scene graph viewport. When one of the tools used to create these types of node is active, clicking on a node in the scene graph viewport causes a new node of the type represented by the current tool to be created as a subnode of the node that was clicked. The new node's transform is the identity, so its position and orientation coincides with those of its super node.&lt;br /&gt;
&lt;br /&gt;
* A new command called &amp;quot;Edit Script or Panel&amp;quot; has been added to the Node menu. This is a shortcut for going straight to the Script Editor or Panel Editor when a node with a script controller attached to it or a panel effect is selected. These editors are also still accessible from the Controller tab in the Node Info window.&lt;br /&gt;
&lt;br /&gt;
* The Mesh Tools page has been removed, and the Select Surface tool now appears at the top of the editor window.&lt;br /&gt;
&lt;br /&gt;
* Fog can now be disabled for a skybox by checking the &amp;quot;Do not apply fog&amp;quot; box under the Skybox tab in the Node Info window.&lt;br /&gt;
&lt;br /&gt;
* The terrain builder can now import RAW voxel data that has been exported from another application. A RAW file should contain an array of floating-point values stored in little endian byte order, and the size of the array should be equal to the product of the width, height, and depth of the voxel map. To be compatible with some other applications, the ''z'' coordinate varies the fastest, followed by the ''y'' coordinate, and finally the ''x'' coordinate. The importer can treat either +''y'' or +''z'' as the up direction.&lt;br /&gt;
&lt;br /&gt;
=== Texture Tool ===&lt;br /&gt;
&lt;br /&gt;
* The texture importer tool can now remember the settings that were used to import each particular texture map. A new check box called &amp;quot;Remember settings&amp;quot; has been added to the texture import dialog, and it is checked by default. When checked, the settings used to import the texture are written to a CFG file alongside the input TGA file in the Import folder. The next time the texture is imported, the information in this file is used to initialize the settings in the import dialog. The CFG file can also be used as a standalone command line that can be executed using the &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt; console command.&lt;br /&gt;
&lt;br /&gt;
* When a texture currently in use is re-imported, the texture is now automatically reloaded by the engine. This only works properly if the type (2D, Rect, Cube) of the texture stays the same.&lt;br /&gt;
&lt;br /&gt;
* A new check box called &amp;quot;Bleed colors for alpha test&amp;quot; has been added to the texture importer tool. When this box is checked, pixels having an alpha value less than 0.75 (where less than 0.5 fails the alpha test) pick up the color from the nearest pixel that passes the alpha test, up to a maximum of 16 pixels away. This process helps remove borders that can appear when alpha-tested textures are rendered. The command-line option for this setting is &amp;lt;code&amp;gt;-bleed&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;texpal&amp;lt;/code&amp;gt; command has been added for creating reference-based terrain palettes. See [[Creating a Terrain Palette]]. &lt;br /&gt;
&lt;br /&gt;
=== Collada Importer ===&lt;br /&gt;
&lt;br /&gt;
* There are two new options exposed by the Collada Importer plugin. First, imported materials can be merged with materials already existing in the scene if they are identical. Second, an existing material in the scene can be used instead of an imported material if the names match.&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Release_Notes_for_Version_6.9&amp;diff=677</id>
		<title>Release Notes for Version 6.9</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Release_Notes_for_Version_6.9&amp;diff=677"/>
		<updated>2025-07-25T05:03:44Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
'''Release date:''' November 2, 2018&lt;br /&gt;
&lt;br /&gt;
(C4 version 6.9 corresponds to Tombstone version 2.9.)&lt;br /&gt;
&lt;br /&gt;
* The file formats have been updated a little bit in this version. While it's not a requirement, you ''may'' upgrade your resources to the newer formats by typing &amp;lt;code&amp;gt;updateworlds&amp;lt;/code&amp;gt; in the [[Command Console]]. '''Always backup your entire Data folder before doing this just in case something goes wrong.'''&lt;br /&gt;
&lt;br /&gt;
== Core Engine ==&lt;br /&gt;
&lt;br /&gt;
* All of the unsigned integer types that previously began with &amp;lt;code&amp;gt;unsigned_&amp;lt;/code&amp;gt; have been changed to begin simply with &amp;lt;code&amp;gt;u&amp;lt;/code&amp;gt;. For example, &amp;lt;code&amp;gt;unsigned_int32&amp;lt;/code&amp;gt; is now just &amp;lt;code&amp;gt;uint32&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;Array::FindArrayElement()&amp;lt;/code&amp;gt; function has been renamed to &amp;lt;code&amp;gt;Array::FindArrayElementIndex()&amp;lt;/code&amp;gt; to make it clear what kind of information is returned.&lt;br /&gt;
&lt;br /&gt;
=== Graphics Manager ===&lt;br /&gt;
&lt;br /&gt;
* The Graphics Manager on Windows and Linux now require OpenGL 3.3 plus the &amp;lt;code&amp;gt;GL_ARB_clip_control&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;GL_ARB_direct_state_access&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;GL_ARB_multi_bind&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;GL_ARB_texture_storage&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;GL_ARB_texture_storage_multisample&amp;lt;/code&amp;gt; extensions. Since Apple does not support some of these extensions (and never will), this means that C4 6.9 does not run on the Mac.&lt;br /&gt;
&lt;br /&gt;
* The projection matrices used by the engine have been modified to produce device-space ''z'' coordinates in the range [0,1] with reversed depth. This greatly increases depth buffer precision and eliminates Z fighting artifacts when parallel surfaces near each other are viewed from far away.&lt;br /&gt;
&lt;br /&gt;
* Generalized depth offset modifications and depth bounds test optimizations have been implemented to handle oblique near plane projections. This can improve the appearance of decals in reflection or refraction images, and it can improve performance of point/cube/spot light sources in reflection or refraction images.&lt;br /&gt;
&lt;br /&gt;
* The motion blur algorithm has been improved and now generates better results. The velocity buffer has been changed to a two-channel format using 8 bits per channel, using half the space it previously used.&lt;br /&gt;
&lt;br /&gt;
* The method used to split linear 32-bit depths into two 16-bit depths for the floating-point structure buffer has been improved. This gives better precision farther from the camera position.&lt;br /&gt;
&lt;br /&gt;
=== Interface Manager ===&lt;br /&gt;
&lt;br /&gt;
* The font format has changed in this version. Any custom fonts that were previously imported must be imported again before they can be used.&lt;br /&gt;
&lt;br /&gt;
* There are many new text rendering capabilities, including underline, strikethrough, horizontal stretch, transform-based subscript/superscripts, right-to-left writing directions, bidirectional layout, adaptive supersampling, rectangle primitives, fraction formatting, and hyphen-minus substitution. Settings have been added to the [[Text Widget]] that can be used to enable these in the [[Panel Editor]], and new [[Text Formatting | embedded format directives]] have been added to control them within a block of text. See the [http://sluglibrary.com/SlugManual.pdf Slug User Manual] for details about all of the text rendering features.&lt;br /&gt;
&lt;br /&gt;
=== Effect Manager ===&lt;br /&gt;
&lt;br /&gt;
* A new [[Text Effect]] node has been added to the engine. This is used to place text on surfaces within a game world and apply materials to the glyphs so they appear to be painted on the surfaces. (This is completely different from using text in a panel effect.)&lt;br /&gt;
&lt;br /&gt;
=== Terrain ===&lt;br /&gt;
&lt;br /&gt;
* The functions that build terrain geometry have been improved so that vertex sharing occurs as often as possible. Rebuilding terrain geometries can reduce the data size by roughly 5&amp;amp;ndash;10%.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
=== Font Importer ===&lt;br /&gt;
&lt;br /&gt;
* The [[Font Importer]] contains new settings for the size and position of underline and strikethrough decorations and the transforms for subscripts and superscripts. These are initialized to the values specified in the input TrueType font file.&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* Two basic game projects called SimpleBall and SimpleChar are now included with the engine. See [[Simple Games]].&lt;br /&gt;
&lt;br /&gt;
* Several new tutorial worlds are included in the &amp;lt;code&amp;gt;Data/Tutorial&amp;lt;/code&amp;gt; folder. Some of them are starting points for [[:Category:Tutorials | tutorial articles]] on the wiki.&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Release_Notes_for_Version_6.0&amp;diff=676</id>
		<title>Release Notes for Version 6.0</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Release_Notes_for_Version_6.0&amp;diff=676"/>
		<updated>2025-07-25T05:01:11Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
'''Release date:''' January 27, 2017&lt;br /&gt;
&lt;br /&gt;
(C4 version 6.0 corresponds to Tombstone version 2.0.)&lt;br /&gt;
&lt;br /&gt;
== Core Engine ==&lt;br /&gt;
&lt;br /&gt;
* Support for the Open Data Description Language has been updated to version 2.0.&lt;br /&gt;
&lt;br /&gt;
=== Graphics Manager ===&lt;br /&gt;
&lt;br /&gt;
* A few new workarounds have been implemented to deal with subtle bugs in the AMD graphics driver.&lt;br /&gt;
&lt;br /&gt;
=== Interface Manager ===&lt;br /&gt;
&lt;br /&gt;
* All text drawing, both in the user interface and in panel effects, now uses our new technology to render glyphs on the GPU directly from font outline data. A shader reads the quadratic B&amp;amp;eacute;zier curves from a special texture map for each glyph and calculates nicely antialiased edges at any resolution. The engine no longer uses texture maps to store pre-rendered bitmap versions of each glyph at one specific font size. Text is sharply rendered no matter how large it is scaled or how it is rotated. This technology anticipates the increasing ubiquity of higher DPI displays where glyphs are rendered at a higher resolution over the same physical area to achieve greater quality.&lt;br /&gt;
&lt;br /&gt;
* Every type of widget that draws text now has a font size setting. The font size corresponds to the height of the em square for the font. (The height of capital letters is usually around 70% of the em square height, but there is no strict rule about this.) Text widgets also have an independent scale factor, and the font size is multiplied by this scale factor to determine the final size of the glyphs that are rendered.&lt;br /&gt;
&lt;br /&gt;
* The text layout code in the engine now uses exact glyph advance widths to position characters, which results in fractional positioning that is correct at all font sizes. This has a much nicer appearance compared to the integral widths used by the texture-based glyphs in earlier versions of the engine.&lt;br /&gt;
&lt;br /&gt;
* The text layout code now also supports kerning. Using the tables contained in the original font, some pairs of glyphs are moved closer together, or sometimes further apart, to improve appearance. Kerning is enabled by default, but text widgets have a setting to disable it if desired.&lt;br /&gt;
&lt;br /&gt;
* Text can now have special effects applied, and they can be dynamically changed at run-time. Two effects are currently available, a shadow effect and a glow effect.&lt;br /&gt;
&lt;br /&gt;
* The color picker dialog now contains copy and paste buttons that operate on the current color.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
=== Font Importer ===&lt;br /&gt;
&lt;br /&gt;
* The Font Importer now reads TrueType Font (&amp;lt;code&amp;gt;.ttf&amp;lt;/code&amp;gt;) files directly instead of relying on the operating system to rasterize glyphs. This means that fonts can be imported on all platforms, and the results are identical on all platforms.&lt;br /&gt;
&lt;br /&gt;
* All Unicode values up to U+2FFFF are now support by the Font Importer, which is everything belonging to the Basic Multilingual Plane (BMP), as before, plus the Supplementary Multilingual Plane (SMP) and the Supplementary Ideographic Plane (SIP). This covers all renderable glyphs currently defined by Unicode.&lt;br /&gt;
&lt;br /&gt;
* When a font is imported, the settings in the Font Importer are saved to a config file so they can be restored if the font is ever imported again. This includes which ranges of glyphs are selected to be imported.&lt;br /&gt;
&lt;br /&gt;
=== OpenGEX Importer ===&lt;br /&gt;
&lt;br /&gt;
* Support for the OpenGEX format has been updated to version 2.0.&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Mathematical_Shader_Processes&amp;diff=675</id>
		<title>Mathematical Shader Processes</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Mathematical_Shader_Processes&amp;diff=675"/>
		<updated>2025-01-06T06:21:59Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a list of the mathematical shader processes that are available in the [[Shader Editor]] under the Math tab.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Absolute Value|Shader_abs.png|Value '''A'''|Value of size matching '''A'''|Calculates the absolute value of each component of the input '''A'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Add|Shader_add.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise sum of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Average|Shader_avg.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise average of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Cosine|Shader_cos.png|Scalar '''A'''|Scalar|Calculates the cosine of the input '''A''', where the input is measured in radians.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Cross Product|Shader_xpd.png|3D vectors '''A''' and '''B'''|3D vector|Calculates the cross product of the inputs '''A''' and '''B'''.&lt;br /&gt;
&lt;br /&gt;
If one of the input vectors is in tangent space and the other is in world space, then additional shader code is generated to transform the tangent-space vector into world space before the cross product is evaluated.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Divide|Shader_div.png|Value '''A''', Scalar '''B'''|Value of size matching '''A'''|Calculates the quotient of each component of the input '''A''' and the scalar input '''B'''.&lt;br /&gt;
&lt;br /&gt;
''Tip:'' If you're dividing by a constant value, then it would be more efficient to multiply by the reciprocal of the constant. For example, you should multiply by 0.5 instead of dividing by 2.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Dot Product 3D|Shader_dp3.png|3D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''.&lt;br /&gt;
&lt;br /&gt;
If one of the input vectors is in tangent space and the other is in world space, then additional shader code is generated to transform the tangent-space vector into world space before the dot product is evaluated.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Dot Product 4D|Shader_dp4.png|4D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Exp Base 2|Shader_ex2.png|Scalar '''A'''|Scalar|Calculates 2 raised to the power given by the input '''A'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Expand|Shader_expand.png|Value '''A'''|Value of size matching '''A'''|Multiplies each component of the input '''A''' by 2.0 and then subtracts 1.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Floor|Shader_flr.png|Value '''A'''|Value of size matching '''A'''|Calculates the floor of each component of the input '''A'''. To calculate a ceiling, negate the input and output of the Floor process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Fraction|Shader_frc.png|Value '''A'''|Value of size matching '''A'''|Calculates the fraction of each component of the input '''A'''. The fraction of a number is the difference between that number and its floor.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Invert|Shader_invert.png|Value '''A'''|Value of size matching '''A'''|Subtracts each component of the input '''A''' from 1.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Linear Interpolate|Shader_lrp.png|Values '''A''', '''B''', and '''t'''|Value of size matching largest of '''A''', '''B''', and '''t'''|Calculates the linear interpolation between the components of '''A''' and '''B''' using the components of the input '''t''' as the interpolation parameter.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Log Base 2|Shader_lg2.png|Scalar '''A'''|Scalar|Calculates the logarithm base 2 of the input '''A'''. If the input is not positive, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Magnitude 3D|Shader_magnitude3d.png|3D vector '''A'''|Scalar|Calculates the magnitude of the input '''A'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Maximum|Shader_max.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise maximum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the maximum of only '''A''' and '''B''' is calculated.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Minimum|Shader_min.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise minimum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the minimum of only '''A''' and '''B''' is calculated.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Multiply|Shader_mul.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise product of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Multiply Add|Shader_mad.png|Values '''A''', '''B''', and '''C'''|Value of size matching largest of '''A''', '''B''', and '''C'''|Calculates the componentwise product of the inputs '''A''' and '''B''' and then adds the components of the input '''C'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Normalize 3D|Shader_normalize3d.png|3D vector '''A'''|3D vector|Normalizes the input '''A'''. If the input is the zero vector, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Power|Shader_pow.png|Scalars '''A''' and '''B'''|Scalar|Calculates the input '''A''' raised to the power of the input '''B'''. If the input '''A''' is negative, then the result is undefined. If the input '''A''' is zero and the input '''B''' is not positive, then the result is undefined.&lt;br /&gt;
&lt;br /&gt;
''Tip:'' If you're just squaring a value, then it would be more efficient to multiply the value by itself. That is, you should calculate '''A'''&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;'''A''' using the '''Multiply''' process instead of raising '''A''' to the power of 2.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reciprocal|Shader_rcp.png|Scalar '''A'''|Scalar|Calculates the reciprocal of the input '''A'''. If the input is zero, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reciprocal Square Root|Shader_rsq.png|Scalar '''A'''|Scalar|Calculates the reciprocal square root of the input '''A'''. If the input is not positive, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Round|Shader_round.png|Value '''A'''|Value of size matching '''A'''|Rounds each component of the input '''A''' to the nearest integer.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Saturate|Shader_sat.png|Value '''A'''|Value of size matching '''A'''|Clamps each component of the input '''A''' to the range [0,1].}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Equal|Shader_seq.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Greater Equal|Shader_sge.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Greater Than|Shader_sgt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Less Equal|Shader_sle.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set of Less Than|Shader_slt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Not Equal|Shader_sne.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is not equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Sine|Shader_sin.png|Scalar '''A'''|Scalar|Calculates the sine of the input '''A''', where the input is measured in radians.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Square Root|Shader_sqrt.png|Scalar '''A'''|Scalar|Calculates the square root of the input '''A'''. If the input is negative, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Subtract|Shader_sub.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise difference of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Sum of Products|Shader_sumproducts.png|Values '''A''', '''B''', '''C''', and '''D'''|Value of size matching largest of '''A''', '''B''', '''C''', and '''D'''|Calculates the componentwise products of the inputs '''A''' and '''B''' and the componentwise products of the inputs '''C''' and '''D''' and then calculates the componentwise sum of the results.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Shader Editor]]&lt;br /&gt;
* [[Basic Shader Processes]]&lt;br /&gt;
* [[Complex Shader Processes]]&lt;br /&gt;
* [[Interpolant Shader Processes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Shader_Editor&amp;diff=674</id>
		<title>Shader Editor</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Shader_Editor&amp;diff=674"/>
		<updated>2025-01-06T04:31:16Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to create a limitless variety of materials within the context of a graphical interface.&lt;br /&gt;
&lt;br /&gt;
== Opening the Shader Editor ==&lt;br /&gt;
&lt;br /&gt;
The image to below shows the Shader Editor. The Shader Editor is opened from inside the [[Material Editor]] by choosing '''Edit Shader''' from the '''Material''' menu. If the selected material already had conventional attributes assigned to it through the settings in the Material Editor, then the Shader Editor will initially show a translation of those attributes into the shader graph. If the selected material was empty (because no settings had been specified for it yet), then the Shader Editor will initially show default graph with a minimal number of nodes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Shadereditor.png]]&lt;br /&gt;
&lt;br /&gt;
== Shader Graphs ==&lt;br /&gt;
&lt;br /&gt;
A shader is represented in the Shader Editor by what is known as a ''data flow graph''. The nodes in this graph are called ''processes'', and the edges in this graph are called ''routes''. A shader is a special type of graph called a ''directed acyclic graph'', or ''DAG'', meaning that data flows in a specific direction from one process to another and there are no loops.&lt;br /&gt;
&lt;br /&gt;
Each box in the shader graph represents a single process. A process can be a simple mathematical operation, a constant input value such as a color, an interpolated value such as the direction to the light source, or a more complex operation defined by the engine such as a parallax offset calculation.&lt;br /&gt;
&lt;br /&gt;
A route is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of data from one process to another. Routes begin at one process and end at a ''port'' belonging to another process. Every process has between zero and four ports, and each can be occupied by only one incoming route at a time. Ports with a plain background are required, and ports with a striped background are optional. All required ports must have an incoming route attached to them in order for the shader to be valid.&lt;br /&gt;
&lt;br /&gt;
== Editing a Shader ==&lt;br /&gt;
&lt;br /&gt;
The tabbed lists on the left side of the Shader Editor show the processes that are available for use in a shader. They are divided into four categories that are described in more detail below: Basic, Math, Complex, and Interpolants. A new process is added to a shader by selecting it in the list and then clicking in the viewport. The editor won't let you place two processes on top of each other, and the cursor will change to indicate where it's possible to place a new process.&lt;br /&gt;
&lt;br /&gt;
Routes are added to a shader by clicking inside the circle on the right side of a process and dragging into a port belonging to another process. This causes a new route to be created beginning at the process you clicked on and ending at the input port to which you dragged. If a port is already occupied by another route, then the existing route is deleted and replaced with the new route that you are creating. You cannot connect a route from one process to a port belonging to any other process preceding that process in the graph because it would create a cycle.&lt;br /&gt;
&lt;br /&gt;
The physical position of a process in the viewport is irrelevant. The data flow structure of a shader is determined entirely by the route connections. Processes may be placed in any convenient location. &lt;br /&gt;
&lt;br /&gt;
== Processes ==&lt;br /&gt;
&lt;br /&gt;
A process takes between zero and four inputs and produces at most a single output. The output may be sent to any number of input ports for other processes.&lt;br /&gt;
&lt;br /&gt;
For many types of processes, the process box shown in the Shader Editor displays additional information. For example, the Texture Map process shows a small image of the texture map, and the Constant Vector process shows the four constant values that it outputs. Most mathematical operations display a mathematical expression showing exactly how their input values are used to calculate an output value.&lt;br /&gt;
&lt;br /&gt;
Double-clicking on a process, or selecting a process and typing Ctrl-I, opens the Process Info window for that process. In the Process Info window, every process has a comment field that let's you specify some text that is displayed at the bottom of the process box in the Shader Editor. Some processes also have extra settings that appear in the Process Info window.&lt;br /&gt;
&lt;br /&gt;
Each type of process available for use in a shader is described individually on the following pages (corresponding to the groups displayed in the Shader Editor):&lt;br /&gt;
&lt;br /&gt;
* [[Basic Shader Processes | List of basic processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Mathematical Shader Processes | List of mathematical processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Complex Shader Processes | List of complex processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Interpolant Shader Processes | List of interpolant processes]]&lt;br /&gt;
&lt;br /&gt;
== Routes ==&lt;br /&gt;
&lt;br /&gt;
The routes in a shader graph carry data from one process to another. Each route can carry between one and four floating-point values&amp;amp;mdash;the actual number is determined by the output size of the route's start process.&lt;br /&gt;
&lt;br /&gt;
A swizzle and negation may be applied to a route. These can be set by double-clicking on a route or by selecting a route and typing Ctrl-I. By default, the swizzle for a route is &amp;lt;code&amp;gt;xyzw&amp;lt;/code&amp;gt;, meaning that there is no change to the order of the components. If any other swizzle is specified, or the values are negated, then that information is displayed in a small box at the center of the path representing the route. The swizzle may be specified using any letters from the sets &amp;lt;code&amp;gt;xyzw&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;rgba&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;stpq&amp;lt;/code&amp;gt;. Specifying only a single letter is shorthand for the same letter repeated four times. For example, the swizzle &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; is equivalent to the swizzle &amp;lt;code&amp;gt;zzzz&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If a route carries fewer than four components, then each component specified in its swizzle is clamped to the last available component. For example, if a route carries only three components, then any &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; in the swizzle ultimately interpreted as the third component of the data carried by the route. The swizzle &amp;lt;code&amp;gt;wxyz&amp;lt;/code&amp;gt; would really mean &amp;lt;code&amp;gt;zxyz&amp;lt;/code&amp;gt;. This is particularly important in the case that two routes of different sizes are used as inputs to a binary operation. The operation is performed using the number of components for larger of the two routes, so the missing components of the smaller route are taken from the components specified by the clamped swizzle.&lt;br /&gt;
&lt;br /&gt;
== Shader Editor Tools ==&lt;br /&gt;
&lt;br /&gt;
There are four tool buttons in the upper-left corner of the Shader Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.)&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead3|Icon|Shortcut|Function}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move'''. Selects a process or route in a shader. Clicking outside of a process and dragging will create a box that selects all of the processes inside it. Clicking inside a process and dragging moves all of the currently selected processes. (When processes are moved, they are automatically prevented from moving on top of other processes.)}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the shader viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Changes the scale of the shader viewport. Using the mouse wheel with any other tool also zooms.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_section.png]]||'''Draw Section'''. Draws a rectangular box with a title bar behind all processes in the graph. This can be used to visually organize groups of processes in a shader.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Output Processes ==&lt;br /&gt;
&lt;br /&gt;
Each shader graph contains a set of ''output processes'' that represent the final values produced by the shader. These are colored green in the shader editor, they cannot be deleted, and they can have no output routes. The only output process that has a required input port is the '''Ambient Reflection Output''' process. All other output processes have only optional input ports and are ignored if they are not used.&lt;br /&gt;
&lt;br /&gt;
The individual output processes are described in the following table.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Ambient&amp;amp;nbsp;Reflection&amp;amp;nbsp;Output|Shader_ambientoutput.png|RGB color '''RGB''' (required), World-space or tangent-space normal '''N''' (optional)|None|This is the primary output process for the ambient shader. The color sent to this output process is combined with the ambient lighting environment to produce the final ambient light reflection for a material.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Light&amp;amp;nbsp;Reflection&amp;amp;nbsp;Output|Shader_lightingoutput.png|RGB color '''RGB''' (optional), Impostor depth '''Z''' (optional)|None|This is the primary output process for the light shader. The color sent to this output process is combined with the color from a light source to produce the final light reflection for a material.&lt;br /&gt;
&lt;br /&gt;
In an impostor shader, the alpha channel of the output of the Impostor Normal process should be sent to the '''Z''' input port to provide the impostor depth.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Alpha&amp;amp;nbsp;Output|Shader_alphaoutput.png|Scalar '''A''' (optional)|None|If a material is transparent, then the alpha value sent to this output process controls the transparency. This is currently useful only for objects rendered in the effect pass. If the Glow Output process is used, then the Alpha Output process is ignored.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Alpha&amp;amp;nbsp;Test&amp;amp;nbsp;Output|Shader_alphatestoutput.png|Scalar '''A''' (optional)|None|If a material uses the alpha test, then the value sent to this output process is the value that is tested. The material must have the alpha test flag set in the Material Manager for this output process to be used.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Emission&amp;amp;nbsp;Output|Shader_emissionoutput.png|RGB color '''RGB''' (optional)|None|The color sent to this output process is added to the final ambient color as an emission term.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Glow&amp;amp;nbsp;Output|Shader_glowoutput.png|Scalar '''A''' (optional)|None|If a material uses emission glow, then the value sent to this output process determines the glow intensity. The material must have the emission glow flag set in the Material Manager for this output process to be used. If the alpha test flag is set, then the Glow Output process is ignored.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Bloom&amp;amp;nbsp;Output|Shader_bloomoutput.png|Scalar '''A''' (optional)|None|If a material uses specular bloom, then the value sent to this output process determines the bloom intensity. The material must have the specular bloom flag set in the Material Manager for this output process to be used.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reflection&amp;amp;nbsp;Buffer&amp;amp;nbsp;Output|Shader_reflectionoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the reflection buffer is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the reflection. Normal incidence reflectivity and bump offset scale can be configured in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Refraction&amp;amp;nbsp;Buffer&amp;amp;nbsp;Output|Shader_refractionoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the refraction buffer is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the refraction. The bump offset scale can be configured in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Environment&amp;amp;nbsp;Output|Shader_environmentoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional), scalar '''BIAS''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain&amp;amp;nbsp;Environment&amp;amp;nbsp;Output|Shader_terrainenvironmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. Terrain normal vectors may be sent to the '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;, and '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; input ports in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Material Editor]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shadereditor.png&amp;diff=673</id>
		<title>File:Shadereditor.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shadereditor.png&amp;diff=673"/>
		<updated>2025-01-06T04:28:13Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shadereditor.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Shader_Editor&amp;diff=672</id>
		<title>Shader Editor</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Shader_Editor&amp;diff=672"/>
		<updated>2025-01-06T04:18:12Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: /* Output Processes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to create a limitless variety of materials within the context of a graphical interface.&lt;br /&gt;
&lt;br /&gt;
== Opening the Shader Editor ==&lt;br /&gt;
&lt;br /&gt;
[[File:Shadereditor.png|right|frame|'''Figure 1.''' The Shader Editor window.]] The image to the right shows the Shader Editor. The Shader Editor is opened from inside the [[Material Editor]] by choosing '''Edit Shader''' from the '''Material''' menu. If the selected material already had conventional attributes assigned to it through the settings in the Material Editor, then the Shader Editor will initially show a translation of those attributes into the shader graph. If the selected material was empty (because no settings had been specified for it yet), then the Shader Editor will initially show default graph with a minimal number of nodes.&lt;br /&gt;
&lt;br /&gt;
== Shader Graphs ==&lt;br /&gt;
&lt;br /&gt;
A shader is represented in the Shader Editor by what is known as a ''data flow graph''. The nodes in this graph are called ''processes'', and the edges in this graph are called ''routes''. A shader is a special type of graph called a ''directed acyclic graph'', or ''DAG'', meaning that data flows in a specific direction from one process to another and there are no loops.&lt;br /&gt;
&lt;br /&gt;
Each box in the shader graph represents a single process. A process can be a simple mathematical operation, a constant input value such as a color, an interpolated value such as the direction to the light source, or a more complex operation defined by the engine such as a parallax offset calculation.&lt;br /&gt;
&lt;br /&gt;
A route is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of data from one process to another. Routes begin at one process and end at a ''port'' belonging to another process. Every process has between zero and four ports, and each can be occupied by only one incoming route at a time. Ports with a plain background are required, and ports with a striped background are optional. All required ports must have an incoming route attached to them in order for the shader to be valid.&lt;br /&gt;
&lt;br /&gt;
== Editing a Shader ==&lt;br /&gt;
&lt;br /&gt;
The tabbed lists on the left side of the Shader Editor show the processes that are available for use in a shader. They are divided into four categories that are described in more detail below: Basic, Math, Complex, and Interpolants. A new process is added to a shader by selecting it in the list and then clicking in the viewport. The editor won't let you place two processes on top of each other, and the cursor will change to indicate where it's possible to place a new process.&lt;br /&gt;
&lt;br /&gt;
Routes are added to a shader by clicking inside the circle on the right side of a process and dragging into a port belonging to another process. This causes a new route to be created beginning at the process you clicked on and ending at the input port to which you dragged. If a port is already occupied by another route, then the existing route is deleted and replaced with the new route that you are creating. You cannot connect a route from one process to a port belonging to any other process preceding that process in the graph because it would create a cycle.&lt;br /&gt;
&lt;br /&gt;
The physical position of a process in the viewport is irrelevant. The data flow structure of a shader is determined entirely by the route connections. Processes may be placed in any convenient location. &lt;br /&gt;
&lt;br /&gt;
== Processes ==&lt;br /&gt;
&lt;br /&gt;
A process takes between zero and four inputs and produces at most a single output. The output may be sent to any number of input ports for other processes.&lt;br /&gt;
&lt;br /&gt;
For many types of processes, the process box shown in the Shader Editor displays additional information. For example, the Texture Map process shows a small image of the texture map, and the Constant Vector process shows the four constant values that it outputs. Most mathematical operations display a mathematical expression showing exactly how their input values are used to calculate an output value.&lt;br /&gt;
&lt;br /&gt;
Double-clicking on a process, or selecting a process and typing Ctrl-I, opens the Process Info window for that process. In the Process Info window, every process has a comment field that let's you specify some text that is displayed at the bottom of the process box in the Shader Editor. Some processes also have extra settings that appear in the Process Info window.&lt;br /&gt;
&lt;br /&gt;
Each type of process available for use in a shader is described individually on the following pages (corresponding to the groups displayed in the Shader Editor):&lt;br /&gt;
&lt;br /&gt;
* [[Basic Shader Processes | List of basic processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Mathematical Shader Processes | List of mathematical processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Complex Shader Processes | List of complex processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Interpolant Shader Processes | List of interpolant processes]]&lt;br /&gt;
&lt;br /&gt;
== Routes ==&lt;br /&gt;
&lt;br /&gt;
The routes in a shader graph carry data from one process to another. Each route can carry between one and four floating-point values&amp;amp;mdash;the actual number is determined by the output size of the route's start process.&lt;br /&gt;
&lt;br /&gt;
A swizzle and negation may be applied to a route. These can be set by double-clicking on a route or by selecting a route and typing Ctrl-I. By default, the swizzle for a route is &amp;lt;code&amp;gt;xyzw&amp;lt;/code&amp;gt;, meaning that there is no change to the order of the components. If any other swizzle is specified, or the values are negated, then that information is displayed in a small box at the center of the path representing the route. The swizzle may be specified using any letters from the sets &amp;lt;code&amp;gt;xyzw&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;rgba&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;stpq&amp;lt;/code&amp;gt;. Specifying only a single letter is shorthand for the same letter repeated four times. For example, the swizzle &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; is equivalent to the swizzle &amp;lt;code&amp;gt;zzzz&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If a route carries fewer than four components, then each component specified in its swizzle is clamped to the last available component. For example, if a route carries only three components, then any &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; in the swizzle ultimately interpreted as the third component of the data carried by the route. The swizzle &amp;lt;code&amp;gt;wxyz&amp;lt;/code&amp;gt; would really mean &amp;lt;code&amp;gt;zxyz&amp;lt;/code&amp;gt;. This is particularly important in the case that two routes of different sizes are used as inputs to a binary operation. The operation is performed using the number of components for larger of the two routes, so the missing components of the smaller route are taken from the components specified by the clamped swizzle.&lt;br /&gt;
&lt;br /&gt;
== Shader Editor Tools ==&lt;br /&gt;
&lt;br /&gt;
There are four tool buttons in the upper-left corner of the Shader Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.)&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead3|Icon|Shortcut|Function}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move'''. Selects a process or route in a shader. Clicking outside of a process and dragging will create a box that selects all of the processes inside it. Clicking inside a process and dragging moves all of the currently selected processes. (When processes are moved, they are automatically prevented from moving on top of other processes.)}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the shader viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Changes the scale of the shader viewport. Using the mouse wheel with any other tool also zooms.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_section.png]]||'''Draw Section'''. Draws a rectangular box with a title bar behind all processes in the graph. This can be used to visually organize groups of processes in a shader.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Output Processes ==&lt;br /&gt;
&lt;br /&gt;
Each shader graph contains a set of ''output processes'' that represent the final values produced by the shader. These are colored green in the shader editor, they cannot be deleted, and they can have no output routes. The only output process that has a required input port is the '''Ambient Reflection Output''' process. All other output processes have only optional input ports and are ignored if they are not used.&lt;br /&gt;
&lt;br /&gt;
The individual output processes are described in the following table.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Ambient&amp;amp;nbsp;Reflection&amp;amp;nbsp;Output|Shader_ambientoutput.png|RGB color '''RGB''' (required), World-space or tangent-space normal '''N''' (optional)|None|This is the primary output process for the ambient shader. The color sent to this output process is combined with the ambient lighting environment to produce the final ambient light reflection for a material.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Light&amp;amp;nbsp;Reflection&amp;amp;nbsp;Output|Shader_lightingoutput.png|RGB color '''RGB''' (optional), Impostor depth '''Z''' (optional)|None|This is the primary output process for the light shader. The color sent to this output process is combined with the color from a light source to produce the final light reflection for a material.&lt;br /&gt;
&lt;br /&gt;
In an impostor shader, the alpha channel of the output of the Impostor Normal process should be sent to the '''Z''' input port to provide the impostor depth.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Alpha&amp;amp;nbsp;Output|Shader_alphaoutput.png|Scalar '''A''' (optional)|None|If a material is transparent, then the alpha value sent to this output process controls the transparency. This is currently useful only for objects rendered in the effect pass. If the Glow Output process is used, then the Alpha Output process is ignored.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Alpha&amp;amp;nbsp;Test&amp;amp;nbsp;Output|Shader_alphatestoutput.png|Scalar '''A''' (optional)|None|If a material uses the alpha test, then the value sent to this output process is the value that is tested. The material must have the alpha test flag set in the Material Manager for this output process to be used.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Emission&amp;amp;nbsp;Output|Shader_emissionoutput.png|RGB color '''RGB''' (optional)|None|The color sent to this output process is added to the final ambient color as an emission term.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Glow&amp;amp;nbsp;Output|Shader_glowoutput.png|Scalar '''A''' (optional)|None|If a material uses emission glow, then the value sent to this output process determines the glow intensity. The material must have the emission glow flag set in the Material Manager for this output process to be used. If the alpha test flag is set, then the Glow Output process is ignored.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Bloom&amp;amp;nbsp;Output|Shader_bloomoutput.png|Scalar '''A''' (optional)|None|If a material uses specular bloom, then the value sent to this output process determines the bloom intensity. The material must have the specular bloom flag set in the Material Manager for this output process to be used.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reflection&amp;amp;nbsp;Buffer&amp;amp;nbsp;Output|Shader_reflectionoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the reflection buffer is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the reflection. Normal incidence reflectivity and bump offset scale can be configured in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Refraction&amp;amp;nbsp;Buffer&amp;amp;nbsp;Output|Shader_refractionoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the refraction buffer is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the refraction. The bump offset scale can be configured in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Environment&amp;amp;nbsp;Output|Shader_environmentoutput.png|RGB color '''RGB''' (optional), World-space or tangent-space normal vector '''N''' (optional), scalar '''BIAS''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. A normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain&amp;amp;nbsp;Environment&amp;amp;nbsp;Output|Shader_terrainenvironmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. Terrain normal vectors may be sent to the '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;, and '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; input ports in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Material Editor]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Complex_Shader_Processes&amp;diff=671</id>
		<title>Complex Shader Processes</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Complex_Shader_Processes&amp;diff=671"/>
		<updated>2025-01-06T04:14:51Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Diffuse Reflection|Shader_diffuse.png|World-space or tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''L''', where '''L''' is the direction to light. The result is saturated to the range [0,1] and divided by pi. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the world light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Specular Reflection|Shader_specular.png|World-space or tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor sat('''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''H''')&amp;lt;sup&amp;gt;''p''&amp;lt;/sup&amp;gt;, where '''H''' is the direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1) in tangent space. The specular power ''p'' controls the sharpness of the specularity.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the world halfway direction interpolant, which in turn uses the world light direction and world view direction interpolants.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Diffuse Transflection|Shader_transflection.png|World-space or tangent-space normal '''N''' (optional)|Scalar|Calculates the diffuse transflection factor '''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''L''', where '''L''' is the direction to light. The result is multiplied by the front-facing factor ''f'' and divided by pi, and it is ''not'' saturated. If '''N''' is omitted, then it's as if '''N''' is (0,0,1) in tangent space.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the world light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Specular Transmission|Shader_transmission.png|Specular power ''p'' (required)|Scalar|Calculates the specular transmission factor sat(&amp;amp;minus;'''L'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''V''')&amp;lt;sup&amp;gt;''p''&amp;lt;/sup&amp;gt;, where '''L''' and '''V''' are the direction to light and direction to viewer. The specular power ''p'' controls the sharpness of the specularity. This produces a transmission strength when a material is viewed from the back side with respect to the incoming light.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the world light direction and view direction interpolants.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (required), Normal vector '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together.&lt;br /&gt;
&lt;br /&gt;
If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; being weighted most when ''t'' is zero and the height corresponding to '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;2''t''&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;''t''&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;&amp;amp;frac12;''w'',&amp;amp;nbsp;''c''&amp;amp;nbsp;+&amp;amp;nbsp;&amp;amp;frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If rendering to the structure buffer is disabled, then the output value is always 1.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent view direction interpolant.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &amp;amp;lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &amp;amp;lt; 0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Render Glyph|Shader_glyph.png|2D vector '''TEXC''' (required), RGBA color '''RGBA''' (required)|RGBA color|Renders glyph or vector graphics with Slug. The '''TEXC''' input should use the Texcoord 2 interpolant, and the '''RGBA''' input would normally use the Vertex Color interpolant.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Composite Buffer|Shader_composite.png|None|RGBA color|Samples from the composite buffer at the current fragment coordinates.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Generate Impostor Normal / Depth|Shader_genimpostor.png|3D vector '''N''' (optional)|RGBA color|When impostor textures are being generated, this process outputs the impostor normal in the RGB channels, and it outputs the impostor depth in the alpha channel.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Shader Editor]]&lt;br /&gt;
* [[Basic Shader Processes]]&lt;br /&gt;
* [[Mathematical Shader Processes]]&lt;br /&gt;
* [[Interpolant Shader Processes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Complex_Shader_Processes&amp;diff=670</id>
		<title>Complex Shader Processes</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Complex_Shader_Processes&amp;diff=670"/>
		<updated>2025-01-06T04:03:40Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1] and divided by pi. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Specular Reflection|Shader_specular.png|Tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor sat('''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''H''')&amp;lt;sup&amp;gt;''p''&amp;lt;/sup&amp;gt;, where '''H''' is the tangent-space direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). The specular power ''p'' controls the sharpness of the specularity.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent halfway direction interpolant, which in turn uses the tangent light direction and tangent view direction interpolants.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Diffuse Transflection|Shader_transflection.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the diffuse transflection factor '''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is multiplied by the front-facing factor ''f'' and divided by pi, and it is ''not'' saturated. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Specular Transmission|Shader_transmission.png|Specular power ''p'' (required)|Scalar|Calculates the specular transmission factor sat(&amp;amp;minus;'''L'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''V''')&amp;lt;sup&amp;gt;''p''&amp;lt;/sup&amp;gt;, where '''L''' and '''V''' are the tangent-space direction to light and direction to viewer. The specular power ''p'' controls the sharpness of the specularity. This produces a transmission strength when a material is viewed from the back side with respect to the incoming light.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent light direction and view direction interpolants.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (required), Normal vector '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together.&lt;br /&gt;
&lt;br /&gt;
If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; being weighted most when ''t'' is zero and the height corresponding to '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;2''t''&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;''t''&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;&amp;amp;frac12;''w'',&amp;amp;nbsp;''c''&amp;amp;nbsp;+&amp;amp;nbsp;&amp;amp;frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If rendering to the structure buffer is disabled, then the output value is always 1.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent view direction interpolant.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &amp;amp;lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &amp;amp;lt; 0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Render Glyph|Shader_glyph.png|2D vector '''TEXC''' (required), RGBA color '''RGBA''' (required)|RGBA color|Renders glyph or vector graphics with Slug. The '''TEXC''' input should use the Texcoord 2 interpolant, and the '''RGBA''' input would normally use the Vertex Color interpolant.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Composite Buffer|Shader_composite.png|None|RGBA color|Samples from the composite buffer at the current fragment coordinates.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Generate Impostor Normal / Depth|Shader_genimpostor.png|3D vector '''N''' (optional)|RGBA color|When impostor textures are being generated, this process outputs the impostor normal in the RGB channels, and it outputs the impostor depth in the alpha channel.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Shader Editor]]&lt;br /&gt;
* [[Basic Shader Processes]]&lt;br /&gt;
* [[Mathematical Shader Processes]]&lt;br /&gt;
* [[Interpolant Shader Processes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_transmission.png&amp;diff=669</id>
		<title>File:Shader transmission.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_transmission.png&amp;diff=669"/>
		<updated>2025-01-06T03:49:04Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_transflection.png&amp;diff=668</id>
		<title>File:Shader transflection.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_transflection.png&amp;diff=668"/>
		<updated>2025-01-06T03:48:52Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Complex_Shader_Processes&amp;diff=667</id>
		<title>Complex Shader Processes</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Complex_Shader_Processes&amp;diff=667"/>
		<updated>2025-01-06T03:46:56Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1]. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Specular Reflection|Shader_specular.png|Tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor ('''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''H''')&amp;lt;sup&amp;gt;''p''&amp;lt;/sup&amp;gt;, where '''H''' is the tangent-space direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). The specular power ''p'' controls the sharpness of the specularity.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent halfway direction interpolant, which in turn uses the tangent light direction and tangent view direction interpolants.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (required), Normal vector '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together.&lt;br /&gt;
&lt;br /&gt;
If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; being weighted most when ''t'' is zero and the height corresponding to '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;2''t''&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;''t''&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;&amp;amp;frac12;''w'',&amp;amp;nbsp;''c''&amp;amp;nbsp;+&amp;amp;nbsp;&amp;amp;frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If rendering to the structure buffer is disabled, then the output value is always 1.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent view direction interpolant.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &amp;amp;lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &amp;amp;lt; 0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Render Glyph|Shader_glyph.png|2D vector '''TEXC''' (required), RGBA color '''RGBA''' (required)|RGBA color|Renders glyph or vector graphics with Slug. The '''TEXC''' input should use the Texcoord 2 interpolant, and the '''RGBA''' input would normally use the Vertex Color interpolant.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Composite Buffer|Shader_composite.png|None|RGBA color|Samples from the composite buffer at the current fragment coordinates.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Generate Impostor Normal / Depth|Shader_genimpostor.png|3D vector '''N''' (optional)|RGBA color|When impostor textures are being generated, this process outputs the impostor normal in the RGB channels, and it outputs the impostor depth in the alpha channel.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Shader Editor]]&lt;br /&gt;
* [[Basic Shader Processes]]&lt;br /&gt;
* [[Mathematical Shader Processes]]&lt;br /&gt;
* [[Interpolant Shader Processes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_genimpostor.png&amp;diff=666</id>
		<title>File:Shader genimpostor.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_genimpostor.png&amp;diff=666"/>
		<updated>2025-01-06T03:46:50Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Complex_Shader_Processes&amp;diff=665</id>
		<title>Complex Shader Processes</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Complex_Shader_Processes&amp;diff=665"/>
		<updated>2025-01-06T03:22:09Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a list of the complex shader processes that are available in the [[Shader Editor]] under the Complex tab.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Diffuse Reflection|Shader_diffuse.png|Tangent-space normal '''N''' (optional)|Scalar|Calculates the Lambertian diffuse reflection factor '''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''L''', where '''L''' is the tangent-space direction to light. The result is saturated to the range [0,1]. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Specular Reflection|Shader_specular.png|Tangent-space normal '''N''' (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor ('''N'''&amp;amp;nbsp;&amp;amp;middot;&amp;amp;nbsp;'''H''')&amp;lt;sup&amp;gt;''p''&amp;lt;/sup&amp;gt;, where '''H''' is the tangent-space direction halfway between the direction to light and direction to viewer. If '''N''' is omitted, then it's as if '''N''' is (0,0,1). The specular power ''p'' controls the sharpness of the specularity.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent halfway direction interpolant, which in turn uses the tangent light direction and tangent view direction interpolants.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Diffuse Reflection|Shader_terraindiffuse.png|Terrain normal '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; (optional)|Scalar|Calculates the Lambertian diffuse reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Specular Reflection|Shader_terrainspecular.png|Terrain normal '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (optional), Terrain normal '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; (optional), Specular power ''p'' (required)|Scalar|Calculates the Blinn specular reflection factor for terrain. If any of the three inputs is missing, then the tangent-space normal vector is assumed to be (0,0,1). If all three inputs are present, then bump-mapped shading is performed. The three inputs should come from the three Terrain Normal processes. The specular power ''p'' controls the sharpness of the specularity.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Combine Normal Maps|Shader_combinenormals.png|Normal vector '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; (required), Normal vector '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; (required), Scalar ''t'' (optional)|3D vector|If ''t'' is omitted, calculates a new normal vector corresponding to the normal that would be produced if the two height maps producing the input normals were added together.&lt;br /&gt;
&lt;br /&gt;
If ''t'' is not omitted, then it determines how the heights are weighted, with the height corresponding to '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; being weighted most when ''t'' is zero and the height corresponding to '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; being weighted most when ''t'' is one. A value for ''t'' of 0.5 produces an average height, which is not the same as the sum produces when ''t'' is omitted.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reflect Vector|Shader_reflectvector.png|3D vector '''V''' (required), 3D vector '''N''' (optional)|3D vector|Calculates the reflection of the vector '''V''' across the vector '''N'''. If '''N''' is omitted, then it's as if '''N''' is (0,0,1).}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Smooth Parameter|Shader_smooth.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 3''t''&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;2''t''&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; componentwise. This has the effect of smoothing an interpolation parameter within the range [0,1] since the derivative at both endpoints is zero.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Steep Parameter|Shader_steep.png|Value ''t'' (required)|Value of size matching ''t''|Calculates 2''t''&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;''t''&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; componentwise. This has the effect of making an interpolation start quickly at a steep slope and finish smoothly.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Linear Ramp|Shader_linearramp.png|Value '''A''' (required)|Value of size matching '''A'''|Remaps the range [''c''&amp;amp;nbsp;&amp;amp;minus;&amp;amp;nbsp;&amp;amp;frac12;''w'',&amp;amp;nbsp;''c''&amp;amp;nbsp;+&amp;amp;nbsp;&amp;amp;frac12;''w''] to the range [0,1] componentwise, where ''c'' is a center value and ''w'' is the width of the input range. The values of ''c'' and ''w'' are specified in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Delta Depth|Shader_deltadepth.png|None|Scalar|Outputs the difference between the depth of the geometry in the structure buffer and the depth of the fragment being shaded, scaled by a factor ''s'' and clamped to the range [0,1]. The scale factor ''s'' is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If rendering to the structure buffer is disabled, then the output value is always 1.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Tangent to World Transform|Shader_tangenttoworld.png|3D vector '''V''' (required)|3D vector|Transforms the vector '''V''' from tangent space coordinates into world space coordinates.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses three 3D vector interpolants containing the matrix that transforms from tangent space to world space.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Parallax Offset|Shader_parallax.png|2D vector '''TEXC''' (required)|2D vector|Perturbs the input texture coordinates using the parallax information in the normal map and outputs the result. The normal map is specified in the settings for the process. If parallax mapping is disabled, then the input texture coordinates '''TEXC''' are simply passed through to the output.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent view direction interpolant.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Horizon Shadow|Shader_horizon.png|2D vector '''TEXC''' (required), RGB color '''RGB''' (required)|RGB color|Calculates the horizon map shadowing based on the two input horizon map sampled at the texture coordinates '''TEXC''' and multiplies the input color '''RGB''' by the amount of light reaching the surface. The horizon map is specified in the settings for the process. Flags for excluding horizon mapping for infinite or points lights can also be set. If horizon mapping is disabled or the shader is used in conjunction with a light type that has been excluded, then the input color '''RGB''' is simply passed through to the output.&lt;br /&gt;
&lt;br /&gt;
This process implicitly uses the tangent light direction interpolant.&lt;br /&gt;
&lt;br /&gt;
If the ambient reflection output depends on this process, then the results are undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Kill Fragment|Shader_kill.png|Scalar '''A''' (required), Scalar '''B''' (optional)|None|Kills the current fragment if '''A''' &amp;amp;lt; '''B'''. If '''B''' is omitted, then the fragment is killed if '''A''' &amp;amp;lt; 0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Render Glyph|Shader_glyph.png|2D vector '''TEXC''' (required), RGBA color '''RGBA''' (required)|RGBA color|Renders glyph or vector graphics with Slug. The '''TEXC''' input should use the Texcoord 2 interpolant, and the '''RGBA''' input would normally use the Vertex Color interpolant.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Composite Buffer|Shader_composite.png|None|RGBA color|Samples from the composite buffer at the current fragment coordinates.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Shader Editor]]&lt;br /&gt;
* [[Basic Shader Processes]]&lt;br /&gt;
* [[Mathematical Shader Processes]]&lt;br /&gt;
* [[Interpolant Shader Processes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_glyph.png&amp;diff=664</id>
		<title>File:Shader glyph.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_glyph.png&amp;diff=664"/>
		<updated>2025-01-06T03:22:02Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader glyph.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_composite.png&amp;diff=663</id>
		<title>File:Shader composite.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_composite.png&amp;diff=663"/>
		<updated>2025-01-06T03:14:22Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader composite.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Basic_Shader_Processes&amp;diff=662</id>
		<title>Basic Shader Processes</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Basic_Shader_Processes&amp;diff=662"/>
		<updated>2025-01-06T03:13:00Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a list of the basic shader processes that are available in the [[Shader Editor]] under the Basic tab.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Constant Scalar|Shader_constantscalar.png|None|Scalar|Outputs a constant scalar value that is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
A ''parameter slot'' may be specified in the process settings. If the parameter slot is set to &amp;amp;ldquo;Constant&amp;amp;rdquo; (the default), then the output of this process can never be changed while rendering. However, if one of the eight numbered parameter slots is selected, then it is possible to change the value output by this process without actually modifying the shader. For instance, the Set Shader Parameter script method can be used to change the output value of this process, effectively making it a variable parameter of the shader.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Constant Vector|Shader_constantvector.png|None|4D vector|Outputs a constant vector value that is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
See the note about parameter slots under the Constant Scalar process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Constant Color|Shader_constantcolor.png|None|RGBA color|Outputs a constant color value that is specified in the settings for the process. This color has components in the range 0 to 1, and it typically represents reflective colors.&lt;br /&gt;
&lt;br /&gt;
See the note about parameter slots under the Constant Scalar process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Constant Luminance|Shader_constantluminance.png|None|RGBA color|Outputs a constant luminance value that is specified in the settings for the process. This luminance has unlimited range, and it typically represents lighting or emissive colors.&lt;br /&gt;
&lt;br /&gt;
See the note about parameter slots under the Constant Scalar process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Shader Time|Shader_time.png|None|Scalar|Outputs a scalar value in the range [0,1) representing the current shader time. The shader time runs from 0 to 1 over a period of 120 seconds and then repeats by wrapping back to 0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Fragment Depth|Shader_fragmentdepth.png|None|Scalar|Outputs a scalar value equal to the depth of the fragment in camera space.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Primitive Facing|Shader_primitivefacing.png|None|Scalar|Outputs a scalar value that is +1.0 for front-facing primitives and &amp;amp;minus;1.0 for back-facing primitives.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Merge 2D|Shader_merge2d.png|Scalar '''x''' (required), Scalar '''y''' (required)|2D vector|Combines the two scalar inputs '''x''' and '''y''' into a single 2D vector output.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Merge 3D|Shader_merge3d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required)|3D vector|Combines the three scalar inputs '''x''', '''y''', and '''z''' into a single 3D vector output.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Merge 4D|Shader_merge4d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required), Scalar '''w''' (required)|4D vector|Combines the four scalar inputs '''x''', '''y''', '''z''', and '''w''' into a single 4D vector output.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Texture Map|Shader_texturemap.png|2D or 3D vector '''TEXC''' (required), scalar '''BIAS''' (optional)|RGBA color|Samples a texture map using the input texture coordinates '''TEXC'''. The texture map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
The size of the input '''TEXC''' is determined by the type of the texture map. The input is a 2D vector for 2D and Rect textures, and the size is a 3D vector for 3D, Cube, and Array 2D textures.&lt;br /&gt;
&lt;br /&gt;
If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.&lt;br /&gt;
&lt;br /&gt;
Note that this process should not be used for normal maps. Use the Normal Map process instead.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Normal Map|Shader_normalmap.png|2D vector '''TEXC''' (required), scalar '''BIAS''' (optional)|3D vector|Samples a normal map using the input texture coordinates '''TEXC'''. The normal map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Paint Texture|Shader_painttexture.png|2D vector '''TEXC''' (required)|RGBA color|Samples a paint space texture map using the input texture coordinates '''TEXC'''. The texture map is determined by what paint space is associated with the geometry being rendered. The input vector is normally the output of the Paint Texcoord [[Interpolant Shader Processes|interpolant process]].}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Texture|Shader_terraintexture.png|None|RGBA color|Samples a terrain texture palette. The texture map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
Note that this process should not be used for terrain normal maps. Use the Terrain Normal process instead.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Normal 1, 2, 3|Shader_terrainnormal1.png|None|3D vector|Samples a terrain normal palette. The normal map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If one of these three processes exists, then all three should exist and should use the same normal map. Their outputs should be used as inputs for the Terrain Diffuse Reflection, Terrain Specular Reflection, and Terrain Environment Output processes.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Impostor Texture|Shader_impostortexture.png|None|RGBA color|Samples an impostor texture map. The texture map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
Note that this process should not be used for impostor normal maps. Use the Impostor Normal process instead.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Impostor Normal|Shader_impostornormal.png|None|3D vector|Samples an impostor normal map. The normal map is specified in the settings for the process.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Shader Editor]]&lt;br /&gt;
* [[Mathematical Shader Processes]]&lt;br /&gt;
* [[Complex Shader Processes]]&lt;br /&gt;
* [[Interpolant Shader Processes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Shader_Editor&amp;diff=661</id>
		<title>Shader Editor</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Shader_Editor&amp;diff=661"/>
		<updated>2025-01-06T03:11:26Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: /* Output Processes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to create a limitless variety of materials within the context of a graphical interface.&lt;br /&gt;
&lt;br /&gt;
== Opening the Shader Editor ==&lt;br /&gt;
&lt;br /&gt;
[[File:Shadereditor.png|right|frame|'''Figure 1.''' The Shader Editor window.]] The image to the right shows the Shader Editor. The Shader Editor is opened from inside the [[Material Editor]] by choosing '''Edit Shader''' from the '''Material''' menu. If the selected material already had conventional attributes assigned to it through the settings in the Material Editor, then the Shader Editor will initially show a translation of those attributes into the shader graph. If the selected material was empty (because no settings had been specified for it yet), then the Shader Editor will initially show default graph with a minimal number of nodes.&lt;br /&gt;
&lt;br /&gt;
== Shader Graphs ==&lt;br /&gt;
&lt;br /&gt;
A shader is represented in the Shader Editor by what is known as a ''data flow graph''. The nodes in this graph are called ''processes'', and the edges in this graph are called ''routes''. A shader is a special type of graph called a ''directed acyclic graph'', or ''DAG'', meaning that data flows in a specific direction from one process to another and there are no loops.&lt;br /&gt;
&lt;br /&gt;
Each box in the shader graph represents a single process. A process can be a simple mathematical operation, a constant input value such as a color, an interpolated value such as the direction to the light source, or a more complex operation defined by the engine such as a parallax offset calculation.&lt;br /&gt;
&lt;br /&gt;
A route is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of data from one process to another. Routes begin at one process and end at a ''port'' belonging to another process. Every process has between zero and four ports, and each can be occupied by only one incoming route at a time. Ports with a plain background are required, and ports with a striped background are optional. All required ports must have an incoming route attached to them in order for the shader to be valid.&lt;br /&gt;
&lt;br /&gt;
== Editing a Shader ==&lt;br /&gt;
&lt;br /&gt;
The tabbed lists on the left side of the Shader Editor show the processes that are available for use in a shader. They are divided into four categories that are described in more detail below: Basic, Math, Complex, and Interpolants. A new process is added to a shader by selecting it in the list and then clicking in the viewport. The editor won't let you place two processes on top of each other, and the cursor will change to indicate where it's possible to place a new process.&lt;br /&gt;
&lt;br /&gt;
Routes are added to a shader by clicking inside the circle on the right side of a process and dragging into a port belonging to another process. This causes a new route to be created beginning at the process you clicked on and ending at the input port to which you dragged. If a port is already occupied by another route, then the existing route is deleted and replaced with the new route that you are creating. You cannot connect a route from one process to a port belonging to any other process preceding that process in the graph because it would create a cycle.&lt;br /&gt;
&lt;br /&gt;
The physical position of a process in the viewport is irrelevant. The data flow structure of a shader is determined entirely by the route connections. Processes may be placed in any convenient location. &lt;br /&gt;
&lt;br /&gt;
== Processes ==&lt;br /&gt;
&lt;br /&gt;
A process takes between zero and four inputs and produces at most a single output. The output may be sent to any number of input ports for other processes.&lt;br /&gt;
&lt;br /&gt;
For many types of processes, the process box shown in the Shader Editor displays additional information. For example, the Texture Map process shows a small image of the texture map, and the Constant Vector process shows the four constant values that it outputs. Most mathematical operations display a mathematical expression showing exactly how their input values are used to calculate an output value.&lt;br /&gt;
&lt;br /&gt;
Double-clicking on a process, or selecting a process and typing Ctrl-I, opens the Process Info window for that process. In the Process Info window, every process has a comment field that let's you specify some text that is displayed at the bottom of the process box in the Shader Editor. Some processes also have extra settings that appear in the Process Info window.&lt;br /&gt;
&lt;br /&gt;
Each type of process available for use in a shader is described individually on the following pages (corresponding to the groups displayed in the Shader Editor):&lt;br /&gt;
&lt;br /&gt;
* [[Basic Shader Processes | List of basic processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Mathematical Shader Processes | List of mathematical processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Complex Shader Processes | List of complex processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Interpolant Shader Processes | List of interpolant processes]]&lt;br /&gt;
&lt;br /&gt;
== Routes ==&lt;br /&gt;
&lt;br /&gt;
The routes in a shader graph carry data from one process to another. Each route can carry between one and four floating-point values&amp;amp;mdash;the actual number is determined by the output size of the route's start process.&lt;br /&gt;
&lt;br /&gt;
A swizzle and negation may be applied to a route. These can be set by double-clicking on a route or by selecting a route and typing Ctrl-I. By default, the swizzle for a route is &amp;lt;code&amp;gt;xyzw&amp;lt;/code&amp;gt;, meaning that there is no change to the order of the components. If any other swizzle is specified, or the values are negated, then that information is displayed in a small box at the center of the path representing the route. The swizzle may be specified using any letters from the sets &amp;lt;code&amp;gt;xyzw&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;rgba&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;stpq&amp;lt;/code&amp;gt;. Specifying only a single letter is shorthand for the same letter repeated four times. For example, the swizzle &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; is equivalent to the swizzle &amp;lt;code&amp;gt;zzzz&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If a route carries fewer than four components, then each component specified in its swizzle is clamped to the last available component. For example, if a route carries only three components, then any &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; in the swizzle ultimately interpreted as the third component of the data carried by the route. The swizzle &amp;lt;code&amp;gt;wxyz&amp;lt;/code&amp;gt; would really mean &amp;lt;code&amp;gt;zxyz&amp;lt;/code&amp;gt;. This is particularly important in the case that two routes of different sizes are used as inputs to a binary operation. The operation is performed using the number of components for larger of the two routes, so the missing components of the smaller route are taken from the components specified by the clamped swizzle.&lt;br /&gt;
&lt;br /&gt;
== Shader Editor Tools ==&lt;br /&gt;
&lt;br /&gt;
There are four tool buttons in the upper-left corner of the Shader Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.)&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead3|Icon|Shortcut|Function}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move'''. Selects a process or route in a shader. Clicking outside of a process and dragging will create a box that selects all of the processes inside it. Clicking inside a process and dragging moves all of the currently selected processes. (When processes are moved, they are automatically prevented from moving on top of other processes.)}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the shader viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Changes the scale of the shader viewport. Using the mouse wheel with any other tool also zooms.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_section.png]]||'''Draw Section'''. Draws a rectangular box with a title bar behind all processes in the graph. This can be used to visually organize groups of processes in a shader.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Output Processes ==&lt;br /&gt;
&lt;br /&gt;
Each shader graph contains a set of ''output processes'' that represent the final values produced by the shader. These are colored green in the shader editor, they cannot be deleted, and they can have no output routes. The only output process that has a required input port is the '''Ambient Reflection Output''' process. All other output processes have only optional input ports and are ignored if they are not used.&lt;br /&gt;
&lt;br /&gt;
The individual output processes are described in the following table.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Ambient&amp;amp;nbsp;Reflection&amp;amp;nbsp;Output|Shader_ambientoutput.png|RGB color '''RGB''' (required), Normal '''N''' (optional)|None|This is the primary output process for the ambient shader. The color sent to this output process is combined with the ambient lighting environment to produce the final ambient light reflection for a material. The normal vector '''N''' is currently unused, but will be important in future ambient lighting models.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Light&amp;amp;nbsp;Reflection&amp;amp;nbsp;Output|Shader_lightingoutput.png|RGB color '''RGB''' (optional), Impostor depth '''Z''' (optional)|None|This is the primary output process for the light shader. The color sent to this output process is combined with the color from a light source to produce the final light reflection for a material.&lt;br /&gt;
&lt;br /&gt;
In an impostor shader, the alpha channel of the output of the Impostor Normal process should be sent to the '''Z''' input port to provide the impostor depth.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Alpha&amp;amp;nbsp;Output|Shader_alphaoutput.png|Scalar '''A''' (optional)|None|If a material is transparent, then the alpha value sent to this output process controls the transparency. This is currently useful only for objects rendered in the effect pass. If the Glow Output process is used, then the Alpha Output process is ignored.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Alpha&amp;amp;nbsp;Test&amp;amp;nbsp;Output|Shader_alphatestoutput.png|Scalar '''A''' (optional)|None|If a material uses the alpha test, then the value sent to this output process is the value that is tested. The material must have the alpha test flag set in the Material Manager for this output process to be used.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Emission&amp;amp;nbsp;Output|Shader_emissionoutput.png|RGB color '''RGB''' (optional)|None|The color sent to this output process is added to the final ambient color as an emission term.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Glow&amp;amp;nbsp;Output|Shader_glowoutput.png|Scalar '''A''' (optional)|None|If a material uses emission glow, then the value sent to this output process determines the glow intensity. The material must have the emission glow flag set in the Material Manager for this output process to be used. If the alpha test flag is set, then the Glow Output process is ignored.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Bloom&amp;amp;nbsp;Output|Shader_bloomoutput.png|Scalar '''A''' (optional)|None|If a material uses specular bloom, then the value sent to this output process determines the bloom intensity. The material must have the specular bloom flag set in the Material Manager for this output process to be used.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reflection&amp;amp;nbsp;Buffer&amp;amp;nbsp;Output|Shader_reflectionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the reflection buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the reflection. Normal incidence reflectivity and bump offset scale can be configured in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Refraction&amp;amp;nbsp;Buffer&amp;amp;nbsp;Output|Shader_refractionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the refraction buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the refraction. The bump offset scale can be configured in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Environment&amp;amp;nbsp;Output|Shader_environmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional), scalar '''BIAS''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain&amp;amp;nbsp;Environment&amp;amp;nbsp;Output|Shader_terrainenvironmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. Terrain normal vectors may be sent to the '''N'''&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, '''N'''&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;, and '''N'''&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; input ports in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Material Editor]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Basic_Shader_Processes&amp;diff=660</id>
		<title>Basic Shader Processes</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Basic_Shader_Processes&amp;diff=660"/>
		<updated>2025-01-06T03:09:44Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a list of the basic shader processes that are available in the [[Shader Editor]] under the Basic tab.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Constant Scalar|Shader_constantscalar.png|None|Scalar|Outputs a constant scalar value that is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
A ''parameter slot'' may be specified in the process settings. If the parameter slot is set to &amp;amp;ldquo;Constant&amp;amp;rdquo; (the default), then the output of this process can never be changed while rendering. However, if one of the eight numbered parameter slots is selected, then it is possible to change the value output by this process without actually modifying the shader. For instance, the Set Shader Parameter script method can be used to change the output value of this process, effectively making it a variable parameter of the shader.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Constant Vector|Shader_constantvector.png|None|4D vector|Outputs a constant vector value that is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
See the note about parameter slots under the Constant Scalar process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Constant Color|Shader_constantcolor.png|None|RGBA color|Outputs a constant color value that is specified in the settings for the process. This color has components in the range 0 to 1, and it typically represents reflective colors.&lt;br /&gt;
&lt;br /&gt;
See the note about parameter slots under the Constant Scalar process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Constant Luminance|Shader_constantluminance.png|None|RGBA color|Outputs a constant luminance value that is specified in the settings for the process. This luminance has unlimited range, and it typically represents lighting or emissive colors.&lt;br /&gt;
&lt;br /&gt;
See the note about parameter slots under the Constant Scalar process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Shader Time|Shader_time.png|None|Scalar|Outputs a scalar value in the range [0,1) representing the current shader time. The shader time runs from 0 to 1 over a period of 120 seconds and then repeats by wrapping back to 0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Fragment Depth|Shader_fragmentdepth.png|None|Scalar|Outputs a scalar value equal to the depth of the fragment in camera space.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Primitive Facing|Shader_primitivefacing.png|None|Scalar|Outputs a scalar value that is +1.0 for front-facing primitives and &amp;amp;minus;1.0 for back-facing primitives.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Merge 2D|Shader_merge2d.png|Scalar '''x''' (required), Scalar '''y''' (required)|2D vector|Combines the two scalar inputs '''x''' and '''y''' into a single 2D vector output.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Merge 3D|Shader_merge3d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required)|3D vector|Combines the three scalar inputs '''x''', '''y''', and '''z''' into a single 3D vector output.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Merge 4D|Shader_merge4d.png|Scalar '''x''' (required), Scalar '''y''' (required), Scalar '''z''' (required), Scalar '''w''' (required)|4D vector|Combines the four scalar inputs '''x''', '''y''', '''z''', and '''w''' into a single 4D vector output.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Texture Map|Shader_texturemap.png|2D or 3D vector '''TEXC''' (required), scalar '''BIAS''' (optional)|RGBA color|Samples a texture map using the input texture coordinates '''TEXC'''. The texture map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
The size of the input '''TEXC''' is determined by the type of the texture map. The input is a 2D vector for 2D and Rect textures, and the size is a 3D vector for 3D, Cube, and Array 2D textures.&lt;br /&gt;
&lt;br /&gt;
If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.&lt;br /&gt;
&lt;br /&gt;
Note that this process should not be used for normal maps. Use the Normal Map process instead.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Normal Map|Shader_normalmap.png|2D vector '''TEXC''' (required), scalar '''BIAS''' (optional)|3D vector|Samples a normal map using the input texture coordinates '''TEXC'''. The normal map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If the '''BIAS''' input is connected, then it's value is added to the mipmap index calculated by the hardware.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Paint Texture|Shader_painttexture.png|2D vector '''TEXC''' (required)|RGBA color|Samples a paint space texture map using the input texture coordinates '''TEXC'''. The texture map is determined by what paint space is associated with the geometry being rendered. The input vector is normally the output of the Paint Texcoord [[Interpolant Shader Processes|interpolant process]].}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Texture|Shader_terraintexture.png|None|RGBA color|Samples a terrain texture palette. The texture map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
Note that this process should not be used for terrain normal maps. Use the Terrain Normal process instead.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain Normal 1, 2, 3|Shader_terrainnormal1.png|None|3D vector|Samples a terrain normal palette. The normal map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
If one of these three processes exists, then all three should exist and should use the same normal map. Their outputs should be sent to a Terrain Diffuse Reflection and/or Terrain Specular Reflection process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Impostor Texture|Shader_impostortexture.png|None|RGBA color|Samples an impostor texture map. The texture map is specified in the settings for the process.&lt;br /&gt;
&lt;br /&gt;
Note that this process should not be used for impostor normal maps. Use the Impostor Normal process instead.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Impostor Normal|Shader_impostornormal.png|None|3D vector|Samples an impostor normal map. The normal map is specified in the settings for the process.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Shader Editor]]&lt;br /&gt;
* [[Mathematical Shader Processes]]&lt;br /&gt;
* [[Complex Shader Processes]]&lt;br /&gt;
* [[Interpolant Shader Processes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Shader_Editor&amp;diff=659</id>
		<title>Shader Editor</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Shader_Editor&amp;diff=659"/>
		<updated>2025-01-06T03:06:16Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: /* Output Processes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
There are two ways to create materials in the C4 Engine. The first method is to simply configure a set of predefined attributes in the [[Material Editor]]. This is the easiest and fastest way to create a new material, and most ordinary materials can be made using only those attributes. A more advanced method is to use the Shader Editor to define the exact calculations used by the engine to render a material. The Shader Editor provides you with the power to create a limitless variety of materials within the context of a graphical interface.&lt;br /&gt;
&lt;br /&gt;
== Opening the Shader Editor ==&lt;br /&gt;
&lt;br /&gt;
[[File:Shadereditor.png|right|frame|'''Figure 1.''' The Shader Editor window.]] The image to the right shows the Shader Editor. The Shader Editor is opened from inside the [[Material Editor]] by choosing '''Edit Shader''' from the '''Material''' menu. If the selected material already had conventional attributes assigned to it through the settings in the Material Editor, then the Shader Editor will initially show a translation of those attributes into the shader graph. If the selected material was empty (because no settings had been specified for it yet), then the Shader Editor will initially show default graph with a minimal number of nodes.&lt;br /&gt;
&lt;br /&gt;
== Shader Graphs ==&lt;br /&gt;
&lt;br /&gt;
A shader is represented in the Shader Editor by what is known as a ''data flow graph''. The nodes in this graph are called ''processes'', and the edges in this graph are called ''routes''. A shader is a special type of graph called a ''directed acyclic graph'', or ''DAG'', meaning that data flows in a specific direction from one process to another and there are no loops.&lt;br /&gt;
&lt;br /&gt;
Each box in the shader graph represents a single process. A process can be a simple mathematical operation, a constant input value such as a color, an interpolated value such as the direction to the light source, or a more complex operation defined by the engine such as a parallax offset calculation.&lt;br /&gt;
&lt;br /&gt;
A route is a directed edge shown as a curve with an arrowhead at one end, and it represents the flow of data from one process to another. Routes begin at one process and end at a ''port'' belonging to another process. Every process has between zero and four ports, and each can be occupied by only one incoming route at a time. Ports with a plain background are required, and ports with a striped background are optional. All required ports must have an incoming route attached to them in order for the shader to be valid.&lt;br /&gt;
&lt;br /&gt;
== Editing a Shader ==&lt;br /&gt;
&lt;br /&gt;
The tabbed lists on the left side of the Shader Editor show the processes that are available for use in a shader. They are divided into four categories that are described in more detail below: Basic, Math, Complex, and Interpolants. A new process is added to a shader by selecting it in the list and then clicking in the viewport. The editor won't let you place two processes on top of each other, and the cursor will change to indicate where it's possible to place a new process.&lt;br /&gt;
&lt;br /&gt;
Routes are added to a shader by clicking inside the circle on the right side of a process and dragging into a port belonging to another process. This causes a new route to be created beginning at the process you clicked on and ending at the input port to which you dragged. If a port is already occupied by another route, then the existing route is deleted and replaced with the new route that you are creating. You cannot connect a route from one process to a port belonging to any other process preceding that process in the graph because it would create a cycle.&lt;br /&gt;
&lt;br /&gt;
The physical position of a process in the viewport is irrelevant. The data flow structure of a shader is determined entirely by the route connections. Processes may be placed in any convenient location. &lt;br /&gt;
&lt;br /&gt;
== Processes ==&lt;br /&gt;
&lt;br /&gt;
A process takes between zero and four inputs and produces at most a single output. The output may be sent to any number of input ports for other processes.&lt;br /&gt;
&lt;br /&gt;
For many types of processes, the process box shown in the Shader Editor displays additional information. For example, the Texture Map process shows a small image of the texture map, and the Constant Vector process shows the four constant values that it outputs. Most mathematical operations display a mathematical expression showing exactly how their input values are used to calculate an output value.&lt;br /&gt;
&lt;br /&gt;
Double-clicking on a process, or selecting a process and typing Ctrl-I, opens the Process Info window for that process. In the Process Info window, every process has a comment field that let's you specify some text that is displayed at the bottom of the process box in the Shader Editor. Some processes also have extra settings that appear in the Process Info window.&lt;br /&gt;
&lt;br /&gt;
Each type of process available for use in a shader is described individually on the following pages (corresponding to the groups displayed in the Shader Editor):&lt;br /&gt;
&lt;br /&gt;
* [[Basic Shader Processes | List of basic processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Mathematical Shader Processes | List of mathematical processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Complex Shader Processes | List of complex processes]]&lt;br /&gt;
&lt;br /&gt;
* [[Interpolant Shader Processes | List of interpolant processes]]&lt;br /&gt;
&lt;br /&gt;
== Routes ==&lt;br /&gt;
&lt;br /&gt;
The routes in a shader graph carry data from one process to another. Each route can carry between one and four floating-point values&amp;amp;mdash;the actual number is determined by the output size of the route's start process.&lt;br /&gt;
&lt;br /&gt;
A swizzle and negation may be applied to a route. These can be set by double-clicking on a route or by selecting a route and typing Ctrl-I. By default, the swizzle for a route is &amp;lt;code&amp;gt;xyzw&amp;lt;/code&amp;gt;, meaning that there is no change to the order of the components. If any other swizzle is specified, or the values are negated, then that information is displayed in a small box at the center of the path representing the route. The swizzle may be specified using any letters from the sets &amp;lt;code&amp;gt;xyzw&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;rgba&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;stpq&amp;lt;/code&amp;gt;. Specifying only a single letter is shorthand for the same letter repeated four times. For example, the swizzle &amp;lt;code&amp;gt;z&amp;lt;/code&amp;gt; is equivalent to the swizzle &amp;lt;code&amp;gt;zzzz&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If a route carries fewer than four components, then each component specified in its swizzle is clamped to the last available component. For example, if a route carries only three components, then any &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;q&amp;lt;/code&amp;gt; in the swizzle ultimately interpreted as the third component of the data carried by the route. The swizzle &amp;lt;code&amp;gt;wxyz&amp;lt;/code&amp;gt; would really mean &amp;lt;code&amp;gt;zxyz&amp;lt;/code&amp;gt;. This is particularly important in the case that two routes of different sizes are used as inputs to a binary operation. The operation is performed using the number of components for larger of the two routes, so the missing components of the smaller route are taken from the components specified by the clamped swizzle.&lt;br /&gt;
&lt;br /&gt;
== Shader Editor Tools ==&lt;br /&gt;
&lt;br /&gt;
There are four tool buttons in the upper-left corner of the Shader Editor window, and they have the following uses. In addition to clicking on the tool button, each of these tools can also be selected by pressing the shortcut number key as shown in the table. (The shortcuts were chosen to be the same as the corresponding tools in the World Editor.)&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead3|Icon|Shortcut|Function}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_select.png]]|1|'''Select / Move'''. Selects a process or route in a shader. Clicking outside of a process and dragging will create a box that selects all of the processes inside it. Clicking inside a process and dragging moves all of the currently selected processes. (When processes are moved, they are automatically prevented from moving on top of other processes.)}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_scroll.png]]|6|'''Scroll'''. Scrolls the shader viewport. Holding the Alt key with any other tool temporarily selects the scroll tool.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_zoom.png]]|7|'''Zoom'''. Changes the scale of the shader viewport. Using the mouse wheel with any other tool also zooms.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Tablerow3|[[File:Tool_section.png]]||'''Draw Section'''. Draws a rectangular box with a title bar behind all processes in the graph. This can be used to visually organize groups of processes in a shader.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Output Processes ==&lt;br /&gt;
&lt;br /&gt;
Each shader graph contains a set of ''output processes'' that represent the final values produced by the shader. These are colored green in the shader editor, they cannot be deleted, and they can have no output routes. The only output process that has a required input port is the '''Ambient Reflection Output''' process. All other output processes have only optional input ports and are ignored if they are not used.&lt;br /&gt;
&lt;br /&gt;
The individual output processes are described in the following table.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Ambient&amp;amp;nbsp;Reflection&amp;amp;nbsp;Output|Shader_ambientoutput.png|RGB color '''RGB''' (required), Normal '''N''' (optional)|None|This is the primary output process for the ambient shader. The color sent to this output process is combined with the ambient lighting environment to produce the final ambient light reflection for a material. The normal vector '''N''' is currently unused, but will be important in future ambient lighting models.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Light&amp;amp;nbsp;Reflection&amp;amp;nbsp;Output|Shader_lightingoutput.png|RGB color '''RGB''' (optional), Impostor depth '''Z''' (optional)|None|This is the primary output process for the light shader. The color sent to this output process is combined with the color from a light source to produce the final light reflection for a material.&lt;br /&gt;
&lt;br /&gt;
In an impostor shader, the alpha channel of the output of the Impostor Normal process should be sent to the '''Z''' input port to provide the impostor depth.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Alpha&amp;amp;nbsp;Output|Shader_alphaoutput.png|Scalar '''A''' (optional)|None|If a material is transparent, then the alpha value sent to this output process controls the transparency. This is currently useful only for objects rendered in the effect pass. If the Glow Output process is used, then the Alpha Output process is ignored.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Alpha&amp;amp;nbsp;Test&amp;amp;nbsp;Output|Shader_alphatestoutput.png|Scalar '''A''' (optional)|None|If a material uses the alpha test, then the value sent to this output process is the value that is tested. The material must have the alpha test flag set in the Material Manager for this output process to be used.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Emission&amp;amp;nbsp;Output|Shader_emissionoutput.png|RGB color '''RGB''' (optional)|None|The color sent to this output process is added to the final ambient color as an emission term.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Glow&amp;amp;nbsp;Output|Shader_glowoutput.png|Scalar '''A''' (optional)|None|If a material uses emission glow, then the value sent to this output process determines the glow intensity. The material must have the emission glow flag set in the Material Manager for this output process to be used. If the alpha test flag is set, then the Glow Output process is ignored.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Bloom&amp;amp;nbsp;Output|Shader_bloomoutput.png|Scalar '''A''' (optional)|None|If a material uses specular bloom, then the value sent to this output process determines the bloom intensity. The material must have the specular bloom flag set in the Material Manager for this output process to be used.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reflection&amp;amp;nbsp;Buffer&amp;amp;nbsp;Output|Shader_reflectionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the reflection buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the reflection. Normal incidence reflectivity and bump offset scale can be configured in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Refraction&amp;amp;nbsp;Buffer&amp;amp;nbsp;Output|Shader_refractionoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the refraction buffer is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the refraction. The bump offset scale can be configured in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Environment&amp;amp;nbsp;Output|Shader_environmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. A tangent-space normal vector may be sent to the '''N''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Terrain&amp;amp;nbsp;Environment&amp;amp;nbsp;Output|Shader_terrainenvironmentoutput.png|RGB color '''RGB''' (optional), Tangent-space normal vector '''N''' (optional)|None|If this output process has an input, then a sample from the environment map is multiplied by the input color and added to the final ambient color. Terrain normal vectors may be sent to the '''N1''', '''N2''', and '''N3''' input port in order to create a bumpy appearance for the environment map. An override environment map can be specified in the settings for the process.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Material Editor]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_terrainenvironmentoutput.png&amp;diff=658</id>
		<title>File:Shader terrainenvironmentoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_terrainenvironmentoutput.png&amp;diff=658"/>
		<updated>2025-01-06T03:06:12Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader terrainenvironmentoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_environmentoutput.png&amp;diff=657</id>
		<title>File:Shader environmentoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_environmentoutput.png&amp;diff=657"/>
		<updated>2025-01-06T03:03:23Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader environmentoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_refractionoutput.png&amp;diff=656</id>
		<title>File:Shader refractionoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_refractionoutput.png&amp;diff=656"/>
		<updated>2025-01-06T03:03:07Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader refractionoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_reflectionoutput.png&amp;diff=655</id>
		<title>File:Shader reflectionoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_reflectionoutput.png&amp;diff=655"/>
		<updated>2025-01-06T03:02:54Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader reflectionoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_bloomoutput.png&amp;diff=654</id>
		<title>File:Shader bloomoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_bloomoutput.png&amp;diff=654"/>
		<updated>2025-01-06T03:02:40Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader bloomoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_glowoutput.png&amp;diff=653</id>
		<title>File:Shader glowoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_glowoutput.png&amp;diff=653"/>
		<updated>2025-01-06T03:02:28Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader glowoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_emissionoutput.png&amp;diff=652</id>
		<title>File:Shader emissionoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_emissionoutput.png&amp;diff=652"/>
		<updated>2025-01-06T03:02:16Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader emissionoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_alphatestoutput.png&amp;diff=651</id>
		<title>File:Shader alphatestoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_alphatestoutput.png&amp;diff=651"/>
		<updated>2025-01-06T03:02:04Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader alphatestoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_alphaoutput.png&amp;diff=650</id>
		<title>File:Shader alphaoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_alphaoutput.png&amp;diff=650"/>
		<updated>2025-01-06T03:01:50Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader alphaoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_lightingoutput.png&amp;diff=649</id>
		<title>File:Shader lightingoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_lightingoutput.png&amp;diff=649"/>
		<updated>2025-01-06T03:01:36Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader lightingoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_ambientoutput.png&amp;diff=648</id>
		<title>File:Shader ambientoutput.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_ambientoutput.png&amp;diff=648"/>
		<updated>2025-01-06T03:01:21Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader ambientoutput.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_sumproducts.png&amp;diff=647</id>
		<title>File:Shader sumproducts.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_sumproducts.png&amp;diff=647"/>
		<updated>2025-01-06T02:55:12Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=Mathematical_Shader_Processes&amp;diff=646</id>
		<title>Mathematical Shader Processes</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=Mathematical_Shader_Processes&amp;diff=646"/>
		<updated>2025-01-06T02:54:54Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a list of the mathematical shader processes that are available in the [[Shader Editor]] under the Math tab.&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
{{Tablehead|Process|Description}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Absolute Value|Shader_abs.png|Value '''A'''|Value of size matching '''A'''|Calculates the absolute value of each component of the input '''A'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Add|Shader_add.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise sum of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Average|Shader_avg.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise average of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Cosine|Shader_cos.png|Scalar '''A'''|Scalar|Calculates the cosine of the input '''A''', where the input is measured in radians.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Cross Product|Shader_xpd.png|3D vectors '''A''' and '''B'''|3D vector|Calculates the cross product of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Divide|Shader_div.png|Value '''A''', Scalar '''B'''|Value of size matching '''A'''|Calculates the quotient of each component of the input '''A''' and the scalar input '''B'''.&lt;br /&gt;
&lt;br /&gt;
''Tip:'' If you're dividing by a constant value, then it would be more efficient to multiply by the reciprocal of the constant. For example, you should multiply by 0.5 instead of dividing by 2.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Dot Product 3D|Shader_dp3.png|3D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Dot Product 4D|Shader_dp4.png|4D vectors '''A''' and '''B'''|Scalar|Calculates the dot product of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Exp Base 2|Shader_ex2.png|Scalar '''A'''|Scalar|Calculates 2 raised to the power given by the input '''A'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Expand|Shader_expand.png|Value '''A'''|Value of size matching '''A'''|Multiplies each component of the input '''A''' by 2.0 and then subtracts 1.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Floor|Shader_flr.png|Value '''A'''|Value of size matching '''A'''|Calculates the floor of each component of the input '''A'''. To calculate a ceiling, negate the input and output of the Floor process.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Fraction|Shader_frc.png|Value '''A'''|Value of size matching '''A'''|Calculates the fraction of each component of the input '''A'''. The fraction of a number is the difference between that number and its floor.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Invert|Shader_invert.png|Value '''A'''|Value of size matching '''A'''|Subtracts each component of the input '''A''' from 1.0.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Linear Interpolate|Shader_lrp.png|Values '''A''', '''B''', and '''t'''|Value of size matching largest of '''A''', '''B''', and '''t'''|Calculates the linear interpolation between the components of '''A''' and '''B''' using the components of the input '''t''' as the interpolation parameter.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Log Base 2|Shader_lg2.png|Scalar '''A'''|Scalar|Calculates the logarithm base 2 of the input '''A'''. If the input is not positive, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Magnitude 3D|Shader_magnitude3d.png|3D vector '''A'''|Scalar|Calculates the magnitude of the input '''A'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Maximum|Shader_max.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise maximum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the maximum of only '''A''' and '''B''' is calculated.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Minimum|Shader_min.png|Values '''A''' and '''B''' (required), value '''C''' (optional)|Value of size matching larger of '''A''', '''B''', and '''C'''|Calculates the componentwise minimum of the inputs '''A''', '''B''', and '''C'''. If input '''C''' is omitted, then the minimum of only '''A''' and '''B''' is calculated.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Multiply|Shader_mul.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise product of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Multiply Add|Shader_mad.png|Values '''A''', '''B''', and '''C'''|Value of size matching largest of '''A''', '''B''', and '''C'''|Calculates the componentwise product of the inputs '''A''' and '''B''' and then adds the components of the input '''C'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Normalize 3D|Shader_normalize3d.png|3D vector '''A'''|3D vector|Normalizes the input '''A'''. If the input is the zero vector, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Power|Shader_pow.png|Scalars '''A''' and '''B'''|Scalar|Calculates the input '''A''' raised to the power of the input '''B'''. If the input '''A''' is negative, then the result is undefined. If the input '''A''' is zero and the input '''B''' is not positive, then the result is undefined.&lt;br /&gt;
&lt;br /&gt;
''Tip:'' If you're just squaring a value, then it would be more efficient to multiply the value by itself. That is, you should calculate '''A'''&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;'''A''' using the '''Multiply''' process instead of raising '''A''' to the power of 2.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reciprocal|Shader_rcp.png|Scalar '''A'''|Scalar|Calculates the reciprocal of the input '''A'''. If the input is zero, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Reciprocal Square Root|Shader_rsq.png|Scalar '''A'''|Scalar|Calculates the reciprocal square root of the input '''A'''. If the input is not positive, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Round|Shader_round.png|Value '''A'''|Value of size matching '''A'''|Rounds each component of the input '''A''' to the nearest integer.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Saturate|Shader_sat.png|Value '''A'''|Value of size matching '''A'''|Clamps each component of the input '''A''' to the range [0,1].}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Equal|Shader_seq.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Greater Equal|Shader_sge.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Greater Than|Shader_sgt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is greater than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Less Equal|Shader_sle.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than or equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set of Less Than|Shader_slt.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is less than the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Set if Not Equal|Shader_sne.png|Value '''A''' (required), Value '''B''' (optional)|Value of size matching larger of '''A''' and '''B'''|For each component of the inputs '''A''' and '''B''', the corresponding component of the output is set to 1.0 if the component of '''A''' is not equal to the same component of '''B''', and 0.0 otherwise. If input '''B''' is omitted, then it is assumed to be a vector of zeros.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Sine|Shader_sin.png|Scalar '''A'''|Scalar|Calculates the sine of the input '''A''', where the input is measured in radians.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Square Root|Shader_sqrt.png|Scalar '''A'''|Scalar|Calculates the square root of the input '''A'''. If the input is negative, then the result is undefined.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Subtract|Shader_sub.png|Values '''A''' and '''B'''|Value of size matching larger of '''A''' and '''B'''|Calculates the componentwise difference of the inputs '''A''' and '''B'''.}}&lt;br /&gt;
|-&lt;br /&gt;
{{Process|Sum of Products|Shader_sumproducts.png|Values '''A''', '''B''', '''C''', and '''D'''|Value of size matching largest of '''A''', '''B''', '''C''', and '''D'''|Calculates the componentwise products of the inputs '''A''' and '''B''' and the componentwise products of the inputs '''C''' and '''D''' and then calculates the componentwise sum of the results.}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Shader Editor]]&lt;br /&gt;
* [[Basic Shader Processes]]&lt;br /&gt;
* [[Complex Shader Processes]]&lt;br /&gt;
* [[Interpolant Shader Processes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Shaders]]&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_sub.png&amp;diff=645</id>
		<title>File:Shader sub.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_sub.png&amp;diff=645"/>
		<updated>2025-01-06T02:51:26Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader sub.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_sqrt.png&amp;diff=644</id>
		<title>File:Shader sqrt.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_sqrt.png&amp;diff=644"/>
		<updated>2025-01-06T02:51:12Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader sqrt.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_sin.png&amp;diff=643</id>
		<title>File:Shader sin.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_sin.png&amp;diff=643"/>
		<updated>2025-01-06T02:50:58Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader sin.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_sne.png&amp;diff=642</id>
		<title>File:Shader sne.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_sne.png&amp;diff=642"/>
		<updated>2025-01-06T02:50:44Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader sne.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_slt.png&amp;diff=641</id>
		<title>File:Shader slt.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_slt.png&amp;diff=641"/>
		<updated>2025-01-06T02:50:28Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader slt.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_sle.png&amp;diff=640</id>
		<title>File:Shader sle.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_sle.png&amp;diff=640"/>
		<updated>2025-01-06T02:49:24Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader sle.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_sgt.png&amp;diff=639</id>
		<title>File:Shader sgt.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_sgt.png&amp;diff=639"/>
		<updated>2025-01-06T02:49:09Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader sgt.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_sge.png&amp;diff=638</id>
		<title>File:Shader sge.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_sge.png&amp;diff=638"/>
		<updated>2025-01-06T02:48:55Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader sge.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_seq.png&amp;diff=637</id>
		<title>File:Shader seq.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_seq.png&amp;diff=637"/>
		<updated>2025-01-06T02:48:42Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader seq.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_sat.png&amp;diff=636</id>
		<title>File:Shader sat.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_sat.png&amp;diff=636"/>
		<updated>2025-01-06T02:48:28Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader sat.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_round.png&amp;diff=635</id>
		<title>File:Shader round.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_round.png&amp;diff=635"/>
		<updated>2025-01-06T02:48:16Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader round.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_rsq.png&amp;diff=634</id>
		<title>File:Shader rsq.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_rsq.png&amp;diff=634"/>
		<updated>2025-01-06T02:48:03Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader rsq.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_rcp.png&amp;diff=633</id>
		<title>File:Shader rcp.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_rcp.png&amp;diff=633"/>
		<updated>2025-01-06T02:47:50Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader rcp.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
	<entry>
		<id>https://c4engine.com/wiki/index.php?title=File:Shader_pow.png&amp;diff=632</id>
		<title>File:Shader pow.png</title>
		<link rel="alternate" type="text/html" href="https://c4engine.com/wiki/index.php?title=File:Shader_pow.png&amp;diff=632"/>
		<updated>2025-01-06T02:47:39Z</updated>

		<summary type="html">&lt;p&gt;Eric Lengyel: Eric Lengyel uploaded a new version of File:Shader pow.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Eric Lengyel</name></author>
	</entry>
</feed>