-
Notifications
You must be signed in to change notification settings - Fork 0
Custom Shaders (Advanced)
Basic syntax of a custom shader:
Properties
Custom Vertex-/Pixelshader In-/Outputs
#include <scHeaderObject>
custom code
#include <scObject>
Example:
#define SKIN_ABLEDO <skin1.xyz>
#define SKIN_NORMAL <skin2.xyz>
#define NORMALMAPPING
#include <scHeaderObject>
#define CUSTOM_VS_POSITION
#ifndef MATWORLD
#define MATWORLD
float4x4 matWorld;
#endif
#ifndef MATWORLDVIEWPROJ
#define MATWORLDVIEWPROJ
float4x4 matWorldViewProj;
#endif
#ifndef VECTIME
#define VECTIME
float4 vecTime;
#endif
#ifndef VECSKILL1
#define VECSKILL1
float4 vecSkill1;
#endif
float4 Custom_VS_Position(vsIn In)
{
float3 P = mul(In.Pos, matWorld);
float force_x = vecSkill1.x;
float force_y = vecSkill1.y;
float speed = sin((vecTime.w+0.2*(P.x+P.y+P.z)) * vecSkill1.z);
if (In.Pos.y > 0 ) // move only upper part of tree
{
In.Pos.x += speed * force_x * In.Pos.y;
In.Pos.z += speed * force_y * In.Pos.y;
In.Pos.y -= 0.1*abs(speed*(force_x+force_y)) * In.Pos.y;
}
return mul(In.Pos,matWorldViewProj);
}
#include <scObject>
When writing your own code, ALWAYS USE
#ifndef X
#define X
put your variable here
#endif
everytime you introduce a global variable. The Ubershader already contains a bunch of generic variables like float3x3 matTangent
and float4x4 matWorldView
etc. . To make sure you don't double define a variable, or are suddenly missing a variable when a Shade-C Update removes a variable from it's ubershader, use the above mentioned defines.
Naming convention is to just write the variable you want to introduce in CAPITAL letters when checking the defines.
Example:
#ifndef MATTANGENT
#define MATTANGENT
float3x3 matTangent;
#endif
This might seem like more work at first, but will save you A LOT of trouble later on!
Set the vertexshader target. Default is vs_2_0.
Note: Some Ati/Amd cards don't support different pixel- and vertexshadertargets. You should therefor always set pixel and vertexshader to the same target.
Example:
#define TARGET_VS vs_2_0
Set the pixelshader target. Default is ps_2_a.
Note: Some Ati/Amd cards don't support different pixel- and vertexshadertargets. You should therefor always set pixel and vertexshader to the same target.
Example:
#define TARGET_PS ps_2_a
Renders a Z-PrePass for the Object, which MIGHT speed up the rendering. This makes sense for heavy shaders like parallax occlusion mapping and the likes. On the other hand, it MIGHT slow down rendering if you actiavte this for fast/small shaders. If you are unsure, just give it a try and see if performance gets better or worse ;)
Example:
#define ZPREPASS
Set the skin that skin1 is mapped to.
Default is #define SKIN1 entSkin1
Example:
#define SKIN1 entSkin1 //use entity skin1
#define SKIN1 mtlSkin1 //use material skin1
#define SKIN1 entSkin3 //use entity skin3, very uncommon, but possible
Set the skin that skin2 is mapped to.
Default is #define SKIN2 entSkin2
Example:
#define SKIN2 entSkin2 //use entity skin2, common
#define SKIN2 mtlSkin2 //use material skin2, uncommmon
#define SKIN2 entSkin3 //use entity skin3, very uncommon, but possible
Set the skin that skin3 is mapped to.
Default is #define SKIN3 entSkin3
Example:
#define SKIN3 entSkin3 //use entity skin3, common
#define SKIN3 mtlSkin3 //use material skin3, uncommmon
#define SKIN3 entSkin1 //use entity skin1, very uncommon, but possible
Set the skin that skin4 is mapped to.
Default is #define SKIN4 entSkin4
Example:
#define SKIN4 entSkin4 //use entity skin4, common
#define SKIN4 mtlSkin4 //use material skin4, uncommmon
#define SKIN4 entSkin3 //use entity skin3, very uncommon, but possible
If set, skin1 won't be accesible in the shader.
Use this to speed up the shader a bit if you don't need skin1 access.
If set, skin2 won't be accesible in the shader.
Use this to speed up the shader a bit if you don't need skin2 access.
If set, skin3 won't be accesible in the shader.
Use this to speed up the shader a bit if you don't need skin3 access.
If set, skin4 won't be accesible in the shader.
Use this to speed up the shader a bit if you don't need skin4 access.
struct vsIn
{
float4 Pos : POSITION;
half2 Tex : TEXCOORD0;
half2 TexShadow : TEXCOORD1;
half3 Normal : NORMAL;
#ifdef NORMALMAPPING
half4 Tangent: TEXCOORD2;
#endif
#ifdef BONES
int4 BoneIndices: BLENDINDICES;
float4 BoneWeights: BLENDWEIGHT;
#endif
#ifdef CUSTOM_VS_INPUT_EXTEND
CUSTOM_VS_INPUT_EXTEND
#endif
};
struct vsOut
{
float4 Pos : POSITION;
float Pos2D : TEXCOORD0;
float4 Tex : TEXCOORD1;
float3 Normal : TEXCOORD2;
#ifdef NORMALMAPPING
float3 Tangent : TEXCOORD3;
float3 Binormal : TEXCOORD4;
#endif
#ifdef CUSTOM_VS_OUTPUT_EXTEND
CUSTOM_VS_OUTPUT_EXTEND
#endif
};
struct psOut
{
float4 NormalsAndDepth : COLOR0;
half4 AlbedoAndEmissiveMask : COLOR1;
float4 MaterialData : COLOR2;
//float4 lightmapAnd : COLOR3;
#ifdef CUSTOM_PS_OUTPUT_EXTEND
CUSTOM_PS_OUTPUT_EXTEND
#endif
};
If you want to extend the In-/Outputs, define CUSTOM_VS_INPUT_EXTEND (addition)
, CUSTOM_VS_OUTPUT_EXTEND (addition)
or CUSTOM_PS_OUTPUT_EXTEND (addition)
. You should always use the highest available texcoord (which is TEXCOORD7) for your extension, as future Shade-C updates might introduce more used TEXCOORDs.
Examples:
//Correct
#define CUSTOM_VS_OUTPUT_EXTEND (
float4 myCustomOutput1 : TEXCOORD7;
float4 myCustomOutput2 : TEXCOORD6;
)
//Incorrect
#define CUSTOM_VS_OUTPUT_EXTEND (
float4 myCustomOutput1 : TEXCOORD5;
float4 myCustomOutput2 : TEXCOORD6;
)
Also, You have to define your custom In-/Outputs BEFORE including scHeaderObject!
Example:
#define CUSTOM_VS_OUTPUT_EXTEND (
float4 myCustomOutput1 : TEXCOORD7;
float4 myCustomOutput2 : TEXCOORD6;
)
#include <scHeaderObject>
custom code goes here
#include <scObject>
float4 Custom_VS_Position(vsIn In)
float2 Custom_VS_Tex(vsIn In)
float Custom_VS_TexShadow(vsIn In)
float3 Custom_VS_Normal(vsIn In) //return in View Space! ( return mul(output, matWorldView) )
float3 Custom_VS_Tangent(vsIn In) //return in View Space! ( return mul(output, matWorldView) )
float3 Custom_VS_Binormal(In) //return in View Space! ( return mul(output, matWorldView) )
Extends the VertexShader. Out
will hold all data which has been processed so far.
vsOut Custom_VS_Extend(vsIn In, vsOut Out)
float4 Custom_PS_Tex(vsOut In)
Custom Texcoords. XY is used to fetch the model's skins. ZW is used to fetch the static shadowmap (not implemented yet).
half4 Custom_PS_Skin1(vsOut In)
half4 Custom_PS_Skin2(vsOut In)
half4 Custom_PS_Skin3(vsOut In)
half4 Custom_PS_Skin4(vsOut In)
half Custom_PS_Alpha(vsOut In, half skinAlpha)
half3 Custom_PS_Normalmapping(vsOut In, half3 skinNormals); //Note: skinNormals are in range 0..1!
float Custom_PS_Depth(vsOut In) //Depth should be linear
half3 Custom_PS_Diffuse(vsOut In, half3 skinAlbedo)
half3 Custom_PS_Color(vsOut In, half3 skinColor)
half3 Custom_PS_EmissiveMask(vsOut In, half skinEmissiveMask)
float Custom_PS_MaterialID(vsOut In) //range 0..1
float Custom_PS_SpecularPower(vsOut In) //range 0..1
half Custom_PS_Gloss(vsOut In, half skinGloss)
Extends the PixelShader. Out
will hold all data which has been processed so far.
psOut Custom_PS_Extend(vsOut In, psOut Out)