# [D3D12] Issue pow HLSL function

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

## Recommended Posts

Hello guys,

I am having some issues with pow HLSL function. I hope you might shed some light on this :-)

In particular, I am doing Phong lighting and I have discovered that specular term is calculated incorrectly.
float3 specularColor = (NdotL * pow(RdotV, specularPower)) * specularAlbedo * lightColor;


I tried to decompose the equation into components and output them separately.

It got out that pow(RdotV, specularPower) returns different value based on how I pass specularPower argument.

For the output pow(RdotV, 0.0f), I get a white picture, which is 1.0f as expected.
However, if pass 0.0f in specularPower argument to pow(RdotV, specularPower), I get a different picture, with black bands in the back wall of Cornell Box.

specularPower = 0.0f; pow(RdotV, specularPower) will yield a different result compared to pow(RdotV, 0.0f).

Is there any precision loss depending on how you pass your data?

Thanks a bunch
Edited by _void_

##### Share on other sites

Which Shader Model are you using?

There was a problem in another thread where two apparently functionally equivalent shaders differing only by whether a variable was moved onto its own line gave different results. That particular problem seemed CS_5_1 specific and that there was no problem with CS_5_0. If you're using PS_5_1 can you try PS_5_0?

Are you compiling with or without /Od?

##### Share on other sites

I am using cs_5_0. The issue is reproducable on cs_5_1 as well. Removing D3DCOMPILE_SKIP_OPTIMIZATION flag did solve the problem.

Tx

##### Share on other sites

MJP's information is good.

There is one point that I'd assumed from the way the question was worded which I perhaps shouldn't have assumed. You said:

specularPower = 0.0f; pow(RdotV, specularPower) will yield a different result compared to pow(RdotV, 0.0f).

What I assumed that to mean is that you wrote something like this, and the result was different from just putting '0.0f' directly into the pow function.

float specularPower = 0.0f;
float someValue = pow(RdotV, specularPower);


I.e, specularPower was a hard-coded 0.0f in its own local variable rather than 0.0f coming through a value called 'specularPower' in a constant buffer. Which is it?

##### Share on other sites

Since the OP confirmed removing /Od fixed it, that makes it irrelevant whether the 0.0f came from a constant buffer or not (as it turns out).

Even a "known-at-compile-time" 0.0f in its own local variable will go the "log, mul, exp" route MJP highlighted. Only if the 0.0f is written directly into the second argument of pow will it evaluate to 1.0f when optimisations are disabled. With optimisations enabled, it doesn't matter whether the 0.0f came from a separate variable or if it was written directly inside the pow function.

##### Share on other sites

MJP, I guess, I should expose myself more to assembly code :-) Thank you guys for the explanation!

1. 1
2. 2
Rutin
24
3. 3
4. 4
JoeJ
16
5. 5

• 14
• 29
• 11
• 11
• 9
• ### Forum Statistics

• Total Topics
631773
• Total Posts
3002265
×