-
Notifications
You must be signed in to change notification settings - Fork 14
Shader Fragments (.vertex_fragment, .pixel_fragment)
Many shaders in Spore are not coded in a single .hlsl file directly. Instead, they are generated by combining different pieces of code, known as shader fragments. This allows to easily create multiple variations of a single shader (see Shader Builders) and avoids repeating code.
There are two types of shader fragments: one for vertex shaders and another for pixel shaders. Shader fragments are coded in HLSL, using the vs_3_0 and ps_3_0 versions.
Shader fragments are stored in the material_shader_fragments~ (0x40212002) folder, in a .smt file. To pack custom shader fragments, those must be placed inside a folder named 0x00000003.smt.unpacked. Inside, two types of files will be used:
-
.vertex_fragment: Fragments that can be used in vertex shaders. -
.pixel_fragment: Fragments that can be used in pixel shaders.
Each file must only contain one shader fragment. The files use the ArgScript format common in many other Spore file formats.
A thing you must keep in mind if you want to pack your own shader fragents is that, since all mods would use the same folder (0x00000003.smt.unpacked), Spore will only read the fragments of one mod. Inside the pack you should also include all the fragments that Spore uses.
Fragments have two attributes, input and output, that specifiy which members are available to use in the code.
Fragments can specify HLSL code in two different ways:
-
declareCode: Here goes any functions, uniforms and samplers used by the fragment code. The Shader Data is also specified here. -
code: The main code of the shader. The code used here will go inside the main function. There are three "special" variables that can be used:In(containing the input),Out(containing the output), andCurrent(containing the current data).Currentis the most used, as it reflects the changes made by other shader fragments.
Both block types contain plain HLSL code, and are ended with a endCode statement (there are examples below).
In, Out and Current are structures whose members depend on the fragment (this is exaplined further below).
They are placed inside a vertexFragment block.
The input attribute can use the following members:
-
position: afloat4containing the vertex coordinates. -
normal: afloat4containing the normal vector of the vertex -
color: afloat4, the verte color -
color1: afloat4 -
texcoord0: afloat4, usually the UV coordinates used for texturing -
texcoord1: afloat4 -
texcoord2: afloat4 -
texcoord3: afloat4 -
texcoord4: afloat4 -
texcoord5: afloat4 -
texcoord6: afloat4 -
texcoord7: afloat4 -
blendIndices: anint4 -
blendWeights: afloat4 -
pointSize: afloat -
position2: afloat4 -
normal2: afloat4 -
tangent: afloat4 -
binormal: afloat4 -
fog: afloat -
blendIndices2: anint4 -
blendWeights2: afloat4
The output attribute can use any of the following members:
-
position: afloat4 -
color: afloat4 -
color1: afloat4 -
fog: afloat -
pointSize: afloat
A few things to consider:
- The attributes available at
Currentare all the ones present in both the input and output. - Output can also use texcoords: you can specify the amount of texcoords used using the
-texcoordsoption; there you must also specify the typeof texcoord variable (e.g.float2). For example, this will use 2 texcoords of typefloat3:
output position color -texcoords 2 float3.
- To access
OutandCurrenttexcoords you must do it likeCurrent.texcoord<t0>. The texcoords there will be of the type specified in the-texcoordsoption.
An example of vertex fragment:
input values...
The vertex attributes this shader receives as input. The values can be any of the members explained before.
output values... -texcoords texcoordCount texcoordType
The attributes that will be output by the shader.
-
values: Any of the members explaied before. -
texcoordCount: The number of texcoords used at Current/Out by this fragment. -
texcoordType: The type of texcoord used at Current/Out, any of the following:float2, float3, float4
declareCode # Your HLSL code endCode
The declaration code, here you can specifiy uniforms, shader data, samplers, functions,...
code # Your HLSL code endCode
The main code. This goes inside the main function of the shader. Here you can use In, Out and Current.
They are placed inside a pixelFragment block.
The input attribute can use any of the following members:
-
position: afloat4 -
normal: afloat3 -
tangent: afloat3 -
binormal: afloat3 -
color: afloat4 -
color1: afloat4 -
indices: aint4
The output attribute can use any of the following members:
-
color: afloat4, the pixel color for the main render target -
color1: afloat4 -
color2: afloat4 -
color3: afloat4 -
depth: afloat, used in the depth buffer
Pixel fragments can also receive texcoords as input. To do so, use the option -texcoords specifying the number of texcoords used. As before, you have to access them like Current.texcoord<t1>.
Pixel fragments can use a specific number of samplers. Similar to texcoords, these must be accessed with <s0>, such as Sampler<s2>.
Additionally, the texture attribute can be used to load a texture when using this fragment.
An example of pixel fragment:
input values... -texcoords texcoordCount
The attributes this shader receives as input.
-
values: Any of the input members explained before. -
texcoordCount: The number of texcoords used at In/Current by this fragment.
output values...
The attributes that will be output by the shader.
-
values: Any of the output members explaied before.
samplers samplerCount
Specifies the amount of generic samplers used by this fragment. These samplers are accessed with Sampler<s0>, Sampler<s1>,.... Apart from these, you can also specify other samplers in the declare code block.
texture resourceID -minFilter minFilter -mipFilter mipFilter -magFilter magFilter -addresses addresses...
Specifies a texture that will be loaded when this fragment is used.
-
resourceID: Group (optional) and name of the texture. For example:0x4D324A4E. -
minFilter: A member of theD3DTEXTUREFILTERTYPEenum. -
mipFilter: A member of theD3DTEXTUREFILTERTYPEenum. -
magFilter: A member of theD3DTEXTUREFILTERTYPEenum. -
addresses: One to three values (u, v, w), members of theD3DTEXTUREADDRESSenum.
declareCode # Your HLSL code endCode
The declaration code, here you can specifiy uniforms, shader data, samplers, functions,...
code # Your HLSL code endCode
The main code. This goes inside the main function of the shader. Here you can use In, Out and Current.

