trzy / Supermodel

Official repository of the Sega Model 3 arcade emulator.
https://supermodel3.com
258 stars 37 forks source link

White track graphics on Scud Race and Daytona USA 2 #91

Closed vanfanel closed 11 months ago

vanfanel commented 11 months ago

Hi there,

As I said in a previous thread, I have just build Supermodel latest GIT code on Debian 12, where I run latest stable SDL2 and latest stable MESA (23.2.1 as of this writing).

The problem is that are supposedly working good on Supermodel current code look like this:

photo_2023-10-18_18-13-33

I suspect MESA drivers: I have 12th gen Intel XE Graphics, and as I said I use latest stable MESA 23.2.1. Has Supermodel been tested on 12th gen Intel graphics?

vanfanel commented 11 months ago

Ok, again answering myself here: passing -quad-rendering seems to fix the issue, but is that expected at all? By reading the docs I seem to understand it's optional?

dukeeeey commented 11 months ago

Yes quad rendering is optional. It's more expensive generally than the triangle version. So you are saying it doesn't work unless it's enabled?

vanfanel commented 11 months ago

Yes quad rendering is optional. It's more expensive generally than the triangle version. So you are saying it doesn't work unless it's enabled?

Without quad rendering, tracks look all white, as in the picture I uploaded.

dukeeeey commented 11 months ago

strange.. the triangle renderer is a much simpler render path What do other games look like

vanfanel commented 11 months ago

@dukeeeey The other games looked the same (ie: white tracks on racing games, which is what I tested so far).

But this is NOT a Supermodel issue: building and installing latest gitlab MESA (23.0 dev currently) the problem does not happen anymore.

So, if someone comes here with that problem on Intel XE graphics, tell them to build and install latest gitlab MESA :)

Sorry for the noise... And thanks for taking a look at this non-inssue!

vanfanel commented 11 months ago

@dukeeeey Apparently this is still an issue: I had left QuadRendering = true on the config file...

So, with latest MESA, on Intel XE graphics, tracks look all white unless QuadRendering = true is used, which produces slowdowns in games.

Can someone please test this on Intel XE graphics with current MESA? If it's possible to reproduce the issue, I will report this to MESA devs on Gitlab.

dukeeeey commented 11 months ago

Can you give some more screenshots, I am more interested in what parts aren't white .. maybe I can figure out what the issue is. Also if you could try older builds to see if the problem exists in those?

vanfanel commented 11 months ago

@dukeeeey I will give you as many screenshots as you need. Just ask me if you need a given scene on a game, etc.

This is Sega Rally 2, only the public and the crystals of the cars seem visible in demo mode and in-game: sm1 sm2

This is Daytona2. Demo mode looks perfectly fine! sm3

...But on the car selection menu, there are already white elements (the icons on the lower left window, and also the cars): sm4 sm5

This may be helpful too: the actual race starts perfectly well, then suddenly (always happens on the same moment) the track and many elements become white: https://github.com/trzy/Supermodel/assets/837585/5014dbb8-04d0-4ac4-8550-122e9da71d4a

As for old versions, can you please give me an specific commit you would like me to build? I have to disable all the legacy GLX stuff in order to build each version (my system doesn't have any GLX stuff, OpenGL runs via GLVND/MESA), so it takes some time for me to do that.

dukeeeey commented 11 months ago

The video is super helpful. Basically it looks like as soon as the spotlight turns on it breaks. The only difference in the shaders between the quad/triangle version is the spotlight code. Someone modified them at some point. Maybe worth copying and pasting that code.

vanfanel commented 11 months ago

@dukeeeey do you mean I should try that?

Then, please point me to the two pieces of code: I don't know my way though the Supermodel code.

dukeeeey commented 11 months ago

I'll try and find time to make a patch today But the shader code lives in R3DShaderTriangles.h and R3DShaderQuads.h

vanfanel commented 11 months ago

ok, I will wait for your patch

vanfanel commented 11 months ago

I tried to copy/paste the quad shaders code into the triangle shaders, but it's not that easy, as there are some variables that are pipelined from the geometry shader, which is not present among the triangle shaders.

So yes, I need a patch to test this.

dukeeeey commented 11 months ago

try this

static const char *fragmentShaderR3D = R"glsl(

version 410 core

uniform usampler2D tex1; // entire texture sheet

// texturing uniform bool textureEnabled; uniform bool microTexture; uniform float microTextureScale; uniform int microTextureID; uniform ivec4 baseTexInfo; // x/y are x,y positions in the texture sheet. z/w are with and height uniform int baseTexType; uniform bool textureInverted; uniform bool textureAlpha; uniform bool alphaTest; uniform bool discardAlpha; uniform ivec2 textureWrapMode;

// general uniform vec3 fogColour; uniform vec4 spotEllipse; // spotlight ellipse position: .x=X position (screen coordinates), .y=Y position, .z=half-width, .w=half-height) uniform vec2 spotRange; // spotlight Z range: .x=start (viewspace coordinates), .y=limit uniform vec3 spotColor; // spotlight RGB color uniform vec3 spotFogColor; // spotlight RGB color on fog uniform vec3 lighting[2]; // lighting state (lighting[0] = sun direction, lighting[1].x,y = diffuse, ambient intensities from 0-1.0) uniform bool lightEnabled; // lighting enabled (1.0) or luminous (0.0), drawn at full intensity uniform bool sunClamp; // not used by daytona and la machine guns uniform bool intensityClamp; // some games such as daytona and uniform bool specularEnabled; // specular enabled uniform float specularValue; // specular coefficient uniform float shininess; // specular shininess uniform float fogIntensity; uniform float fogDensity; uniform float fogStart; uniform float fogAttenuation; uniform float fogAmbient; uniform bool fixedShading; uniform int hardwareStep; uniform int colourLayer;

//interpolated inputs from vertex shader in vec3 fsViewVertex; in vec3 fsViewNormal; // per vertex normal vector in vec4 fsColor; in vec2 fsTexCoord; in float fsDiscard; in float fsFixedShade;

//outputs layout(location = 0) out vec4 out0; // opaque layout(location = 1) out vec4 out1; // trans layer 1 layout(location = 2) out vec4 out2; // trans layer 2

// forward declarations (see common file)

float CalcFog(); void Step15Luminous(inout vec4 colour); vec4 GetTextureValue(); void WriteOutputs(vec4 colour, int layer);

float sqr(float a) { return a*a; }

float sqr_length(vec2 a) { return a.xa.x + a.ya.y; }

void main() { vec4 tex1Data; vec4 colData; vec4 finalData; vec4 fogData;

if(fsDiscard > 0) {
    discard;        //emulate back face culling here
}

fogData = vec4(fogColour.rgb * fogAmbient, CalcFog());
tex1Data = vec4(1.0, 1.0, 1.0, 1.0);

if(textureEnabled) {
    tex1Data = GetTextureValue();
}

colData = fsColor;
Step15Luminous(colData);            // no-op for step 2.0+  
finalData = tex1Data * colData;

if (finalData.a < (1.0/16.0)) {     // basically chuck out any totally transparent pixels value = 1/16 the smallest transparency level h/w supports
    discard;
}

float ellipse;
ellipse = sqr_length((gl_FragCoord.xy - spotEllipse.xy) / spotEllipse.zw); // decay rate = square of distance from center
ellipse = 1.0 - ellipse;      // invert
ellipse = max(0.0, ellipse);  // clamp

// Compute spotlight and apply lighting
float enable, absExtent, d, inv_r, range;

// start of spotlight
enable = step(spotRange.x, -fsViewVertex.z);

if (spotRange.y == 0.0) {
    range = 0.0;
}
else {
    absExtent = abs(spotRange.y);

    d = spotRange.x + absExtent + fsViewVertex.z;
    d = min(d, 0.0);

    // slope of decay function
    inv_r = 1.0 / (1.0 + absExtent);

    // inverse-linear falloff
    // Reference: https://imdoingitwrong.wordpress.com/2011/01/31/light-attenuation/
    // y = 1 / (d/r + 1)^2
    range = 1.0 / sqr(d * inv_r - 1.0);
    range *= enable;
}

float lobeEffect = range * ellipse;
float lobeFogEffect = enable * ellipse;

if (lightEnabled) {
    vec3   lightIntensity;
    vec3   sunVector;     // sun lighting vector (as reflecting away from vertex)
    float  sunFactor;     // sun light projection along vertex normal (0.0 to 1.0)

    // Sun angle
    sunVector = lighting[0];

    // Compute diffuse factor for sunlight
    if(fixedShading) {
        sunFactor = fsFixedShade;
    }
    else {
        sunFactor = dot(sunVector, fsViewNormal);
    }

    // Clamp ceil, fix for upscaled models without "modelScale" defined
    sunFactor = clamp(sunFactor,-1.0,1.0);

    // Optional clamping, value is allowed to be negative
    if(sunClamp) {
        sunFactor = max(sunFactor,0.0);
    }

    // Total light intensity: sum of all components 
    lightIntensity = vec3(sunFactor*lighting[1].x + lighting[1].y);   // diffuse + ambient

    lightIntensity.rgb += spotColor*lobeEffect;

    // Upper clamp is optional, step 1.5+ games will drive brightness beyond 100%
    if(intensityClamp) {
        lightIntensity = min(lightIntensity,1.0);
    }

    finalData.rgb *= lightIntensity;

    // for now assume fixed shading doesn't work with specular
    if (specularEnabled) {

        float exponent, NdotL, specularFactor;
        vec4 biasIndex, expIndex, multIndex;

        // Always clamp floor to zero, we don't want deep black areas
        NdotL = max(0.0,sunFactor);

        expIndex = vec4(8.0, 16.0, 32.0, 64.0);
        multIndex = vec4(2.0, 2.0, 3.0, 4.0);
        biasIndex = vec4(0.95, 0.95, 1.05, 1.0);
        exponent = expIndex[int(shininess)] / biasIndex[int(shininess)];

        specularFactor = pow(NdotL, exponent);
        specularFactor *= multIndex[int(shininess)];
        specularFactor *= biasIndex[int(shininess)];

        specularFactor *= specularValue;
        specularFactor *= lighting[1].x;

        if (colData.a < 1.0) {
            /// Specular hi-light affects translucent polygons alpha channel ///
            finalData.a = max(finalData.a, specularFactor);
        }

        finalData.rgb += vec3(specularFactor);
    }
}

// Final clamp: we need it for proper shading in dimmed light and dark ambients
finalData.rgb = min(finalData.rgb, vec3(1.0));

// Spotlight on fog
vec3 lSpotFogColor = spotFogColor * fogAttenuation * fogColour.rgb * lobeFogEffect;

 // Fog & spotlight applied
finalData.rgb = mix(finalData.rgb, fogData.rgb + lSpotFogColor, fogData.a);

// Write outputs to colour buffers
WriteOutputs(finalData,colourLayer);

} )glsl";

vanfanel commented 11 months ago

@dukeeeey That shader code seems to be broken or incorrect:


0:69(8): error: invalid swizzle / mask `xa'
0:69(8): error: type mismatch
0:69(8): error: type mismatch
0:69(17): error: invalid swizzle / mask `ya'
0:69(17): error: type mismatch
0:69(17): error: type mismatch
0:69(8): error: operands to arithmetic operators must be numeric
0:69(1): error: `return' with wrong type error, in function `sqr_length' returning float

error: linking with uncompiled/unspecialized shader
dukeeeey commented 11 months ago

try this https://pastebin.com/zparWMRC Same code, maybe something got broken during copy.

Just replace the code in the file with that version

vanfanel commented 11 months ago

@dukeeeey That works PERFECT!

Not only it looks perfectly fine, but framerate has improved! Please make this the fragment shader for the triangle-based renderer! Great!

dukeeeey commented 11 months ago

thanks for the feedback, i'll push the changes soon :)

dukeeeey commented 11 months ago

Okay should be fixed in the latest version! Thanks for your help with finding this issue.