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

Tales of the World: Radiant Mythology Graphic Glitch with Hardware Transform #2424

Closed
hsark opened this issue Jun 23, 2013 · 14 comments · Fixed by #3547
Closed

Tales of the World: Radiant Mythology Graphic Glitch with Hardware Transform #2424

hsark opened this issue Jun 23, 2013 · 14 comments · Fixed by #3547

Comments

@hsark
Copy link

hsark commented Jun 23, 2013

Software/Game tested: Tales of the World: Radiant Mythology
File format(ISO/CSO/EBOOT): ISO
Version: v0.8-5 , v0.7.6-1564
OS: Android 4.2 Paranoid
Device: Google Nexus 7

Buffered Render on/off doesn't seem to make a difference
Force linear filtering: on
Jit : on

Having problems with this game on Android can't see the characters while playing the game due to there shadows being too heavy but when i turn hardware transform off it looks fine but the frame rate drops from 60fps to 30-28fps

I've also tested this on the pc version v0.7.6-1381 which works well with HT on, so it seems the problem only occurs on android but i'm not sure if the problem is exclusive to the tegra 3 devices.

HT On shadow glitch
a1

HT off , you can see the drop in frame rate
a2

@unknownbrackets
Copy link
Collaborator

This happens for me on Windows using an NVIDIA card. I hadn't realized it went away with hardware transform off, interesting.

-[Unknown]

@unknownbrackets
Copy link
Collaborator

If I replace:

WRITE(p, "  lowp vec4 lightSum0 = u_ambient * %s + vec4(u_matemissive, 0.0);\n", ambientStr);

With:

WRITE(p, "  lowp vec4 lightSum0 = %s + vec4(u_matemissive, 0.0);\n", ambientStr);

The problem goes away. Using clamp(u_ambient, 0.5, 1.0) makes the black effect less pronounced. So it seems like u_ambient is 0... but I'm not sure if that's a problem, for sure...

-[Unknown]

@solarmystic
Copy link
Contributor

@unknownbrackets

Score 1 for AMD cards. (finally lol) I don't get this problem even with Hardware Transform ON on my AMD card.

Tested on ppsspp-v0.8-6-g6a9e6ce-amd64. Finally, those crappy OGL drivers work to our benefit.

capture

@hsark
Copy link
Author

hsark commented Jun 24, 2013

that's interesting i'm also using an ATI graphics card on pc and i've never experienced this problem I've only had a problem with it on my tablet so it seems to be a problem affecting NVIDA products. I'll test out a nvida cards tomorrow

@unknownbrackets
has this occurred with other games ?

@hrydgard
Copy link
Owner

Can you try removing all the precision markers (lowp, mediump etc) and see if that changes anything?

Although these days I think nvidia always uses full precision on Windows...

@unknownbrackets
Copy link
Collaborator

Blade Dancer also shows things black that it shouldn't (being everything) but I think it's a separate problem. I do think someone was reporting this sort of "reverse lighting" look in another game.

I removed all the lowp and mediump and ifdefs that played with precision. I tried that and also leaving WRITE(p, "precision highp float;\n"); in there, didn't help either way...

Frame dump:
https://gist.github.com/unknownbrackets/5856370

From software, u_ambient is probably correct, so it's probably something else...

-[Unknown]

@unknownbrackets
Copy link
Collaborator

I may be wrong, but I think type == GE_LIGHTTYPE_DIRECTIONAL is handled differently between software and hardware. For specular, toLight is divided by distanceToLight always in SW, but only when not GE_LIGHTTYPE_DIRECTIONAL in hw, I think. But I'm not sure.

It doesn't seem to affect this issue either way.

-[Unknown]

@hrydgard
Copy link
Owner

In HW, I pre-divide before uploading the uniform for directional lights. See ShaderManager.cpp. This shortens shaders by a few instructions, hopefully making more of them run on Mali.

@unknownbrackets
Copy link
Collaborator

Ah, okay. Right, that was a recent commit.

-[Unknown]

@unknownbrackets
Copy link
Collaborator

Okay, so for sure, the only value assigned to u_ambient here is 0x333333/0xFF (color/alpha.) I tried hard coding vec4(0.2, 0.2, 0.2, 1.0) and nothing changed. So, that's probably not the problem.

If I identified it correctly with gDEBugger, this is the problem shader:

#version 110
#define lowp
#define mediump
attribute mediump vec4 a_w1, a_w2;
attribute vec3 a_position;
attribute mediump vec3 a_normal;
attribute vec2 a_texcoord;
uniform mat4 u_proj;
uniform mat4 u_world;
uniform mat4 u_view;
uniform mat4 u_bone0;
uniform mat4 u_bone1;
uniform mat4 u_bone2;
uniform mat4 u_bone3;
uniform mat4 u_bone4;
uniform mat4 u_bone5;
uniform mat4 u_bone6;
uniform mat4 u_bone7;
uniform vec4 u_uvscaleoffset;
uniform vec3 u_lightpos0;
uniform mediump vec3 u_lightdir0;
uniform lowp vec3 u_lightambient0;
uniform lowp vec3 u_lightdiffuse0;
uniform lowp vec3 u_lightspecular0;
uniform lowp vec4 u_ambient;
uniform lowp vec4 u_matspecular;
uniform lowp vec3 u_matemissive;
uniform lowp vec4 u_matambientalpha;
uniform vec2 u_fogcoef;
varying lowp vec4 v_color0;
varying lowp vec3 v_color1;
varying vec2 v_texcoord;
varying float v_fogdepth;
void main() {
  mat4 skinMatrix = a_w1.x * u_bone0 + a_w1.y * u_bone1 + a_w1.z * u_bone2 + a_w1.w * u_bone3 + a_w2.x * u_bone4 + a_w2.y * u_bone5 + a_w2.z * u_bone6 + a_w2.w * u_bone7;
  vec3 skinnedpos = (skinMatrix * vec4(a_position, 1.0)).xyz  * 1.9921875;
  vec3 worldpos = (u_world * vec4(skinnedpos, 1.0)).xyz;
  vec3 skinnednormal = (skinMatrix * vec4(a_normal, 0.0)).xyz  * 1.9921875;
  vec3 worldnormal = normalize((u_world * vec4(skinnednormal, 0.0)).xyz);
  vec4 viewPos = u_view * vec4(worldpos, 1.0);
  gl_Position = u_proj * viewPos;
  lowp vec4 lightSum0 = u_ambient * u_matambientalpha + vec4(u_matemissive, 0.0);
  lowp vec3 lightSum1 = vec3(0.0);
  vec3 toLight;
  lowp vec3 diffuse;
  toLight = u_lightpos0;
  mediump float dot0 = pow(dot(toLight, worldnormal), u_matspecular.a);
  diffuse = (u_lightdiffuse0 * u_matambientalpha.rgb) * max(dot0, 0.0);
  dot0 = dot(normalize(toLight + vec3(0.0, 0.0, 1.0)), worldnormal);
  if (dot0 > 0.0)
    lightSum1 += u_lightspecular0 * u_matambientalpha.rgb * (pow(dot0, u_matspecular.a) );
  lightSum0.rgb += (u_lightambient0 * u_matambientalpha.rgb + diffuse);
  v_color0 = clamp(lightSum0, 0.0, 1.0);
  v_color1 = clamp(lightSum1, 0.0, 1.0);
  v_texcoord = a_texcoord * u_uvscaleoffset.xy + u_uvscaleoffset.zw;
  v_fogdepth = (viewPos.z + u_fogcoef.x) * u_fogcoef.y;
}

Where:

u_ambient = vec4(0.2, 0.2, 0.2, 1.0)
u_matambientalpha = vec4(1.0, 1.0, 1.0, 1.0)
u_matemissive = vec3(0.0, 0.0, 0.0)
u_uvscaleoff = one of vec4(1.0, 1.0, 0.0), vec4(1.999969, 1.999969, 0.0, 0.0), or vec4(1.0, 1.0, 0.0, 0.26)
u_fogcoef = one of vec2(-20000.0, -0.0001) or vec2(-1000.0, -0.000999), 
u_lightpos0 = vec3(-1.0, 0.0, 0.0)
u_lightdir0 --- (appears not to be set or used?)  ought to be vec3(0.0, 0.0, 0.0)
u_matspecular.a = 0.0
u_lightdiffuse0 = vec3(1.0, 1.0, 1.0)
u_lightspecular0 = vec3(0.0, 0.0, 0.0)
u_lightambient0 = vec3(0.0, 0.0, 0.0)

-[Unknown]

@unknownbrackets
Copy link
Collaborator

If I change:

WRITE(p, "  mediump float dot%i = pow(dot(toLight, worldnormal), u_matspecular.a);\n", i);

To:

WRITE(p, "  mediump float dot%i = pow(dot(toLight, worldnormal), 0.0);\n", i);

It works properly. Any non-zero value there seems to cause the problem. I tried changing:

    if (u_matspecular != -1 && (dirtyUniforms & DIRTY_MATSPECULAR)) {
        SetColorUniform3ExtraFloat(u_matspecular, gstate.materialspecular, getFloat24(gstate.materialspecularcoef));
    }

To:

    //if (u_matspecular != -1 && (dirtyUniforms & DIRTY_MATSPECULAR)) {
        SetColorUniform3ExtraFloat(u_matspecular, gstate.materialspecular, 0.0f);
    //}

And also commenting out the early return under if (!dirtyUniforms)... which did not help, it still shows wrong. So then I tried this:

        const float u_matspecular_col[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
        glUniform4fv(u_matspecular, 1, u_matspecular_col);

Which doesn't work either.

-[Unknown]

unknownbrackets added a commit to unknownbrackets/ppsspp that referenced this issue Sep 1, 2013
Zero to the power of zero is mathematically undefined, NVIDIA chokes but
AMD seems to accept it.  Not well tested on Android.

Fixes hrydgard#2424.
@unknownbrackets
Copy link
Collaborator

Please reply or reopen if this happens on an Android or other device, and specify what GPU you're using (e.g. the original report is fine.)

-[Unknown]

@hsark
Copy link
Author

hsark commented Sep 2, 2013

hey unknownb, hrydgard thanks for the hard work and taking the time to address this issue its working quite well on

Software/Game tested: Tales of the World: Radiant Mythology
File format(ISO/CSO/EBOOT): ISO
Version: v0.9.1 -467
OS: Android 4.1.2 Paranoid
Device: Google Nexus 7

Buffered Render on
Vertex cahe on
Mipmapping on
HT on
Jit : on

@hrydgard
Copy link
Owner

hrydgard commented Sep 2, 2013

I don't think I deserve much of the credit for this one :)

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 a pull request may close this issue.

4 participants