Jump to content
  • Advertisement
Sign in to follow this  
arjansingh00

HLSL Function Problem

This topic is 645 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

Right now I am trying to implement Specular lighting in my DirectX Engine. Whenever I create the DirectSpecularBRDF function in my .HLSL file, my program crashes. Can anybody help me? The problem is in DirectSpecularBRDF, I haven't called the function yet but when I comment out the function code everything works fine. However DirectDiffuseBRDF works fine though? Here is my code:

 

effects.fx

#include "Common.hlsl"

struct Light
{
float3 dir;
float4 ambient;
float4 diffuse;
};

cbuffer cbPerFrame
{
Light light;
float4x4 camPos;
float Roughness;
float Metalness;
};

cbuffer cbPerObject
{
float4x4 WVP;
float4x4 World;
};

Texture2D ObjTexture;
SamplerState ObjSamplerState
{
Filter = ANISOTROPIC;
MaxAnisotropy = 16;
AddressU = Wrap;
AddressV = Wrap;
};

struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float2 TexCoord : TEXCOORD;
float3 normal : NORMAL;
};

float3 DirectDiffuseBRDF(float3 diffuseAlbedo, float nDotL)
{
return (diffuseAlbedo * nDotL);
}

float3 DirectSpecularBRDF(float3 specularAlbedo, float3 positionWS, float3 normalWS, float3 lightDir)
{
float3 viewDir = normalize(camPos - positionWS);
float3 halfVec = normalize(viewDir + lightDir);

float nDotH = saturate(dot(normalWS, halfVec));
float nDotL = saturate(dot(normalWS, lightDir));
float nDotV = max(dot(normalWS, viewDir), 0.0001f);

float alpha2 = Roughness * Roughness;

// Computes the distribution of the microfacets for the shaded surface.
// Trowbridge-Reitz/GGX normal distribution function.
float D = alpha2 / (Pi * pow(nDotH * nDotH * (alpha2 - 1) + 1, 2.0f));

// Computes the amount of light that reflects from a mirror surface given its index of refraction. 
// Schlick's approximation.
float3 F = Schlick_Fresnel(specularAlbedo, halfVec, lightDir);

// Computes the shadowing from the microfacets.
// Smith's approximation.
float G = G_Smith(Roughness, nDotV, nDotL);

return D * F * G;
}

VS_OUTPUT VS(float4 inPos : POSITION, float2 inTexCoord : TEXCOORD, float3 normal : NORMAL)
{
VS_OUTPUT output;

output.Pos = mul(inPos, WVP);

output.normal = mul(normal, World);

output.TexCoord = inTexCoord;

return output;
}

float4 PS(VS_OUTPUT input) : SV_TARGET
{
input.normal = normalize(input.normal);

float4 textureColor = ObjTexture.Sample(ObjSamplerState, input.TexCoord);
float3 specularColor = float3(Metalness, Metalness, Metalness);

float nDotL = saturate(dot(input.normal, light.dir));

float3 diffuseLighting = textureColor * light.ambient * light.diffuse;

diffuseLighting += saturate(DirectDiffuseBRDF(textureColor, nDotL));

return float4(diffuseLighting, textureColor.a);
}

common.hlsl

//=================================================================================================
// Constant Variables
//=================================================================================================
static const float Pi = 3.141592654f;
static const float Pi2 = 6.283185307f;
static const float Pi_2 = 1.570796327f;
static const float Pi_4 = 0.7853981635f;
static const float InvPi = 0.318309886f;
static const float InvPi2 = 0.159154943f;

//=================================================================================================
// Sampler States
//=================================================================================================
SamplerState SamplerLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};

SamplerState SamplerAnisotropic
{
Filter = ANISOTROPIC;
MaxAnisotropy = 16;
AddressU = Wrap;
AddressV = Wrap;
};

// ===============================================================================================
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
// ===============================================================================================
float2 Hammersley(uint i, uint N)
{
float ri = reversebits(i) * 2.3283064365386963e-10f;
return float2(float(i) / float(N), ri);
}

// ===============================================================================================
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
// ===============================================================================================
float GGX(float NdotV, float a)
{
float k = a / 2;
return NdotV / (NdotV * (1.0f - k) + k);
}

// ===============================================================================================
// Geometry Term
// -----------------------------------------------------------------------------------------------
// Defines the shadowing from the microfacets.
//
// Smith approximation:
// http://blog.selfshadow.com/publications/s2013-shading-course/rad/s2013_pbs_rad_notes.pdf
// http://graphicrants.blogspot.fr/2013/08/specular-brdf-reference.html
//
// ===============================================================================================
float G_Smith(float a, float nDotV, float nDotL)
{
return GGX(nDotL, a * a) * GGX(nDotV, a * a);
}

// ================================================================================================
// Fresnel
// ------------------------------------------------------------------------------------------------
// The Fresnel function describes the amount of light that reflects from a mirror surface 
// given its index of refraction. 
//
// Schlick's approximation:
// http://blog.selfshadow.com/publications/s2013-shading-course/rad/s2013_pbs_rad_notes.pdf
// http://graphicrants.blogspot.fr/2013/08/specular-brdf-reference.html
//
// ================================================================================================
float3 Schlick_Fresnel(float3 f0, float3 h, float3 l)
{
return f0 + (1.0f - f0) * pow((1.0f - dot(l, h)), 5.0f);
}

// ===============================================================================================
// http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf 
// ===============================================================================================
float3 ImportanceSampleGGX(float2 Xi, float Roughness, float3 N)
{
float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]

float Phi = 2 * Pi * Xi.x;
float CosTheta = sqrt((1 - Xi.y) / (1 + (a * a - 1) * Xi.y));
float SinTheta = sqrt(1 - CosTheta * CosTheta);

float3 H;
H.x = SinTheta * cos(Phi);
H.y = SinTheta * sin(Phi);
H.z = CosTheta;

float3 UpVector = abs(N.z) < 0.999 ? float3(0, 0, 1) : float3(1, 0, 0);
float3 TangentX = normalize(cross(UpVector, N));
float3 TangentY = cross(N, TangentX);

// Tangent to world space
return TangentX * H.x + TangentY * H.y + N * H.z;
}
Edited by arjansingh00

Share this post


Link to post
Share on other sites
Advertisement

The first thing you need to do is find out where your code is crashing, and then you need to figure out why it's crashing. The first question is very easy to answer with a debugger, since it will tell you the line of code (or assembly instruction if you choose to go that deep) where the crash occurred. The second question is also easy to answer with a debugger in many cases, although in some cases the root cause will not be obvious which requires more investigation. In either case you should start by reading the message reported to you by the debugger and understanding what it means. Once you've done that, look at the flow of your program so that you can determine the sequence of events that led to the error condition.

 

These are extremely important and basic skills for a programmer, so now is a good time to start learning them and putting them to use. :)

Edited by MJP

Share this post


Link to post
Share on other sites
I've heard that the .FX framework is now deprecated so there's no longer a debugger in visual studio 2015. If there is one how can I enable it/ use it? At the moment I can't even include the .fx and .hlsl files in visual studio without getting an error, I have to include it in the projects directory and open it in visual studio 2015 and work with it that way.

Share this post


Link to post
Share on other sites

 Expounding upon MYPs answer, and offering a little bit of advice of my own in the process. Usually you don't want to post a wall of code on a thread, and ask someone else to do the debugging for you. (Usually those threads don't even get a response. Not because we are lazy, but because that wall of code may not even offer all of the required variables to answer your question fully).

 

Now, not using a debugger aside. One thing you can try is commenting out some individual functions, or lines of code that your DirectSpecularBRDF function is dependent on. This will help you to logically deduce if the issue is really the code in the DirectSpecularBRDF function at all, or maybe an issue in one of the functions in common.hlsl. Maybe even, in time, you can narrow down the issue to an individual function or line of code.

 

This is really a medieval way to debug admittedly. But it gives you more insight than just sitting on your palms wondering why it won't work at all.

 

EDIT

    In regards to your app code, not shader code. Without any input from you in regards to what your app debugger is actually showing (and completely dependent upon the one clue of removal, and re-adding of your function in the shader determining whether or not your app crashes) I would make a blind wager that it's very possible that an exception is being thrown when you compile your shader into a blob object. (If you are indeed handling performing compilation in your app code base, and not offline)

 

Which onto that topic, do you have any error/exception handling for your shader compilation code? Can you post the code for that?

 

Food for thought

 

Marcus

Edited by markypooch

Share this post


Link to post
Share on other sites

I meant your normal C++ debugger, not a debugger for your shader code. 

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!