• 14
• 12
• 9
• 10
• 9

Some help needed on Ward brdf implementation

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

Recommended Posts

Hey guys, I've been trying to implement a Ward brdf model on a simple forward rendering example application in XNA for testing purposes.
I'm having some problems though.

 float4 Ward(float3 N, float3 L, float3 V, float3 T, float3 B) { float3 H = normalize(-L + V); float3 _B = cross(N, T); float NdotL = saturate(dot(N, -L)); float NdotH = saturate(dot(N, H)); float NdotV = saturate(dot(N, V)); float HdotT = saturate(dot(H, T)) / alphaX; float HdotB = saturate(dot(H, _B)) / alphaY; float output = sqrt(max(0.0f, NdotL / NdotV)) * exp(-2.0f * (HdotT * HdotT + HdotB * HdotB) / (1.0f + NdotH)); return float4(NdotL, NdotL, NdotL, output); } 

I've gone through the example code a few times now but I don't see anything wrong with it.
Does anyone have an idea?

Also please look at this video for further info on how the result looks:
http://www.vidup.de/v/DoESS/ (sorry for the bad quality) Edited by lipsryme

Share on other sites
I've gone through the example code a few times now but I don't see anything wrong with it.
What example code? Where are you copying from?

Your code doesn't seem to match the formula, e.g. you don't even calculate the reflection vector.

Share on other sites
Hmm that is odd...it does look different than this one here : http://en.wikibooks.org/wiki/GLSL_Programming/Unity/Brushed_Metal

Share on other sites
Ok, that version has simplified the formula a lot and seems to be correct... The only other difference is that they're replaced N.R with N.V, which I don't quite understand off the top of my head, but should give somewhat similar results..

If we assume for now that both of these are different implementation's of Ward's ideas, then maybe your problem is elsewhere... Are your tangent vectors valid? Does L point away from or towards the light? How are you making use of the result of your [font=courier new,courier,monospace]Ward[/font] function? What space are you doing your calculations in, and have all the variables been transformed into that space? Edited by Hodgman

Share on other sites
Did not try checking the tangent vector yet, but I was assuming they were correct as I input them from the vertex shader and multiply them by the World matrix.
Anyway here's the PS:
 float4 WardPS(PSI input) : COLOR0 { float4 output = float4(0, 0, 0, 1); // Normals float3 Normals = normalize(input.Normals); float3 Tangent = normalize(input.Tangent); float3 BiTangent = normalize(input.BiTangent); // View Direction float3 ViewDirection = normalize(input.ViewDirection); // Light Direction float3 LightDir = normalize(LightDirection); // Albedo Color float4 Albedo = tex2D(AlbedoSampler, input.UV); // Convert to Linear Color Space Albedo = ToLinear(Albedo); // Light float4 Light = Ward(Normals, LightDir, ViewDirection, Tangent, BiTangent); output = Albedo * float4(Light.rgb + Light.a, 1); // Convert back to sRGB Color Space output = ToSRGB(output); return output; }  Edited by lipsryme

output = Albedo * float4(Light.rgb + Light.a, 1);Instead you should use a different mask for the specular lighting, if you don't have a spec-map texture handy, try a constant value of somewhere between 0.05 and 0.2.
output = float4( Albedo.rgb * Light.rrr + SpecularMask.rgb * Light.aaa, 1);