diff --git a/Source/Core/VideoCommon/ConstantManager.h b/Source/Core/VideoCommon/ConstantManager.h index 3be4793d86..de1f346ed3 100644 --- a/Source/Core/VideoCommon/ConstantManager.h +++ b/Source/Core/VideoCommon/ConstantManager.h @@ -22,7 +22,8 @@ struct PixelShaderConstants float4 fog[2]; // For pixel lighting - float4 plights[40]; + int4 plight_colors[8]; + float4 plights[32]; float4 pmaterials[4]; }; @@ -31,7 +32,8 @@ struct VertexShaderConstants float4 posnormalmatrix[6]; float4 projection[4]; float4 materials[4]; - float4 lights[40]; + int4 light_colors[8]; // 8 lights + float4 lights[32]; // 8 lights * 4 parameters float4 texmatrices[24]; float4 transformmatrices[64]; float4 normalmatrices[32]; diff --git a/Source/Core/VideoCommon/LightingShaderGen.h b/Source/Core/VideoCommon/LightingShaderGen.h index 7afcff2ef7..485d020b2f 100644 --- a/Source/Core/VideoCommon/LightingShaderGen.h +++ b/Source/Core/VideoCommon/LightingShaderGen.h @@ -9,19 +9,19 @@ #include "VideoCommon/XFMemory.h" -#define LIGHT_COL "%s[5*%d].%s" -#define LIGHT_COL_PARAMS(lightsName, index, swizzle) (lightsName), (index), (swizzle) +#define LIGHT_COL "(float4(%s[%d]).%s / 255.0)" +#define LIGHT_COL_PARAMS(lightsColName, index, swizzle) (lightsColName), (index), (swizzle) -#define LIGHT_COSATT "%s[5*%d+1]" +#define LIGHT_COSATT "%s[4*%d]" #define LIGHT_COSATT_PARAMS(lightsName, index) (lightsName), (index) -#define LIGHT_DISTATT "%s[5*%d+2]" +#define LIGHT_DISTATT "%s[4*%d+1]" #define LIGHT_DISTATT_PARAMS(lightsName, index) (lightsName), (index) -#define LIGHT_POS "%s[5*%d+3]" +#define LIGHT_POS "%s[4*%d+2]" #define LIGHT_POS_PARAMS(lightsName, index) (lightsName), (index) -#define LIGHT_DIR "%s[5*%d+4]" +#define LIGHT_DIR "%s[4*%d+3]" #define LIGHT_DIR_PARAMS(lightsName, index) (lightsName), (index) /** @@ -39,7 +39,7 @@ struct LightingUidData template -static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsName, int coloralpha) +static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsColName, const char* lightsName, int coloralpha) { const LitChannel& chan = (litchan_index > 1) ? xfregs.alpha[litchan_index-2] : xfregs.color[litchan_index]; const char* swizzle = "xyzw"; @@ -56,13 +56,13 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, switch (chan.diffusefunc) { case LIGHTDIF_NONE: - object.Write("lacc.%s += " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsName, index, swizzle)); + object.Write("lacc.%s += " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsColName, index, swizzle)); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(lightsName, index)); object.Write("lacc.%s += %sdot(ldir, _norm0)) * " LIGHT_COL";\n", - swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(", LIGHT_COL_PARAMS(lightsName, index, swizzle)); + swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(", LIGHT_COL_PARAMS(lightsColName, index, swizzle)); break; default: _assert_(0); } @@ -94,14 +94,14 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, switch (chan.diffusefunc) { case LIGHTDIF_NONE: - object.Write("lacc.%s += attn * " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsName, index, swizzle)); + object.Write("lacc.%s += attn * " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsColName, index, swizzle)); break; case LIGHTDIF_SIGN: case LIGHTDIF_CLAMP: object.Write("lacc.%s += attn * %sdot(ldir, _norm0)) * " LIGHT_COL";\n", swizzle, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(", - LIGHT_COL_PARAMS(lightsName, index, swizzle)); + LIGHT_COL_PARAMS(lightsColName, index, swizzle)); break; default: _assert_(0); } @@ -115,7 +115,7 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, // inColorName is color in vs and colors_ in ps // dest is o.colors_ in vs and colors_ in ps template -static void GenerateLightingShader(T& object, LightingUidData& uid_data, int components, const char* materialsName, const char* lightsName, const char* inColorName, const char* dest) +static void GenerateLightingShader(T& object, LightingUidData& uid_data, int components, const char* materialsName, const char* lightsColName, const char* lightsName, const char* inColorName, const char* dest) { for (unsigned int j = 0; j < xfregs.numChan.numColorChans; j++) { @@ -226,7 +226,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com { if (mask & (1<(object, uid_data, i, j, lightsName, 3); + GenerateLightShader(object, uid_data, i, j, lightsColName, lightsName, 3); } } } @@ -236,9 +236,9 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com for (int i = 0; i < 8; ++i) { if (!(mask&(1<(object, uid_data, i, j, lightsName, 1); + GenerateLightShader(object, uid_data, i, j, lightsColName, lightsName, 1); if (!(mask&(1<(object, uid_data, i, j+2, lightsName, 2); + GenerateLightShader(object, uid_data, i, j+2, lightsColName, lightsName, 2); } } else if (color.enablelighting || alpha.enablelighting) @@ -252,7 +252,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com for (int i = 0; i < 8; ++i) { if (workingchannel.GetFullLightMask() & (1<(object, uid_data, i, lit_index, lightsName, coloralpha); + GenerateLightShader(object, uid_data, i, lit_index, lightsColName, lightsName, coloralpha); } } object.Write("%s%d = mat * clamp(lacc, 0.0, 1.0);\n", dest, j); diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 50f3a8e9c6..915cfc2176 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -294,7 +294,8 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T DeclareUniform(out, ApiType, C_FOG, "float4", I_FOG"[2]"); // For pixel lighting - TODO: Should only be defined when per pixel lighting is enabled! - DeclareUniform(out, ApiType, C_PLIGHTS, "float4", I_PLIGHTS"[40]"); + DeclareUniform(out, ApiType, C_PLIGHT_COLORS, "int4", I_PLIGHT_COLORS"[8]"); + DeclareUniform(out, ApiType, C_PLIGHTS, "float4", I_PLIGHTS"[32]"); DeclareUniform(out, ApiType, C_PMATERIALS, "float4", I_PMATERIALS"[4]"); if (ApiType == API_OPENGL) @@ -416,10 +417,11 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T "\tfloat3 ldir, h;\n" "\tfloat dist, dist2, attn;\n"); - out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+39); // TODO: Can be optimized further + out.SetConstantsUsed(C_PLIGHT_COLORS, C_PLIGHT_COLORS+7); // TODO: Can be optimized further + out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+31); // TODO: Can be optimized further out.SetConstantsUsed(C_PMATERIALS, C_PMATERIALS+3); uid_data.components = components; - GenerateLightingShader(out, uid_data.lighting, components, I_PMATERIALS, I_PLIGHTS, "colors_", "colors_"); + GenerateLightingShader(out, uid_data.lighting, components, I_PMATERIALS, I_PLIGHT_COLORS, I_PLIGHTS, "colors_", "colors_"); } out.Write("\tclipPos = float4(rawpos.x, rawpos.y, clipPos.z, clipPos.w);\n"); diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h index ad9bbecddb..972101cd1c 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.h +++ b/Source/Core/VideoCommon/PixelShaderGen.h @@ -9,17 +9,18 @@ #include "VideoCommon/ShaderGenCommon.h" #include "VideoCommon/VideoCommon.h" -#define I_COLORS "color" -#define I_KCOLORS "k" -#define I_ALPHA "alphaRef" -#define I_TEXDIMS "texdim" -#define I_ZBIAS "czbias" -#define I_INDTEXSCALE "cindscale" -#define I_INDTEXMTX "cindmtx" -#define I_FOGCOLOR "cfogcolor" -#define I_FOG "cfog" -#define I_PLIGHTS "cPLights" -#define I_PMATERIALS "cPmtrl" +#define I_COLORS "color" +#define I_KCOLORS "k" +#define I_ALPHA "alphaRef" +#define I_TEXDIMS "texdim" +#define I_ZBIAS "czbias" +#define I_INDTEXSCALE "cindscale" +#define I_INDTEXMTX "cindmtx" +#define I_FOGCOLOR "cfogcolor" +#define I_FOG "cfog" +#define I_PLIGHT_COLORS "cPLightColors" +#define I_PLIGHTS "cPLights" +#define I_PMATERIALS "cPmtrl" // TODO: get rid of them as they aren't used #define C_COLORMATRIX 0 // 0 @@ -33,8 +34,9 @@ #define C_FOGCOLOR (C_INDTEXMTX + 6) //27 #define C_FOG (C_FOGCOLOR + 1) //28 -#define C_PLIGHTS (C_FOG + 3) -#define C_PMATERIALS (C_PLIGHTS + 40) +#define C_PLIGHT_COLORS (C_FOG + 2) +#define C_PLIGHTS (C_PLIGHT_COLORS + 8) +#define C_PMATERIALS (C_PLIGHTS + 32) #define C_PENVCONST_END (C_PMATERIALS + 4) // Different ways to achieve rendering with destination alpha diff --git a/Source/Core/VideoCommon/PixelShaderManager.cpp b/Source/Core/VideoCommon/PixelShaderManager.cpp index b0b1ce7037..b9418b4afd 100644 --- a/Source/Core/VideoCommon/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/PixelShaderManager.cpp @@ -104,6 +104,7 @@ void PixelShaderManager::SetConstants() { if (nLightsChanged[0] >= 0) { + // TODO: Outdated comment // lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats int istart = nLightsChanged[0] / 0x10; int iend = (nLightsChanged[1] + 15) / 0x10; @@ -112,10 +113,10 @@ void PixelShaderManager::SetConstants() for (int i = istart; i < iend; ++i) { u32 color = *(const u32*)(xfmemptr + 3); - constants.plights[5*i][0] = ((color >> 24) & 0xFF) / 255.0f; - constants.plights[5*i][1] = ((color >> 16) & 0xFF) / 255.0f; - constants.plights[5*i][2] = ((color >> 8) & 0xFF) / 255.0f; - constants.plights[5*i][3] = ((color) & 0xFF) / 255.0f; + constants.plight_colors[i][0] = (color >> 24) & 0xFF; + constants.plight_colors[i][1] = (color >> 16) & 0xFF; + constants.plight_colors[i][2] = (color >> 8) & 0xFF; + constants.plight_colors[i][3] = (color) & 0xFF; xfmemptr += 4; for (int j = 0; j < 4; ++j, xfmemptr += 3) @@ -125,11 +126,11 @@ void PixelShaderManager::SetConstants() fabs(xfmemptr[1]) < 0.00001f && fabs(xfmemptr[2]) < 0.00001f) // dist attenuation, make sure not equal to 0!!! - constants.plights[5*i+j+1][0] = 0.00001f; + constants.plights[4*i+j][0] = 0.00001f; else - constants.plights[5*i+j+1][0] = xfmemptr[0]; - constants.plights[5*i+j+1][1] = xfmemptr[1]; - constants.plights[5*i+j+1][2] = xfmemptr[2]; + constants.plights[4*i+j][0] = xfmemptr[0]; + constants.plights[4*i+j][1] = xfmemptr[1]; + constants.plights[4*i+j][2] = xfmemptr[2]; } } dirty = true; diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index a4893ce2dc..6310f6ceba 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -88,7 +88,8 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ DeclareUniform(out, api_type, C_POSNORMALMATRIX, "float4", I_POSNORMALMATRIX"[6]"); DeclareUniform(out, api_type, C_PROJECTION, "float4", I_PROJECTION"[4]"); DeclareUniform(out, api_type, C_MATERIALS, "float4", I_MATERIALS"[4]"); - DeclareUniform(out, api_type, C_LIGHTS, "float4", I_LIGHTS"[40]"); + DeclareUniform(out, api_type, C_LIGHT_COLORS, "int4", I_LIGHT_COLORS"[8]"); + DeclareUniform(out, api_type, C_LIGHTS, "float4", I_LIGHTS"[32]"); DeclareUniform(out, api_type, C_TEXMATRICES, "float4", I_TEXMATRICES"[24]"); DeclareUniform(out, api_type, C_TRANSFORMMATRICES, "float4", I_TRANSFORMMATRICES"[64]"); DeclareUniform(out, api_type, C_NORMALMATRICES, "float4", I_NORMALMATRICES"[32]"); @@ -230,7 +231,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ out.Write("o.colors_0 = float4(1.0, 1.0, 1.0, 1.0);\n"); } - GenerateLightingShader(out, uid_data.lighting, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); + GenerateLightingShader(out, uid_data.lighting, components, I_MATERIALS, I_LIGHT_COLORS, I_LIGHTS, "color", "o.colors_"); if (xfregs.numChan.numColorChans < 2) { diff --git a/Source/Core/VideoCommon/VertexShaderGen.h b/Source/Core/VideoCommon/VertexShaderGen.h index e705845a6a..43d5273f4a 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.h +++ b/Source/Core/VideoCommon/VertexShaderGen.h @@ -33,6 +33,7 @@ #define I_POSNORMALMATRIX "cpnmtx" #define I_PROJECTION "cproj" #define I_MATERIALS "cmtrl" +#define I_LIGHT_COLORS "clight_colors" #define I_LIGHTS "clights" #define I_TEXMATRICES "ctexmtx" #define I_TRANSFORMMATRICES "ctrmtx" @@ -44,8 +45,9 @@ #define C_POSNORMALMATRIX 0 #define C_PROJECTION (C_POSNORMALMATRIX + 6) #define C_MATERIALS (C_PROJECTION + 4) -#define C_LIGHTS (C_MATERIALS + 4) -#define C_TEXMATRICES (C_LIGHTS + 40) +#define C_LIGHT_COLORS (C_MATERIALS + 4) +#define C_LIGHTS (C_LIGHT_COLORS + 8) +#define C_TEXMATRICES (C_LIGHTS + 32) #define C_TRANSFORMMATRICES (C_TEXMATRICES + 24) #define C_NORMALMATRICES (C_TRANSFORMMATRICES + 64) #define C_POSTTRANSFORMMATRICES (C_NORMALMATRICES + 32) diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index e505fbba37..d1264a68ba 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -252,6 +252,7 @@ void VertexShaderManager::SetConstants() if (nLightsChanged[0] >= 0) { + // TODO: Outdated comment // lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats int istart = nLightsChanged[0] / 0x10; int iend = (nLightsChanged[1] + 15) / 0x10; @@ -260,10 +261,10 @@ void VertexShaderManager::SetConstants() for (int i = istart; i < iend; ++i) { u32 color = *(const u32*)(xfmemptr + 3); - constants.lights[5*i][0] = ((color >> 24) & 0xFF) / 255.0f; - constants.lights[5*i][1] = ((color >> 16) & 0xFF) / 255.0f; - constants.lights[5*i][2] = ((color >> 8) & 0xFF) / 255.0f; - constants.lights[5*i][3] = ((color) & 0xFF) / 255.0f; + constants.light_colors[i][0] = (color >> 24) & 0xFF; + constants.light_colors[i][1] = (color >> 16) & 0xFF; + constants.light_colors[i][2] = (color >> 8) & 0xFF; + constants.light_colors[i][3] = (color) & 0xFF; xfmemptr += 4; for (int j = 0; j < 4; ++j, xfmemptr += 3) @@ -274,12 +275,12 @@ void VertexShaderManager::SetConstants() fabs(xfmemptr[2]) < 0.00001f) { // dist attenuation, make sure not equal to 0!!! - constants.lights[5*i+j+1][0] = 0.00001f; + constants.lights[4*i+j][0] = 0.00001f; } else - constants.lights[5*i+j+1][0] = xfmemptr[0]; - constants.lights[5*i+j+1][1] = xfmemptr[1]; - constants.lights[5*i+j+1][2] = xfmemptr[2]; + constants.lights[4*i+j][0] = xfmemptr[0]; + constants.lights[4*i+j][1] = xfmemptr[1]; + constants.lights[4*i+j][2] = xfmemptr[2]; } } dirty = true;