- Qt 3D Studio
- File Formats
- The .shader Format
- Qt 3D Studio 2.8 Manual

# The .shader Format

Qt 3D Studio supports custom materials used to render elements. Materials are arbitrary single-pass GLSL shaders, wrapped in a file format providing an artist-friendly interface for tweaking material parameters in Studio.

## Overview

The general structure of a `.shader` file is shown below. Note that some of the attributes and elements shown here are optional (and this example does not include all possible attributes):

     <Material formalName="..." version="1.0">
       <MetaData author="...">
         <Property name="..." />
         <Property name="..." />
       </MetaData>
       <Shaders type="GLSL">
         <Shader>
           <VertexShader>
             <Source>...</Source>
           </VertexShader>
           <FragmentShader>
             <Source>...</Source>
           </FragmentShader>
         </Shader>
       </Shaders>
     </Material>

The actual code for the shader is placed within the `<Source>` elements.

## Schemata

Legal `.shader` files are described by the following formal schemata. The RelaxNG Compact schema is the reference from which the XML Schema Definition schema was derived.

### RelaxNG Compact (`.rnc)`

     grammar \{
       start = MaterialElement                       # Everything is wrapped in a <Material> element

       MaterialElement = element Material \{
         attribute version     \{"1.0"\,              }# This file describes version 1.0 only
         attribute formalName  \{text\?,              }# The formalName attribute is optional;      default: filename (minus extension)
         attribute description \{text\?,              }# Optional long description of the material
         MetaDataElement?,                           # <MetaData> is optional,
         ShadersElement                              # but <Shaders> is required
       \}

       MetaDataElement = element MetaData\{
         attribute author      \{text\?,              }# Various descriptive attributes (optional)
         attribute created     \{text\?,}
         attribute modified    \{text\?,}
         PropertyElement*                            # Zero or more <Property> elements
       \}

       PropertyElement = element Property \{          # All <Property> attributes are optional except for name
         attribute name        \{xsd:ID\,             }# The internal, script name of the property (must be a unique identifier)
         attribute description \{text\?,              }# Tooltip to display in Inspector palette
         attribute formalName  \{text\?,              }# The name to display in Inspector palette;  default: the property `name`
         attribute type        \{PropertyType\?,      }# The type of the property (defined below);  default: Float
         attribute min         \{xsd:float\?,         }# UI min value for numeric types;            default: none
         attribute max         \{xsd:float\?,         }# UI max value for numeric types;            default: none
         attribute default     \{text\?,              }# Default value for the property;            default: 0/""
         attribute usage       \{UsageType\?,         }# Only for textures;                         default: diffuse
         attribute filter      \{FilterType\?,        }# Only for textures;                         default: linear
         attribute clamp       \{ClampType\?          }# Only for textures;                         default: wrap
       \}

       ShadersElement = element Shaders \{
         attribute type        \{"GLSL" | "HLSL"\?,   }# Optional shader type; only GLSL supported. default: GLSL
         attribute version     \{text\?,              }# Code version
         element Shared        \{text\?,              }# Arbitrary definition code to run for all shaders (optional)
         ShaderElement+                              # There must be at least one <Shader> in the .shader file
       \}

       ShaderElement = element Shader \{
         attribute name        \{xsd:NCName\?,        }# An identifier-like name
         ((VSEl | FSEl) | (VSEl & FSEl))             # Either or both of <VertexShader> and <FragmentShader>, in either order
       \}
       VSEl = element VertexShader   \{ShaderContent\}
       FSEl = element FragmentShader \{ShaderContent\}

       ShaderContent = element Source  \{ text \      }# Shaders currently require a single <Source> element

       UsageType     = "diffuse" | "specular" | "bump" | "environment"
       FilterType    = "nearest" | "linear"
       ClampType     = "clamp" | "wrap"
       PropertyType  = "Boolean" | "Color" | "Float" | "Float2" | "Font"
                       | "FontSize" | "Image" | "Import" | "Long" | "Mesh"
                       | "MultiLineString" | "Rotation" | "String" | "Vector"
                       | "Texture" | "Texture3D" | "TextureCube"
     \}

### XML Schema Definition (`.xsd)`

     <?xml version="1.0" encoding="UTF-8"?>
     <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
       <xs:element name="Material">
         <xs:complexType>
           <xs:sequence>
             <xs:element minOccurs="0" ref="MetaData"/>
             <xs:element ref="Shaders"/>
           </xs:sequence>
           <xs:attribute name="version" use="required">
             <xs:simpleType>
               <xs:restriction base="xs:token">
                 <xs:enumeration value="1.0"/>
               </xs:restriction>
             </xs:simpleType>
           </xs:attribute>
           <xs:attribute name="formalName"/>
           <xs:attribute name="description"/>
         </xs:complexType>
       </xs:element>
       <xs:element name="MetaData">
         <xs:complexType>
           <xs:sequence>
             <xs:element minOccurs="0" maxOccurs="unbounded" ref="Property"/>
           </xs:sequence>
           <xs:attribute name="author"/>
           <xs:attribute name="created"/>
           <xs:attribute name="modified"/>
         </xs:complexType>
       </xs:element>
       <xs:element name="Property">
         <xs:complexType>
           <xs:attribute name="name" use="required" type="xs:ID"/>
           <xs:attribute name="description"/>
           <xs:attribute name="formalName"/>
           <xs:attribute name="type" type="PropertyType"/>
           <xs:attribute name="min" type="xs:float"/>
           <xs:attribute name="max" type="xs:float"/>
           <xs:attribute name="default"/>
           <xs:attribute name="usage" type="UsageType"/>
           <xs:attribute name="filter" type="FilterType"/>
           <xs:attribute name="clamp" type="ClampType"/>
         </xs:complexType>
       </xs:element>
       <xs:element name="Shaders">
         <xs:complexType>
           <xs:sequence>
             <xs:element minOccurs="0" ref="Shared"/>
             <xs:element maxOccurs="unbounded" ref="Shader"/>
           </xs:sequence>
           <xs:attribute name="type">
             <xs:simpleType>
               <xs:restriction base="xs:token">
                 <xs:enumeration value="GLSL"/>
                 <xs:enumeration value="HLSL"/>
               </xs:restriction>
             </xs:simpleType>
           </xs:attribute>
           <xs:attribute name="version"/>
         </xs:complexType>
       </xs:element>
       <xs:element name="Shared" type="xs:string"/>
       <xs:element name="Shader">
         <xs:complexType>
           <xs:choice>
             <xs:choice>
               <xs:element ref="VertexShader"/>
               <xs:element ref="FragmentShader"/>
             </xs:choice>
             <xs:choice minOccurs="0" maxOccurs="unbounded">
               <xs:element ref="VertexShader"/>
               <xs:element ref="FragmentShader"/>
             </xs:choice>
           </xs:choice>
           <xs:attribute name="name" type="xs:NCName"/>
         </xs:complexType>
       </xs:element>
       <xs:element name="VertexShader" type="ShaderContent"/>
       <xs:element name="FragmentShader" type="ShaderContent"/>
       <xs:complexType name="ShaderContent">
         <xs:sequence>
           <xs:element ref="Source"/>
         </xs:sequence>
       </xs:complexType>
       <xs:element name="Source" type="xs:string"/>
       <xs:simpleType name="UsageType">
         <xs:restriction base="xs:token">
           <xs:enumeration value="diffuse"/>
           <xs:enumeration value="specular"/>
           <xs:enumeration value="bump"/>
           <xs:enumeration value="environment"/>
         </xs:restriction>
       </xs:simpleType>
       <xs:simpleType name="FilterType">
         <xs:restriction base="xs:token">
           <xs:enumeration value="nearest"/>
           <xs:enumeration value="linear"/>
         </xs:restriction>
       </xs:simpleType>
       <xs:simpleType name="ClampType">
         <xs:restriction base="xs:token">
           <xs:enumeration value="clamp"/>
           <xs:enumeration value="wrap"/>
         </xs:restriction>
       </xs:simpleType>
       <xs:simpleType name="PropertyType">
         <xs:restriction base="xs:token">
           <xs:enumeration value="Boolean"/>
           <xs:enumeration value="Color"/>
           <xs:enumeration value="Float"/>
           <xs:enumeration value="Float2"/>
           <xs:enumeration value="Font"/>
           <xs:enumeration value="FontSize"/>
           <xs:enumeration value="Image"/>
           <xs:enumeration value="Import"/>
           <xs:enumeration value="Long"/>
           <xs:enumeration value="Mesh"/>
           <xs:enumeration value="MultiLineString"/>
           <xs:enumeration value="Rotation"/>
           <xs:enumeration value="String"/>
           <xs:enumeration value="Vector"/>
           <xs:enumeration value="Texture"/>
           <xs:enumeration value="Texture3D"/>
           <xs:enumeration value="TextureCube"/>
         </xs:restriction>
       </xs:simpleType>
     </xs:schema>