-
Notifications
You must be signed in to change notification settings - Fork 11
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).Current
is 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
: afloat4
containing the vertex coordinates. -
normal
: afloat4
containing 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
Current
are 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
-texcoords
option; 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
Out
andCurrent
texcoords you must do it likeCurrent.texcoord<t0>
. The texcoords there will be of the type specified in the-texcoords
option.
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 theD3DTEXTUREFILTERTYPE
enum. -
mipFilter
: A member of theD3DTEXTUREFILTERTYPE
enum. -
magFilter
: A member of theD3DTEXTUREFILTERTYPE
enum. -
addresses
: One to three values (u, v, w
), members of theD3DTEXTUREADDRESS
enum.
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
.