Texturing component

This component provides extensive textures support. 2D textures may be loaded from image files (ImageTexture), movie files (MovieTexture) or encoded directly in VRML/X3D files (PixelTexture, also ImageTexture with data urls). Multiple textures may be overlayed on a single polygon in a variety of ways. Texture coordinates may be explicitly provided or automatically calculated, and may be transformed.

See also X3D specification of the Texturing component.

Contents:

See also Castle Game Engine (and view3dscene) extensions related to texturing.

1. Demos

For demos and tests of these features, see the texturing_advanced and movie_texture and multi_texturing subdirectories inside our VRML/X3D demo models.

2. Supported nodes

  • ImageTexture(Pascal API: TImageTextureNode),
    PixelTexture(Pascal API: TPixelTextureNode).

    These nodes define a texture, from an external file (in the usual case of ImageTexture) or embedded inside the X3D file (in case of PixelTexture, or ImageTexture using data URI).

    ImageTexture allows various texture formats, including JPEG, PNG, GIF, BMP, PPM, RGBE, KTX, DDS. See Castle Image Viewer documentation for a detailed list.

    Note about alpha channel: alpha channel of the textures is fully supported, both a simple yes-no transparency (done by alpha_test in OpenGL) and full range transparency (done by blending in OpenGL, just like partially transparent materials). See "override alpha channel detection" extension description for details. The bottom line is: everything will magically work fast and look perfect.

  • TextureCoordinate(Pascal API: TTextureCoordinateNode),
    TextureTransform(Pascal API: TTextureTransformNode).

    These nodes specify how the texture is mapped onto the shape. All X3D nodes have some "default" texture mapping, if you don't provide explicit texture coordinates.

  • MovieTexture(Pascal API: TMovieTextureNode)

    This node defines a texture that is actually a (playing) movie file.

    TODO: for now, the sound of the movie is not played.

    Notes:

    • Current implementation keeps the whole encoded video in memory (images may be discarded after loading (by TCastleSceneCore.FreeResources feature), but still the textures for all frames are kept in memory). The disadvantage is that this makes it impractical to load "real" movies, normal 2-hour movie will most usually eat all of your memory. The advantage is that once the movie is loaded, the playback is super-fast, just like you would display normal nodes with static textures. Since there's no streaming, decoding etc. in the background while you browse your models.

      In other words, this is quite perfect for movie textures with game effects, like smoke or flame. But it's not a substitute for your "real" multimedia movie player.

    • ffmpeg must be installed and available on $PATH to actually open any movie format. See instructions for installing ffmpeg in view3dscene docs. Thanks to ffmpeg, we can handle probably any movie format you will ever need to open.

    • We can also open movies from images sequence. This doesn't require ffmpeg, and allows for some tricks (movie texture with alpha channel). See "Movies from images sequence" extension description.

  • MultiTexture(Pascal API: TMultiTextureNode),
    MultiTextureCoordinate(Pascal API: TMultiTextureCoordinateNode),
    MultiTextureTransform(Pascal API: TMultiTextureTransformNode)

    Multi-texturing means that you can use multiple textures on a single polygon (face). A number of textures can be mixed, in a way resembling the "layers" concept you from image editing applications (like GIMP or Photoshop). For each layer, you specify which texture to use, the "mode" (how it is mixed), also each layer may have it's own texture coordinates.

    Some examples are present in the demo-models, in particular in multi_texturing subdirectory.

    We implement various modes (in MultiTexture.mode), sources (MultiTexture.source) and functions (in MultiTexture.function). As an extension, we also allow separate mode and sources for RGB and alpha, as documented in Proposed improved MultiTexture.mode specification.

    TODO: Modes not implemented yet: MODULATEALPHA_ADDCOLOR, MODULATEINVALPHA_ADDCOLOR, MODULATEINVCOLOR_ADDALPHA.

    MultiTexture.source values "DIFFUSE" and "SPECULAR" are treated the same. They don't make much sense in the context of PBR material parameters anyway.

    Note that the multi-texturing specification of X3D has unfortunately some issues. Clarifications and our extensions are documented here.

    Note that in case of 2D games, when the camera cannot move freely, you can often use multiple polygons (each with a single texture) rendered on top of each other (positioned with slight shift), instead of using a single polygon with multi-texturing. Both choices are fine, in principle: use whichever is more comfortable for your case.

  • TextureCoordinateGenerator(Pascal API: TTextureCoordinateGeneratorNode)

    This node can be used instead of TextureCoordinate(Pascal API: TTextureCoordinateNode) to automatically calculate the coordinates based on some algorithm.

    Supported modes are now "SPHERE", "COORD", "COORD-EYE", "CAMERASPACEPOSITION", "CAMERASPACENORMAL", "CAMERASPACEREFLECTIONVECTOR". We also allow some extensions: "WORLDSPACEREFLECTIONVECTOR" and "WORLDSPACENORMAL", "BOUNDS", "BOUNDS2D" and "BOUNDS3D".

    Note that "CAMERASPACEPOSITION" and "COORD-EYE" are exactly the same thing. Google confirms it (e.g. this source code also treats them as equal and in this old bitmanagement spec they mention they are equal).

    TODO: not implemented modes: "SPHERE-LOCAL", "NOISE", "NOISE-EYE", "SPHERE-REFLECT", "SPHERE-REFLECT-LOCAL".

  • TextureProperties(Pascal API: TTexturePropertiesNode)

    Adjust various texture filtering/wrapping properties. Supported fields now are:

    • minificationFilter, magnificationFilter,
    • anisotropicDegree,
    • boundaryModeS, boundaryModeT, boundaryModeR.

    Some details about supported and unsupported fields:

    anisotropicDegree (fully supported)

    See examples/viewport_and_scenes/anisotropic_filtering/ for example Pascal code that creates TextureProperties nodes and requests anisotropic filtering for specific textures. We plan to enable adjusting this in CGE editor at some point too.

    textureCompression (we do not support compressing texture data at runtime)

    We don't plan to support the this field now.

    Reason: If you're looking for a way to use GPU compressed textures, simply place the GPU compressed texture data in DDS or KTX files. Using GPU compressed textures in DDS and KTX is fully supported, and always will be a more efficient solution anyway.

    boundaryModeS/T/R overrides texture repeatS/T/R

    Be aware that using TextureProperties means that texture fields repeatS/T/R is ignored.

    E.g. ImageTexture.repeatS is ignored, instead we'll use TextureProperties.boundaryModeS to determine whether texture repeats or not in S coordinate.

    You should instead adjust boundaryModeS/T/R, which is by default "REPEAT" (regardless of the texture type, 2D or 3D). You get more options for it now: "CLAMP_TO_EDGE", "REPEAT" and "MIRRORED_REPEAT".

    This is a particular trap for 3D texture nodes, like ImageTexture3D, that have by default repeatS/T/R = FALSE (unlike 2D textures like ImageTexture that have by default repeatS/T = TRUE). So merely adding a TextureProperties node to 3D texture, with everything left as default, changes the default (for 3D textures) "clamp" mode into "repeat". Adjust the boundaryModeS/T/R to "CLAMP_TO_EDGE" to restore "clamp" mode.

    clamp to border (unsupported)

    We don't plan to support the "clamp to border" wrapping modes for boundaryModeXxx fields. For the same reason, we don't plan to support related borderColor and borderWidth fields, that only make sense for "clamp to border" mode. The idea of "clamping to border" is from OpenGL but it does not have much actual usage and it was removed/rejected from various other modern APIs:

    For this reason, "CLAMP", "CLAMP_TO_EDGE", "CLAMP_TO_BOUNDARY" are all equivalent and work like "CLAMP_TO_EDGE".

    meaning of "DEFAULT" minification / magnification filters

    The default value of magnificationFilter and minificationFilter is "DEFAULT". Which means to use the texture filtering mode specified by TCastleRenderOptions.MinificationFilter, TCastleRenderOptions.MagnificationFilter (by default nice minLinearMipmapLinear, magLinear), matching behavior when TextureProperties was not specified.

    So this behavior is most natural.

    (It was a bit more tricky in older CGE versions <= 7.0-alpha.1, before 2022-03-09.)

3. Supported image file formats

See Castle Image Viewer for the full list of image formats we can handle.

See also details about DDS format support and KTX format support.

4. Clarifications to X3D multi-texturing specification

Comments about X3D MultiTexturing problems and solutions (used in our engine, and proposed for future X3D spec) are here.