dxlib 0.5.1

dxlib dll for Rust
Documentation
// Pixel Shader
// https://github.com/darknesswind/DxLib/blob/master/DxLibMake/Windows/DxShader_PS_D3D11.h
// https://github.com/darknesswind/DxLib/blob/master/DxLibMake/Shader/Windows/Direct3D11/PixelShader.h

struct PS_INPUT { // from Vertex Shader
  float2 texCoords0 : TEXCOORD0; // through
  float4 dif : COLOR0; // through
  float4 spc : COLOR1; // through
  float3 norm : NORMAL0; // through
  float3 pos : POSITION0; // through
  float4 ppos : SV_POSITION; // pos in projection
};

struct PS_OUTPUT {
  float4 color0 : SV_TARGET0; // screen pixel color
};

#include <shader_common.hlsl>

struct DX_D3D11_PS_CONST_BUFFER_BASE {
  float4 FactorColor; // alpha etc
  float MulAlphaColor; // 0.0f: ignore 1.0f: mul alpha
  float AlphaTestRef; // alpha test compare with it
  float2 Padding1;
  int AlphaTestCmpMode; // alpha test mode (DX_CMP_NEVER etc)
  int NoLightAngleAttenuation; // 0: attenuation, 1: no attenuation
  int UseHalfLambert; // half lambert mode (20240324 later)
  int Padding2;
  float4 IgnoreTextureColor; // color when ignore texture
  float4 DrawAddColor; // add color
};

struct DX_D3D11_PS_CONST_SHADOWMAP {
  float AdjustDepth;
  float GradationParam;
  float Enable_Light0;
  float Enable_Light1;
  float Enable_Light2;
  float3 Padding;
};

struct DX_D3D11_PS_CONST_BUFFER_SHADOWMAP {
  DX_D3D11_PS_CONST_SHADOWMAP Data[3];
};

cbuffer cbD3D11_CONST_BUFFER_COMMON : register(b0) {
  DX_D3D11_CONST_BUFFER_COMMON g_Common;
};

cbuffer cbD3D11_CONST_BUFFER_PS_BASE : register(b1) {
  DX_D3D11_PS_CONST_BUFFER_BASE g_Base;
};

cbuffer cbD3D11_CONST_BUFFER_PS_SHADOWMAP : register(b2) {
  DX_D3D11_PS_CONST_BUFFER_SHADOWMAP g_ShadowMap;
};

// DX_D3D11_PS_CONST_FILTER_SIZE 1280
// cbuffer cbD3D11_CONST_BUFFER_PS_FILTER : register(b3) {
//   DX_D3D11_PS_CONST_BUFFER_FILTER g_Filter;
// };
cbuffer cbD3D11_CONST_BUFFER_PS_FILTER : register(b3) {
  float4 g_Filter[1280 / 4 / 4]; // length will be changed (dummy)
};

SamplerState g_DiffuseMapSampler : register(s0);
Texture2D g_DiffuseMapTexture : register(t0);

cbuffer cb_Test : register(b4) {
float4 g_Test = float4(2.2f, 4.4f, 6.6f, 8.8f);
float4 g_Arr[4] = {
  float4(0.2f, 0.3f, 0.4f, 0.5f),
  float4(0.4f, 0.5f, 0.6f, 0.7f),
  float4(0.6f, 0.7f, 0.8f, 0.9f),
  float4(0.8f, 0.9f, 1.0f, 1.1f)};
};

float4 g_Reg0 : register(c0);
float4 g_Reg1 : register(c1);

cbuffer cb_5 : register(b5) {
  float4 cb_cam_pos4;
};

cbuffer cb_6 : register(b6) {
  float4 cb_a;
  float4 cb_b;
};

cbuffer cb_7 : register(b7) {
  float4 cb_c;
};

struct CamLight {
  float4 cam_pos4;
  float4 cam_lat4;
  float4 r[2]; // light ratio: (r[0].xyzw and r[1].xy), camera angle: r[1].w
};

cbuffer cb_CamLight : register(b8) { // max 14 slots
  CamLight g_CL;
};

struct LIGHT {
  float4 test;
  float4 amb;
  float4 spc;
  float a;
  float3 padding;
};

LIGHT proc_light(PS_INPUT psi, int lh)
{
  float3 n = normalize(psi.norm.xyz);
  float3 look_vec = g_CL.cam_lat4.xyz - g_CL.cam_pos4.xyz;
//  float3 look_vec = float3(0.0f, 0.0f, 0.0f); // test

  DX_D3D11_CONST_LIGHT light = g_Common.Light[lh];
  float4 light_amb = light.Ambient;
  float4 light_pos4;
  light_pos4.xyz = light.Position;
  light_pos4.w = 1.0f;
  float4 light_vec4;
  light_vec4.xyz = light.Direction;
  light_vec4.w = light.RangePow2;

  float4 test = light_vec4;
  test.xyz = light.Specular;
  test.w = 1.0f;

  float3 light_dir = normalize(light_vec4.xyz);
//  float3 light_dir = normalize(float3(1.0f, 1.0f, 1.0f)); // test

  float3 r = -normalize(light_dir);
  float3 v = -normalize(look_vec);
  float2 p = float2(
    max(0.0f, dot(r, n)), // not use camera angle
    dot(v, normalize(dot(r, n) * n))); // both rev. (- * - = +) hide by culling
//  max(0.0f, dot(v, n)) * max(0.0f, dot(r, n))
  float q = g_CL.r[1].w;
  float a = dot(float2(1.0f - q, q), p);
  float4 spc = psi.spc * pow(a, light_vec4.w);
//  float4 spc = psi.spc * pow(a, 1.0f);
  LIGHT l = {test, light_amb, spc, a, float3(0.0f, 0.0f, 0.0f)};
  return l;
}

LIGHT m_s(CamLight e, LIGHT l[6], int i) // mul struct r LIGHT
{
  float r[8]; // not use loop in HLSL
  r[0] = e.r[0].x;
  r[1] = e.r[0].y;
  r[2] = e.r[0].z;
  r[3] = e.r[0].w;
  r[4] = e.r[1].x;
  r[5] = e.r[1].y;
  r[6] = e.r[1].z;
  r[7] = e.r[1].w;
  LIGHT o = {
    float4(0.0f, 0.0f, 0.0f, 0.0f),
    max(0.0f, r[i] * l[i].amb),
    max(0.0f, r[i] * l[i].spc),
    max(0.0f, r[i] * l[i].a),
    float3(0.0f, 0.0f, 0.0f)};
  return o;
}

LIGHT a_s(LIGHT a, LIGHT b) // add struct LIGHT LIGHT
{
  LIGHT o = {
    a.test + b.test,
    a.amb + b.amb,
    a.spc + b.spc,
    a.a + b.a,
    a.padding + b.padding};
  return o;
}

LIGHT c_s(float c, LIGHT a) // clip struct s LIGHT
{
  LIGHT o = {
    min(c, a.test),
    min(c, a.amb),
    min(c, a.spc),
    min(c, a.a),
    min(c, a.padding)};
  return o;
}

LIGHT dot_s(float c, CamLight e, LIGHT l[6]) // dot and clip struct c r LIGHT
{
  return c_s(c, a_s(a_s(a_s(a_s(a_s(
    m_s(e, l, 0), m_s(e, l, 1)), m_s(e, l, 2)),
    m_s(e, l, 3)), m_s(e, l, 4)), m_s(e, l, 5)));
}

PS_OUTPUT main(PS_INPUT psi)
{
  PS_OUTPUT pso;

  LIGHT l[6]; // not use loop in HLSL
  l[0] = proc_light(psi, 0);
  l[1] = proc_light(psi, 1);
  l[2] = proc_light(psi, 2);
  l[3] = proc_light(psi, 3);
  l[4] = proc_light(psi, 4);
  l[5] = proc_light(psi, 5);

  LIGHT o = dot_s(1.0f, g_CL, l);

  // texture diffused color
  float4 dc = g_DiffuseMapTexture.Sample(g_DiffuseMapSampler, psi.texCoords0);
//  pso.color0 = dc * psi.dif; // not use light spc
//  pso.color0 = dc * psi.dif * l[0].a + l[0].spc + l[0].amb; // only light 0
//  pso.color0 = dc * psi.dif * l[1].a + l[1].spc + l[1].amb; // only light 1
//  pso.color0 = (dc * psi.dif * l[1].a + l[1].spc + l[1].amb)
//    * l[0].a + l[0].spc + l[0].amb;
  pso.color0 = dc * psi.dif * o.a + o.spc + o.amb;
//  pso.color0 = l[0].test; // test by light 0 direction or specular
//  pso.color0 = l[1].test; // test by light 1 direction or specular
//  pso.color0 = g_CL.cam_pos4; // test by constant buffer
//  pso.color0 = float4(r[0], r[1], r[2], r[3]); // test by constant buffer
  return pso;
}