Home Technical Talk
The BRAWL² Tournament Challenge has been announced!

It starts May 12, and ends Sept 12. Let's see what you got!

https://polycount.com/discussion/237047/the-brawl²-tournament

Shader - Kelemen Szirmay Kalos - Negative values

polycounter lvl 12
Offline / Send Message
Ace-Angel polycounter lvl 12
Hey peeps,

Can anyone double check the Kelemen snippet I found, here?

For some reason, it doesn't seem to be working as intended, I'm getting some nasty 'negative glowing artifacts' on my mesh when I apply.

I'm trying to avoid a Beckmann texture lookup, instead trying a real-time thing, so it's not 100% nVidia approved, but that shouldn't really be an issue, should it?
float KelemenSzirmayKalosSpec( float3 V, float3 N, float3 L, float4 eccentricity, float rollOff, float4 weight )
{
float spec = 0;

float cosne = dot( V, N );
float cosln = dot( N, L );

float3 h = L + V;
float3 H = normalize( h );

float coseh = dot( H, V );
float cosnh = dot( H, N );

// float alpha = acos( cosnh );
// float ta = tan( alpha );

float cosnhPow2 = cosnh*cosnh;
float ta = sqrt( 1 - cosnhPow2 ) / cosnh;


float cosnhPow4 = cosnhPow2*cosnhPow2;
float4 eccPow2 = eccentricity * eccentricity;

float4 pH = exp( -( ta * ta ) / ( eccPow2 ) ) / ( eccPow2 * cosnhPow4 );

// A Schlick Fresnel
float cosehPow = pow( 1 - coseh, 5.0 );

float Ff = cosehPow + ( 1 - cosehPow ) / rollOff;

float4 specCoeff = max ( ( pH * Ff ) / dot( h, h ), 0 );

spec = saturate( cosln ) * dot( specCoeff, weight );

Here is what it looks like:

asdfap.png

I double checked and triple checked the stuff, even changed a few things around for testing, and I still get the same issue.

Saturating my variables is not an option since my white parts turn black and they end up killing my spec and give it a 'glass' like effect instead.

So any tips?

Replies

  • equil
    just do a max(0.0,spec)?
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Wouldn't this part have the 'clamp' you're suggesting?
    float4 specCoeff = max ( ( pH * Ff ) / dot( h, h ), 0 );

    Unless I misunderstood what you suggested.
  • Drew++
    Offline / Send Message
    Drew++ polycounter lvl 15
    I have a slightly different version of this. Forgot where I got it :P
    float KelemenSzirmayKalosSpec( float3 V, float3 N, float3 L, float4 eccentricity, float rollOff, float4 weight )
    {
    float spec = 0;

    float cosne = dot( V, N );
    float cosln = dot( N, L );

    if( cosln > 0 )
    {
    float3 h = L + V;
    float3 H = normalize( h );

    float coseh = dot( H, V );
    float cosnh = dot( H, N );

    float cosnhPow2 = cosnh*cosnh;
    float ta = sqrt( 1 - cosnhPow2 ) / cosnh;


    float cosnhPow4 = cosnhPow2*cosnhPow2;
    float4 eccPow2 = eccentricity * eccentricity;

    float4 pH = exp( -( ta * ta ) / ( eccPow2 ) ) / ( eccPow2 * cosnhPow4 );

    // A Schlick Fresnel
    float cosehPow = pow( 1 - coseh, 5.0 );

    float Ff = cosehPow + ( 1 - cosehPow ) / rollOff;

    float4 specCoeff = max ( ( pH * Ff ) / dot( h, h ), 0 );

    spec = saturate( cosln ) * dot( specCoeff, weight );

    }


    return spec;
    }
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Hey Drew, thanks, that's solves part of my problem, I guess I did a mistake in the Ta calculation, kudos for finding a 'simpler' code then the one I found, thanks.

    Forward moving, new issue it seems, the part of the code that still eludes me:
    exp( -( ta * ta ) / ( eccPow2 ) ) / ( eccPow2 * cosnhPow4 );
    If I keep the first part of the code [exp( -( ta * ta ) / ( eccPow2 ) )] I get something which looks decent.

    If I on the other hand, include the second code: [/ ( eccPow2 * cosnhPow4 )] I'm getting the glass effect again.

    Here is an example, I'm using Hot Colors for my Ecc values to emulate skin, which shouldn't be a problemo, but here is the other part:

    asdadfm.png

    Any clues? I don't mind cutting fat from the code if it serves my purpose, but this seems ridiculous.

    Also, weighing in at 70+ instructions, it better cure 3 types of cancer and solve world peace.
  • Drew++
    Offline / Send Message
    Drew++ polycounter lvl 15
    I think for the final specular calc, it could/should be something like this.
    specular = 0;

    //Some settings that work?
    float4 eccentricity = float4( 1.0, .333, .167, .1 );
    float rolloff = 15;
    float4 weight = float4( 1, .6, 0.07, 0.004 );

    //diffuse was float diffuse = saturate(dot(lightVec, normal));
    specular = diffuse*KelemenSzirmayKalosSpec(normalize(viewVec), normal, lightVec, eccentricity, rolloff, weight );

    //And then you you know... do your diffuse stuff, then multiply your spec, gloss and whatnot. :P
    Hope this might fix some problems?
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Ah, thanks, those variables look pretty rad, didn't expect Kalos to be such a layered Specular, nice!

    Cheers and thanks a bunch mate, much appreciated!
Sign In or Register to comment.