guycalledfrank / bakery-issues

Bug tracker for Bakery
4 stars 0 forks source link

volume highlight ignore AO #70

Closed laurentopia closed 3 years ago

laurentopia commented 3 years ago

dark AO should dim the highlight as it represents cavity

but it doesn't:

with AO image no AO image black AO image it seems that AO only affects the diffuse component

laurentopia commented 3 years ago

alright, fixed image

you should add that to your repo, i can't be bothered doing a push, don't even know how

image

`void BakeryVolumeSpec_float(float3 posWorld, float3 normalWorld, float3 viewDir, float smoothness, float3 albedo, float metalness, float occlusion, out float3 diffuseSH, out float3 specularSH) { bool isGlobal = dot(abs(_VolumeInvSize),1) == 0; float3 lpUV = (posWorld - (isGlobal ? _GlobalVolumeMin : _VolumeMin)) * (isGlobal ? _GlobalVolumeInvSize : _VolumeInvSize);

float4 tex0, tex1, tex2;
float3 L0, L1x, L1y, L1z;
tex0 = _Volume0.Sample(sampler_Volume0, lpUV);
tex1 = _Volume1.Sample(sampler_Volume0, lpUV);
tex2 = _Volume2.Sample(sampler_Volume0, lpUV);
L0 = tex0.xyz;
L1x = tex1.xyz;
L1y = tex2.xyz;
L1z = float3(tex0.w, tex1.w, tex2.w);
diffuseSH.r = shEvaluateDiffuseL1Geomerics(L0.r, float3(L1x.r, L1y.r, L1z.r), normalWorld);
diffuseSH.g = shEvaluateDiffuseL1Geomerics(L0.g, float3(L1x.g, L1y.g, L1z.g), normalWorld);
diffuseSH.b = shEvaluateDiffuseL1Geomerics(L0.b, float3(L1x.b, L1y.b, L1z.b), normalWorld);
diffuseSH = max(diffuseSH, 0);

const float3 lumaConv = float3(0.2125f, 0.7154f, 0.0721f);

float3 nL1x = L1x / L0;
float3 nL1y = L1y / L0;
float3 nL1z = L1z / L0;
float3 dominantDir = float3(dot(nL1x, lumaConv), dot(nL1y, lumaConv), dot(nL1z, lumaConv));
float3 halfDir = normalize(normalize(dominantDir) - -viewDir);
float nh = saturate(dot(normalWorld, halfDir));
float perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness);
float roughness = BakeryPerceptualRoughnessToRoughness(perceptualRoughness);
float spec = GGXTerm(nh, roughness);

specularSH = L0 + dominantDir.x * L1x + dominantDir.y * L1y + dominantDir.z * L1z;

specularSH = max(spec * specularSH, 0.0);

// Convert metalness to specular and "oneMinusReflectivity"
float3 specularColor = lerp(float3(0.04, 0.04, 0.04), albedo, metalness);
float oneMinusDielectricSpec = 1.0 - 0.04;
float oneMinusReflectivity = oneMinusDielectricSpec - metalness * oneMinusDielectricSpec;

// Directly apply fresnel and smoothness-dependent grazing term
float nv = 1.0f - saturate(dot(normalWorld, viewDir));
float nv2 = nv * nv;
float fresnel = nv * nv2 * nv2;

float reflectivity = max(max(specularColor.r, specularColor.g), specularColor.b); // hack, but consistent with Unity code
float grazingTerm = saturate(smoothness + reflectivity);
float3 fresnel3 = lerp(specularColor, float3(grazingTerm, grazingTerm, grazingTerm), fresnel);

diffuseSH *= oneMinusReflectivity; // no baked GI override: modify diffuse
specularSH *= fresnel3;
specularSH *= occlusion;

diffuseSH = max(diffuseSH, 0);
specularSH = max(specularSH, 0);

}`

guycalledfrank commented 3 years ago

At first I thought you mean that Bakery's AO doesn't bake into voxels, but seems like you actually mean material's AO not darkening the highlight?

The logic here is a bit tricky: you can have both direct and indirect (ambient) lighting and specular present in the volume. Indirect should be occluded, that's true. But it's technically incorrect to occlude direct specular with AO, because it should be occluded by shadows with proper direction. When you don't have proper shadows it might sometimes look OK when occluded with AO as well, but it's an arbitrary decision that may not look good in every scenario.

Vertex AO: is it specific to your game? Is using vertex AO common in built-in URP shaders?

laurentopia commented 3 years ago

I agree it's an approximation which works well on dynamic objects in scenes with no realtime shadow, it works really well when the lightsource is outside cavities but if a light baked inside a hole then not so much. Yes AO vertices is unique to my game so you can ignore, I only wanted to show you how i connect the new occlusion input.