Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct shade mapping when light pos is all zeros #11567

Merged
merged 3 commits into from
Nov 18, 2018

Conversation

unknownbrackets
Copy link
Collaborator

This fixes #4155. Well, except the slope mip mapping issue which I'm opening separately.

  • Software transform used uninitialized values for tex env / lighting disabled. May have caused other flickering, but sometimes caused it to render not white.
  • Hardware normalized a light pos of (0, 0, 0) as NAN, and this resulted in using the color at x=0.
  • SoftGPU normalized a light pos of (0, 0, 0) as NAN, but this just resulted in no shading (maybe 1.)

The correct behavior appears when normalizing it as (0, 0, 1) which effectively means using the z component of worldnormal only. A bit worried this might affect other places we normalize.

This is what it looks like now:
better shade mapping

Correct result (PSP screenshot from @daniel229) - different frame, of course:
naturo_correct

I think the white could be a bit too strong, but it looks close, compare to without white at all:
naruto_shading_wrong

-[Unknown]

Was using invalid values when lighting was off.
May need to audit more normalize() usage, if it's consistent in other
places.
};
auto calcShadingLPos = [&](int l) {
Vec3f pos = getLPos(l);
if (pos.Length() == 0.0f) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that it's important, but you could save a square root here by using Length2() instead (which is simply length without the square root).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point, didn't think about that.

-[Unknown]

@@ -715,7 +715,11 @@ void GenerateVertexShaderHLSL(const VShaderID &id, char *buffer, ShaderLanguage
break;

case GE_TEXMAP_ENVIRONMENT_MAP: // Shade mapping - use dots from light sources.
WRITE(p, " Out.v_texcoord = float3(u_uvscaleoffset.xy * float2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 + dot(normalize(u_lightpos%i), worldnormal)) * 0.5, 1.0);\n", ls0, ls1);
{
std::string lightFactor0 = StringFromFormat("(length(u_lightpos%i) == 0.0 ? worldnormal.z : dot(normalize(u_lightpos%i), worldnormal))", ls0, ls0);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to the previous comment, I wonder if GPU compilers optimize length==0 to avoid the square root. Then again, square roots are pretty fast on gpu so maybe it doesn't matter. No idea if either way is faster than just comparing all three components to 0.0.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I can't get any even slightly consistent results between:

  • all(equal(light.pos[%i], vec3(0.0)))
  • length(light.pos[%i]) == 0.0
  • dot(light.pos[%i], vec3(1.0)) == 0.0
  • dot(light.pos[%i], light.pos[%i]) == 0.0
  • light.pos[%i].x == 0.0 && light.pos[%i].y == 0.0 && light.pos[%i].z == 0.0

If you have any preference, happy to change it. No idea which might be faster on various drivers...

-[Unknown]

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably all of small enough impact to not really make a performance difference...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Naruto Ultimate Ninja Impact Hachibi White Colour
2 participants