// 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 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; }