diff --git a/WickedEngine/shaders/brdf.hlsli b/WickedEngine/shaders/brdf.hlsli index b6b8bf17c..423ab513b 100644 --- a/WickedEngine/shaders/brdf.hlsli +++ b/WickedEngine/shaders/brdf.hlsli @@ -149,6 +149,7 @@ struct Surface uint layerMask; // the engine-side layer mask bool receiveshadow; float3 facenormal; // surface normal without normal map + bool is_frontface; // These will be computed when calling Update(): float roughnessBRDF; // roughness input for BRDF functions @@ -440,6 +441,10 @@ struct Surface N = n0 * w + n1 * u + n2 * v; N = mul((float3x3)inst.transformInverseTranspose.GetMatrix(), N); N = normalize(N); + if (is_frontface == false && !is_hairparticle && !is_emittedparticle) + { + N = -N; + } facenormal = N; [branch] diff --git a/WickedEngine/shaders/raytraceCS.hlsl b/WickedEngine/shaders/raytraceCS.hlsl index 67e39d9c9..4559aa554 100644 --- a/WickedEngine/shaders/raytraceCS.hlsl +++ b/WickedEngine/shaders/raytraceCS.hlsl @@ -99,6 +99,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) prim.instanceIndex = q.CommittedInstanceID(); prim.subsetIndex = q.CommittedGeometryIndex(); + surface.is_frontface = q.CommittedTriangleFrontFace(); surface.load(prim, q.CommittedTriangleBarycentrics()); #else diff --git a/WickedEngine/shaders/rtreflectionLIB.hlsl b/WickedEngine/shaders/rtreflectionLIB.hlsl index 3c52bc1cb..f56124090 100644 --- a/WickedEngine/shaders/rtreflectionLIB.hlsl +++ b/WickedEngine/shaders/rtreflectionLIB.hlsl @@ -112,6 +112,7 @@ void RTReflection_ClosestHit(inout RayPayload payload, in BuiltInTriangleInterse prim.subsetIndex = GeometryIndex(); Surface surface; + surface.is_frontface = (HitKind() == HIT_KIND_TRIANGLE_FRONT_FACE); surface.load(prim, attr.barycentrics); [branch] @@ -125,50 +126,57 @@ void RTReflection_ClosestHit(inout RayPayload payload, in BuiltInTriangleInterse surface.pixel = DispatchRaysIndex().xy; surface.screenUV = surface.pixel / (float2)DispatchRaysDimensions().xy; - // Light sampling: - surface.P = WorldRayOrigin() + WorldRayDirection() * RayTCurrent(); - surface.V = -WorldRayDirection(); - surface.update(); - - Lighting lighting; - lighting.create(0, 0, GetAmbient(surface.N), 0); - - [loop] - for (uint iterator = 0; iterator < g_xFrame.LightArrayCount; iterator++) + if (surface.material.IsUnlit()) { - ShaderEntity light = load_entity(g_xFrame.LightArrayOffset + iterator); - if ((light.layerMask & surface.material.layerMask) == 0) - continue; - - if (light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC) - { - continue; // static lights will be skipped (they are used in lightmap baking) - } - - switch (light.GetType()) - { - case ENTITY_TYPE_DIRECTIONALLIGHT: - { - DirectionalLight(light, surface, lighting); - } - break; - case ENTITY_TYPE_POINTLIGHT: - { - PointLight(light, surface, lighting); - } - break; - case ENTITY_TYPE_SPOTLIGHT: - { - SpotLight(light, surface, lighting); - } - break; - } + payload.data.xyz += surface.albedo + surface.emissiveColor; } + else + { + // Light sampling: + surface.P = WorldRayOrigin() + WorldRayDirection() * RayTCurrent(); + surface.V = -WorldRayDirection(); + surface.update(); - lighting.indirect.specular += max(0, EnvironmentReflection_Global(surface)); + Lighting lighting; + lighting.create(0, 0, GetAmbient(surface.N), 0); - LightingPart combined_lighting = CombineLighting(surface, lighting); - payload.data.xyz += surface.albedo * combined_lighting.diffuse + combined_lighting.specular + surface.emissiveColor; + [loop] + for (uint iterator = 0; iterator < g_xFrame.LightArrayCount; iterator++) + { + ShaderEntity light = load_entity(g_xFrame.LightArrayOffset + iterator); + if ((light.layerMask & surface.material.layerMask) == 0) + continue; + + if (light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC) + { + continue; // static lights will be skipped (they are used in lightmap baking) + } + + switch (light.GetType()) + { + case ENTITY_TYPE_DIRECTIONALLIGHT: + { + DirectionalLight(light, surface, lighting); + } + break; + case ENTITY_TYPE_POINTLIGHT: + { + PointLight(light, surface, lighting); + } + break; + case ENTITY_TYPE_SPOTLIGHT: + { + SpotLight(light, surface, lighting); + } + break; + } + } + + lighting.indirect.specular += max(0, EnvironmentReflection_Global(surface)); + + LightingPart combined_lighting = CombineLighting(surface, lighting); + payload.data.xyz += surface.albedo * combined_lighting.diffuse + combined_lighting.specular + surface.emissiveColor; + } payload.data.w = RayTCurrent(); } diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 393b8fb31..95ed0c768 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates, breaking compatibility changes const int minor = 58; // minor bug fixes, alterations, refactors, updates - const int revision = 2; + const int revision = 3; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);