/engine.fxh Secret
Last active
April 7, 2018 18:30
Star
You must be signed in to star a gist
W3D shader generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define CBUFFER_BEGIN(name) cbuffer name { struct { | |
#define CBUFFER_BEGIN_SHARED(name) shared cbuffer name { struct { | |
#define CBUFFER_END(name) } name; }; | |
CBUFFER_BEGIN(VertexMaterial) | |
float3 Diffuse; | |
float Opacity; | |
float3 Ambient; | |
float3 Emissive; | |
CBUFFER_END(VertexMaterial) | |
CBUFFER_BEGIN(EngineLighting) | |
float4 DirectionX; | |
float4 DirectionY; | |
float4 DirectionZ; | |
float3 Diffuse[4]; | |
float3 Ambient; | |
CBUFFER_END(EngineLighting) | |
CBUFFER_BEGIN(EnginePerDraw) | |
float4x4 matrixW; | |
float4x4 matrixWIT; | |
CBUFFER_END(EnginePerDraw) | |
CBUFFER_BEGIN(EnginePerDrawMapper) | |
float4x4 matrixT0; | |
float4x4 matrixT1; | |
float4 BumpMatrix; | |
CBUFFER_END(EnginePerDrawMapper) | |
CBUFFER_BEGIN_SHARED(EnginePerCamera) | |
float4x4 matrixVP; | |
float4x4 matrixV; | |
float3 WorldCameraPosition; | |
CBUFFER_END(EnginePerCamera) | |
CBUFFER_BEGIN_SHARED(DistanceFog) | |
float4 Constants; | |
float3 Color; | |
float3 SunDirection; | |
float3 SunColor; | |
CBUFFER_END(DistanceFog); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void HandleUVSource(StringClass& params, int uv_source, const StringClass& stage_name) | |
{ | |
if (uv_source & UV_SOURCE_PROJECTED) | |
params += stage_name + "_UV_SOURCE_PROJECTED;"; | |
switch (uv_source & ~UV_SOURCE_PROJECTED) | |
{ | |
case 0: params += stage_name + "_UV_SOURCE0;"; break; | |
case 1: params += stage_name + "_UV_SOURCE1;"; break; | |
case 2: params += stage_name + "_UV_SOURCE2;"; break; | |
case 3: params += stage_name + "_UV_SOURCE3;"; break; | |
case UV_SOURCE_VIEWNORMAL: params += stage_name + "_UV_SOURCE_VIEWNORMAL;"; break; | |
case UV_SOURCE_VIEWPOSITION: params += stage_name + "_UV_SOURCE_VIEWPOSITION;"; break; | |
case UV_SOURCE_VIEWREFLECT: params += stage_name + "_UV_SOURCE_VIEWREFLECT;"; break; | |
case UV_SOURCE_WORLDNORMAL: params += stage_name + "_UV_SOURCE_WORLDNORMAL;"; break; | |
case UV_SOURCE_WORLDREFLECT: params += stage_name + "_UV_SOURCE_WORLDREFLECT;"; break; | |
case UV_SOURCE_CLIPPOSITION: params += stage_name + "_UV_SOURCE_CLIPPOSITION;"; break; | |
default: assert("Unsupported" && false); break; | |
} | |
} | |
StringClass MaterialGroup::BuildShaderParamString() const | |
{ | |
StringClass params("LIGHTING;", true); | |
if (material->Use_Vertex_Colors()) params += "VERTEX_COLOR;"; | |
if (textures[0]) params += "MAIN_TEXTURE;"; | |
if (material->Peek_Mapper(0) || material->Peek_Mapper(1)) | |
{ | |
params += "TEXTURE_MAPPER;"; | |
} | |
HandleUVSource(params, material->Get_UV_Source(0), "MAIN"); | |
HandleUVSource(params, material->Get_UV_Source(1), "DETAIL"); | |
switch (blend_state.Get_Primary_Gradient()) | |
{ | |
case ShaderClass::GRADIENT_DISABLE: params += "GRADIENT_DISABLE;"; break; | |
case ShaderClass::GRADIENT_MODULATE: params += "GRADIENT_MODULATE;"; break; | |
case ShaderClass::GRADIENT_ADD: params += "GRADIENT_ADD;"; break; | |
case ShaderClass::GRADIENT_BUMPENVMAP: params += "GRADIENT_BUMPENVMAP;"; break; | |
case ShaderClass::GRADIENT_BUMPENVMAPLUMINANCE: params += "GRADIENT_BUMPENVMAPLUMINANCE;"; break; | |
case ShaderClass::GRADIENT_DOTPRODUCT3: params += "GRADIENT_DOTPRODUCT3;"; break; | |
} | |
auto detail_color = blend_state.Get_Post_Detail_Color_Func(); | |
auto detail_alpha = blend_state.Get_Post_Detail_Alpha_Func(); | |
if (textures[1]) params += "DETAIL_TEXTURE;"; | |
else | |
{ | |
detail_color = ShaderClass::DETAILCOLOR_DISABLE; | |
detail_alpha = ShaderClass::DETAILALPHA_DISABLE; | |
} | |
switch (detail_color) | |
{ | |
case ShaderClass::DETAILCOLOR_DISABLE: params += "DETAILCOLOR_DISABLE;"; break; | |
case ShaderClass::DETAILCOLOR_DETAIL: params += "DETAILCOLOR_DETAIL;"; break; | |
case ShaderClass::DETAILCOLOR_SCALE: params += "DETAILCOLOR_SCALE;"; break; | |
case ShaderClass::DETAILCOLOR_INVSCALE: params += "DETAILCOLOR_INVSCALE;"; break; | |
case ShaderClass::DETAILCOLOR_ADD: params += "DETAILCOLOR_ADD;"; break; | |
case ShaderClass::DETAILCOLOR_SUB: params += "DETAILCOLOR_SUB;"; break; | |
case ShaderClass::DETAILCOLOR_SUBR: params += "DETAILCOLOR_SUBR;"; break; | |
case ShaderClass::DETAILCOLOR_BLEND: params += "DETAILCOLOR_BLEND;"; break; | |
case ShaderClass::DETAILCOLOR_DETAILBLEND: params += "DETAILCOLOR_DETAILBLEND;"; break; | |
} | |
switch (detail_alpha) | |
{ | |
case ShaderClass::DETAILALPHA_DISABLE: params += "DETAILALPHA_DISABLE;"; break; | |
case ShaderClass::DETAILALPHA_DETAIL: params += "DETAILALPHA_DETAIL;"; break; | |
case ShaderClass::DETAILALPHA_SCALE: params += "DETAILALPHA_SCALE;"; break; | |
case ShaderClass::DETAILALPHA_INVSCALE: params += "DETAILALPHA_INVSCALE;"; break; | |
} | |
if (blend_state.Get_Alpha_Test() == ShaderClass::ALPHATEST_ENABLE) | |
params += "ALPHA_TEST;"; | |
switch (blend_state.Get_Fog_Func()) | |
{ | |
case ShaderClass::FOG_ENABLE: params += "FOG;"; break; | |
case ShaderClass::FOG_SCALE_FRAGMENT: params += "FOG;FOG_SCALE_FRAGMENT;"; break; | |
case ShaderClass::FOG_WHITE: params += "FOG;FOG_WHITE;"; break; | |
} | |
return params; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "engine.fxh" | |
#material vertex vs_main | |
#material pixel ps_main | |
#if MAIN_TEXTURE | |
Texture2D MainTexture; | |
SamplerState MainTextureSampler; | |
#endif | |
#if DETAIL_TEXTURE | |
Texture2D DetailTexture; | |
SamplerState DetailTextureSampler; | |
#endif | |
#if NORMAL_MAP | |
Texture2D NormalMap; | |
SamplerState NormalMapSampler; | |
#endif | |
struct vertexInput | |
{ | |
float3 Position : POSITION; | |
#if LIGHTING | |
float3 Normal : NORMAL; | |
#endif | |
#if NORMAL_MAP | |
float3 Tangent : TANGENT; | |
float3 Binormal : BINORMAL; | |
#endif | |
#if VERTEX_COLOR | |
float4 Color : COLOR0; | |
#endif | |
#if MAIN_UV_SOURCE0 || DETAIL_UV_SOURCE0 | |
float2 TexCoord0 : TEXCOORD0; | |
#endif | |
#if MAIN_UV_SOURCE1 || DETAIL_UV_SOURCE1 | |
float2 TexCoord1 : TEXCOORD1; | |
#endif | |
#if MAIN_UV_SOURCE2 || DETAIL_UV_SOURCE2 | |
float2 TexCoord2 : TEXCOORD2; | |
#endif | |
#if MAIN_UV_SOURCE3 || DETAIL_UV_SOURCE3 | |
float2 TexCoord3 : TEXCOORD3; | |
#endif | |
#if MAIN_UV_SOURCE4 || DETAIL_UV_SOURCE4 | |
float2 TexCoord4 : TEXCOORD4; | |
#endif | |
}; | |
struct vertexOutput | |
{ | |
float4 Position : SV_POSITION; | |
#if VERTEX_COLOR | |
float4 Color : COLOR0; | |
#endif | |
#if MAIN_TEXTURE | |
float3 TexCoord0 : TEXCOORD0; | |
#endif | |
#if DETAIL_TEXTURE | |
float3 TexCoord1 : TEXCOORD1; | |
#endif | |
float4 WorldPos : TEXCOORD2; | |
#if LIGHTING | |
#if NORMAL_MAP | |
float3 Normal : TEXCOORD3; | |
float3 Tangent : TEXCOORD4; | |
float3 Binormal : TEXCOORD5; | |
#else | |
float3 Normal : TEXCOORD3; | |
#endif | |
#endif | |
#if LIGHTING || FOG | |
float3 View : TEXCOORD6; | |
#endif | |
#if FOG | |
float3 Fog : TEXCOORD7; | |
#endif | |
}; | |
#define pixelInput vertexOutput | |
vertexOutput vs_main(vertexInput IN) | |
{ | |
vertexOutput OUT; | |
float4 world_position = mul(float4(IN.Position, 1), EnginePerDraw.matrixW); | |
float4 clip_position = mul(world_position, EnginePerCamera.matrixVP); | |
OUT.Position = clip_position; | |
OUT.WorldPos = world_position; | |
#if LIGHTING | |
float3 world_normal = mul(float4(IN.Normal, 0), EnginePerDraw.matrixWIT).xyz; | |
OUT.Normal = world_normal; | |
#if NORMAL_MAP | |
float3 world_tangent = mul(float4(IN.Tangent, 0), EnginePerDraw.matrixWIT).xyz; | |
OUT.Tangent = world_tangent; | |
float3 world_binormal = mul(float4(IN.Binormal, 0), EnginePerDraw.matrixWIT).xyz; | |
OUT.Binormal = world_binormal; | |
#endif | |
#endif | |
#if VERTEX_COLOR | |
OUT.Color = float4(pow(abs(IN.Color.rgb), 2.2f), IN.Color.a); | |
#endif | |
#if MAIN_UV_SOURCE_WORLDREFLECT || DETAIL_UV_SOURCE_WORLDREFLECT || MAIN_UV_SOURCE_VIEWREFLECT || DETAIL_UV_SOURCE_VIEWREFLECT | |
float3 incident = world_position.xyz - EnginePerCamera.WorldCameraPosition; | |
#endif | |
float4 texcoord; | |
#if MAIN_TEXTURE | |
#if MAIN_UV_SOURCE0 | |
texcoord = float4(IN.TexCoord0.xy, 1, 0); | |
#elif MAIN_UV_SOURCE1 | |
texcoord = float4(IN.TexCoord1.xy, 1, 0); | |
#elif MAIN_UV_SOURCE2 | |
texcoord = float4(IN.TexCoord2.xy, 1, 0); | |
#elif MAIN_UV_SOURCE3 | |
texcoord = float4(IN.TexCoord3.xy, 1, 0); | |
#elif MAIN_UV_SOURCE_WORLDNORMAL | |
texcoord = float4(world_normal, 0); | |
#elif MAIN_UV_SOURCE_WORLDREFLECT | |
texcoord = normalize(float4(reflect(incident, world_normal), 0)); | |
texcoord.w = 1; | |
#elif MAIN_UV_SOURCE_VIEWNORMAL | |
texcoord = mul(float4(world_normal, 0), EnginePerCamera.matrixV); | |
texcoord.w = 1; | |
#elif MAIN_UV_SOURCE_VIEWPOSITION | |
texcoord = mul(float4(world_position.xyz, 1), EnginePerCamera.matrixV); | |
texcoord.w = 1; | |
#elif MAIN_UV_SOURCE_VIEWREFLECT | |
texcoord = normalize(mul(float4(reflect(incident, world_normal), 0), EnginePerCamera.matrixV)); | |
texcoord.w = 1; | |
#elif MAIN_UV_SOURCE_CLIPPOSITION | |
texcoord = clip_position; | |
#endif | |
#if TEXTURE_MAPPER | |
texcoord = mul(texcoord, EnginePerDrawMapper.matrixT0); | |
#endif | |
#if MAIN_UV_SOURCE_PROJECTED | |
OUT.TexCoord0 = float3(texcoord.xy, texcoord.w); | |
#else | |
OUT.TexCoord0 = float3(texcoord.xy, 1); | |
#endif | |
#endif | |
#if DETAIL_TEXTURE | |
#if DETAIL_UV_SOURCE0 | |
texcoord = float4(IN.TexCoord0.xy, 1, 0); | |
#elif DETAIL_UV_SOURCE1 | |
texcoord = float4(IN.TexCoord1.xy, 1, 0); | |
#elif DETAIL_UV_SOURCE2 | |
texcoord = float4(IN.TexCoord2.xy, 1, 0); | |
#elif DETAIL_UV_SOURCE3 | |
texcoord = float4(IN.TexCoord3.xy, 1, 0); | |
#elif DETAIL_UV_SOURCE_WORLDNORMAL | |
texcoord = float4(world_normal, 0); | |
#elif DETAIL_UV_SOURCE_WORLDREFLECT | |
texcoord = normalize(float4(reflect(incident, world_normal), 0)); | |
texcoord.w = 1; | |
#elif DETAIL_UV_SOURCE_VIEWNORMAL | |
texcoord = mul(float4(world_normal, 0), EnginePerCamera.matrixV); | |
texcoord.w = 1; | |
#elif DETAIL_UV_SOURCE_VIEWPOSITION | |
texcoord = mul(float4(world_position.xyz, 1), EnginePerCamera.matrixV); | |
texcoord.w = 1; | |
#elif DETAIL_UV_SOURCE_VIEWREFLECT | |
texcoord = normalize(mul(float4(reflect(incident, world_normal), 0), EnginePerCamera.matrixV)); | |
texcoord.w = 1; | |
#elif DETAIL_UV_SOURCE_CLIPPOSITION | |
texcoord = clip_position; | |
#endif | |
#if TEXTURE_MAPPER | |
texcoord = mul(texcoord, EnginePerDrawMapper.matrixT1); | |
#endif | |
#if DETAIL_UV_SOURCE_PROJECTED | |
OUT.TexCoord1 = float3(texcoord.xy, texcoord.w); | |
#else | |
OUT.TexCoord1 = float3(texcoord.xy, 1); | |
#endif | |
#endif | |
#if LIGHTING || FOG | |
OUT.View = normalize(EnginePerCamera.WorldCameraPosition - world_position.xyz); | |
#endif | |
#if FOG | |
OUT.Fog = clip_position.xyz; | |
#endif | |
return OUT; | |
}; | |
float4 ps_main(vertexOutput IN): SV_TARGET | |
{ | |
float4 color_out = float4(VertexMaterial.Emissive, VertexMaterial.Opacity); | |
float3 material_diffuse, material_ambient; | |
float4 view_pos = mul(float4(IN.WorldPos.xyz, 1), EnginePerCamera.matrixV); | |
#if VERTEX_COLOR | |
color_out *= IN.Color; | |
material_diffuse = VertexMaterial.Diffuse.rgb * IN.Color.rgb; | |
material_ambient = VertexMaterial.Ambient.rgb * IN.Color.rgb; | |
#else | |
material_diffuse = VertexMaterial.Diffuse.rgb; | |
material_ambient = VertexMaterial.Ambient.rgb; | |
#endif | |
#if LIGHTMAP | |
float2 light_uv = IN.LightmapUV.xy; | |
float4 lightmap = tex2D(LightmapTexture, light_uv); | |
#endif | |
#if LIGHTING | |
#if NORMAL_MAP | |
float3x3 tbn; | |
tbn[0] = normalize(IN.Tangent); | |
tbn[1] = normalize(IN.Binormal); | |
tbn[2] = normalize(IN.Normal); | |
float3 normal_map = NormalMap.Sample(NormalMapSampler, IN.TexCoord0.xy).rgb * 2 - 1; | |
float3 N = normalize(mul(normal_map, tbn)); | |
#else | |
float3 N = normalize(IN.Normal); | |
#endif | |
float4 lambert; | |
lambert = EngineLighting.DirectionX * N.x; | |
lambert += EngineLighting.DirectionY * N.y; | |
lambert += EngineLighting.DirectionZ * N.z; | |
lambert = max(0, lambert); | |
float3 diffuse = EngineLighting.Diffuse[0].rgb * lambert.x; | |
diffuse += EngineLighting.Diffuse[1].rgb * lambert.y; | |
diffuse += EngineLighting.Diffuse[2].rgb * lambert.z; | |
diffuse += EngineLighting.Diffuse[3].rgb * lambert.w; | |
#if LIGHTMAP | |
color_out.rgb += lightmap.rgb; | |
#else | |
color_out.rgb += EngineLighting.Ambient.rgb * material_ambient; | |
#endif | |
color_out.rgb += diffuse * material_diffuse; | |
#else | |
color_out.rgb = material_diffuse.rgb; | |
#endif | |
#if MAIN_TEXTURE | |
#if MAIN_UV_SOURCE_PROJECTED | |
float4 main_texture = MainTexture.Sample(MainTextureSampler, IN.TexCoord0.xy / IN.TexCoord0.z); | |
#else | |
float4 main_texture = MainTexture.Sample(MainTextureSampler, IN.TexCoord0.xy); | |
#endif | |
#if GRADIENT_DISABLE | |
color_out = main_texture; | |
#elif GRADIENT_BUMPENVMAP | |
IN.TexCoord1.x += main_texture.r * EnginePerDrawMapper.BumpMatrix.x + main_texture.g * EnginePerDrawMapper.BumpMatrix.z; | |
IN.TexCoord1.y += main_texture.r * EnginePerDrawMapper.BumpMatrix.y + main_texture.g * EnginePerDrawMapper.BumpMatrix.w; | |
#elif GRADIENT_MODULATE | |
color_out *= main_texture; | |
#elif GRADIENT_ADD | |
color_out.rgb += main_texture.rgb; | |
color_out.a = main_texture.a; | |
#endif | |
#endif | |
#if DETAIL_TEXTURE | |
#if DETAIL_UV_SOURCE_PROJECTED | |
float4 detail_texture = DetailTexture.Sample(DetailTextureSampler, IN.TexCoord1.xy / IN.TexCoord1.z); | |
#else | |
float4 detail_texture = DetailTexture.Sample(DetailTextureSampler, IN.TexCoord1.xy); | |
#endif | |
#if DETAILCOLOR_DETAIL | |
color_out.rgb = detail_texture.rgb; | |
#elif DETAILCOLOR_SCALE | |
color_out.rgb *= detail_texture.rgb; | |
#elif DETAILCOLOR_INVSCALE | |
color_out.rgb = detail_texture.rgb + color_out.rgb * (1 - detail_texture.rgb); | |
#elif DETAILCOLOR_ADD | |
color_out.rgb += detail_texture.rgb; | |
#elif DETAILCOLOR_SUB | |
color_out.rgb = detail_texture.rgb - color_out.rgb; | |
#elif DETAILCOLOR_SUBR | |
color_out.rgb -= detail_texture.rgb; | |
#elif DETAILCOLOR_BLEND | |
color_out.rgb = lerp(color_out.rgb, detail_texture.rgb, detail_texture.a); | |
#elif DETAILCOLOR_DETAILBLEND | |
color_out.rgb = lerp(color_out.rgb, detail_texture.rgb, color_out.a); | |
#endif | |
#if DETAILALPHA_DETAIL | |
color_out.a = detail_texture.a; | |
#elif DETAILALPHA_SCALE | |
color_out.a *= detail_texture.a; | |
#elif DETAILALPHA_INVSCALE | |
color_out.a = detail_texture.a + color_out.a * (1 - detail_texture.a); | |
#endif | |
#endif | |
#if FOG | |
float3 fog_color; | |
#if FOG_SCALE_FRAGMENT | |
fog_color = 0; | |
#elif FOG_WHITE | |
fog_color = 1; | |
#else | |
float sun_amount = max(dot(IN.View, normalize(DistanceFog.SunDirection)), 0); | |
float3 sun_color = lerp(DistanceFog.Color, DistanceFog.SunColor, 0.25f); | |
fog_color = lerp(DistanceFog.Color, sun_color, pow(sun_amount, 16)); | |
#endif | |
float fog = saturate(length(IN.Fog) * DistanceFog.Constants.x + DistanceFog.Constants.y); | |
color_out.rgb = lerp(fog_color, color_out.rgb, fog); | |
#endif | |
#if ALPHA_TEST | |
if (color_out.a < 0.375) | |
discard; | |
#endif | |
return color_out; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment