Jump to content
  • Advertisement
Sign in to follow this  
Alundra

Problem on physical material

This topic is 2021 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all,

I'm working on physical material to change because phong is dead nowadays.

Here the code I currently use to compute the specular factor :

// [Walter et al. 2007, "Microfacet models for refraction through rough surfaces"].
float D_GGX( in float Roughness, in float NoH )
{
  float m = Roughness * Roughness;
  float m2 = m * m;
  float d = ( NoH * m2 - NoH ) * NoH + 1.0f;
  return m2 / ( d*d );
}

// Tuned to match behavior of Smith.
// [Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"].
float G_Schlick( in float Roughness, in float NoV, in float NoL )
{
  float k = (Roughness * Roughness) * 0.5f;
  float G_SchlickV = NoV * (1.0f - k) + k;
  float G_SchlickL = NoL * (1.0f - k) + k;
  return 0.25f / ( G_SchlickV * G_SchlickL );
}

// [Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"]
float3 F_Schlick( in float3 SpecularColor, in float VoH )
{
  return SpecularColor + ( 1.0f - SpecularColor ) * exp2( (-5.55473f * VoH - 6.98316f) * VoH );
}

float3 ComputeSpecFactor( in SURFACE_DATA SurfaceData, in float3 LightDirection, in float NdotL )
{ 
  // Variables used to compute the lighting factor.
  float3 ViewDirection = normalize( -SurfaceData.Position );
  float3 HalfDirection = normalize( LightDirection + ViewDirection );
  
  // Compute the lighting factors.
  float NdotH = max( 0.0f, dot( SurfaceData.Normal, HalfDirection ) );
  float NdotV = max( 0.0f, dot( SurfaceData.Normal, ViewDirection ) );
  float VdotH = max( 0.0f, dot( ViewDirection, HalfDirection ) );
  
  // Generalized microfacet specular.
  float D = D_GGX( Roughness, NdotH );
  float G = G_Schlick( Roughness, NdotV, NdotL );
  float3 F = F_Schlick( SurfaceData.SpecularColor, VdotH );
  
  // Return the specular factor.
  return D * G * F;
}

The problem is I have artifact sometimes on different settings or angles.

Thanks for the help

Edited by Alundra

Share this post


Link to post
Share on other sites
Advertisement

I suggest you get nVidia nSight if you have a nVidia card, AMD Perfstudio 2 if you have an AMD card and Intel's equivalent if you have an Intel iGPU.

Use that software's framedebugger to debug your shaders.

Share this post


Link to post
Share on other sites

First guess: either shadowmapping or NaN. The latter would be the case if you divide by 0 (eg in D_GGX or G_Schlick), so try to clamp the results before dividing by 0.

 

PS:


because phong is dead nowadays.

This is only true for photorealistic rendering, not for NPR. I would bet that NPR games will have a large share in the market in the future wink.png

Edited by Ashaman73

Share this post


Link to post
Share on other sites

It's a mix of unreal 4 shader code, paper of Brian Karis and article of Sebastien Lagarde.

I looked on SpecularAA of Matt Petineo, can be nice to add that to avoid aliasing on specular (normal map).

All work fine, just on directional light when you have this angle of view (pretty on top on a specific side).

I tried to change the max function with an epsilon (0.001f) on each against 0.0f, the problem still the same.

I tried to scale the static mesh who is the level by 5, the problem still the same.

 

Links:

http://seblagarde.wordpress.com/2011/08/17/hello-world/

http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf

UnrealEngine4 Shader = BRDF.usf

Edited by Alundra

Share this post


Link to post
Share on other sites
That screenshot really indicates to me either unbiased shadow-mapping or overlapping double-sided polygons.
If you want to prove it is your shader itself, disable parts of it until that goes away. In doing so, you will not only prove it is the shader but also figure out what part of the shader it is and likely be able to fix it, or at least ask a narrower question.


L. Spiro

Share this post


Link to post
Share on other sites

I have disabled the specular on directionalLight (you can see the comment at the end of function) :

void Directional( in SURFACE_DATA SurfaceData, in DIRECTIONAL_LIGHT Light, inout float3 Result )
{
  float3 LightDirection = normalize( -Light.Direction );
  float NdotL = max( 0.0f, dot( SurfaceData.Normal, LightDirection ) );
  if( NdotL > 0.0f )
  {    
    // Compute the specular factor.
    float3 SpecFactor = ComputeSpecFactor( SurfaceData, LightDirection, NdotL );
    
    // Accumulate the light results.
    //Result += Light.Intensity * Light.Color * (SurfaceData.DiffuseColor * NdotL + SpecFactor);
    Result += Light.Intensity * Light.Color * (SurfaceData.DiffuseColor * NdotL);
  }
}

The problem is away without specular :

http://uppix.com/f-ProbNoSpec533c1fc10015ee2a.png

The problem still the same with just :

Result += SpecFactor;

I had no problems with PhongShading, it's not a problem of geometry I guess. I just changed the ComputeSpecFactor function to move to physical.

On all other side there is no prob but only on this side with the directional light artifacts are visible, here decomposed D/F/G on the bad side :

D : http://uppix.com/f-ProbD533c225e0015ee2f.png
F : http://uppix.com/f-ProbF533c226e0015ee31.png
G : http://uppix.com/f-ProbG533c227e0015ee32.png

Share this post


Link to post
Share on other sites

Looks like the G term is the likely culprit.

 

For starters, schlick's G is

 

G1(x) = dot(n, x) / ( dot(n, x) * (1-k) + k )

 

G(L, V, H) = G1(L) * G1(V)

 

I don't know where that 0.25 in your numerator came from, but at the least you're missing an NoL * NoV, and I'm pretty sure that doesn't cancel out. Epic's paper mentions using a remapping of roughness to (roughness+1)/2 before squaring it, which guarantees a non-zero denominator.

 

Your math for G is probably exploding for surfaces that don't have normals facing one of the two directions, and a roughness of 0.

Share this post


Link to post
Share on other sites

Additionally, your D term formulation might start misbehaving as NoH approaches 1, but the artifacting in that term is probably supposed to get masked off by the missing NoL * NoV in the G term.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!