diff --git a/Editor/LightWindow.cpp b/Editor/LightWindow.cpp index 367aa2d25..ae4ffe1ee 100644 --- a/Editor/LightWindow.cpp +++ b/Editor/LightWindow.cpp @@ -13,7 +13,7 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui) float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight(); lightWindow = new wiWindow(GUI, "Light Window"); - lightWindow->SetSize(XMFLOAT2(650, 500)); + lightWindow->SetSize(XMFLOAT2(650, 520)); //lightWindow->SetEnabled(false); GUI->AddWidget(lightWindow); @@ -158,6 +158,19 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui) haloCheckBox->SetTooltip("Visualize light source emission"); lightWindow->AddWidget(haloCheckBox); + staticCheckBox = new wiCheckBox("Static: "); + staticCheckBox->SetPos(XMFLOAT2(x, y += step)); + staticCheckBox->OnClick([&](wiEventArgs args) { + LightComponent* light = wiRenderer::GetScene().lights.GetComponent(entity); + if (light != nullptr) + { + light->SetStatic(args.bValue); + } + }); + staticCheckBox->SetEnabled(false); + staticCheckBox->SetTooltip("Static lights will only be used for baking into lightmaps."); + lightWindow->AddWidget(staticCheckBox); + addLightButton = new wiButton("Add Light"); addLightButton->SetPos(XMFLOAT2(x, y += step)); addLightButton->SetSize(XMFLOAT2(150, 30)); diff --git a/Editor/LightWindow.h b/Editor/LightWindow.h index 193f19bfe..0c1cb019e 100644 --- a/Editor/LightWindow.h +++ b/Editor/LightWindow.h @@ -33,6 +33,7 @@ public: wiCheckBox* shadowCheckBox; wiCheckBox* haloCheckBox; wiCheckBox* volumetricsCheckBox; + wiCheckBox* staticCheckBox; wiButton* addLightButton; wiColorPicker* colorPicker; wiComboBox* typeSelectorComboBox; diff --git a/Tests/Tests.cpp b/Tests/Tests.cpp index 7e9180ecc..0cd2c890b 100644 --- a/Tests/Tests.cpp +++ b/Tests/Tests.cpp @@ -111,6 +111,7 @@ TestsRenderer::TestsRenderer() testSelector->OnSelect([=](wiEventArgs args) { // Reset all state that tests might have modified: + wiRenderer::GetDevice()->SetVSyncEnabled(true); wiRenderer::SetToDrawGridHelper(false); wiRenderer::SetTemporalAAEnabled(false); wiRenderer::ClearWorld(); @@ -185,6 +186,7 @@ TestsRenderer::TestsRenderer() RunSpriteTest(); break; case 14: + wiRenderer::GetDevice()->SetVSyncEnabled(false); // turn off vsync if we can to accelerate the baking wiRenderer::SetTemporalAAEnabled(true); wiRenderer::LoadModel("../models/lightmap_bake_test.wiscene", XMMatrixTranslation(0, 0, 4)); break; diff --git a/WickedEngine/ShaderInterop.h b/WickedEngine/ShaderInterop.h index 12b259078..ac1567d6d 100644 --- a/WickedEngine/ShaderInterop.h +++ b/WickedEngine/ShaderInterop.h @@ -143,9 +143,11 @@ typedef XMINT4 int4; #define ENTITY_TYPE_FORCEFIELD_POINT 200 #define ENTITY_TYPE_FORCEFIELD_PLANE 201 +#define ENTITY_FLAG_LIGHT_STATIC 1 << 0 + struct ShaderEntityType { - uint type; + uint params; float3 positionVS; float range; float3 directionVS; @@ -159,6 +161,24 @@ struct ShaderEntityType int additionalData_index; float4 texMulAdd; + inline uint GetType() + { + return params & 0xFFFF; + } + inline uint GetFlags() + { + return (params >> 16) & 0xFFFF; + } + + inline void SetType(uint type) + { + params = type & 0xFFFF; // also initializes to zero, so flags must be set after the type + } + inline void SetFlags(uint flags) + { + params |= (flags & 0xFFFF) << 16; + } + // Load uncompressed color: inline float4 GetColor() { diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj b/WickedEngine/WickedEngine_SHADERS.vcxproj index 45f306ccf..86111caca 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj @@ -668,9 +668,13 @@ Pixel - + Pixel + + Pixel + 5.0 + Vertex diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters index f1114fa25..11d61f2bc 100644 --- a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters +++ b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters @@ -819,9 +819,6 @@ VS - - PS - CS @@ -840,6 +837,12 @@ PS + + PS + + + PS + diff --git a/WickedEngine/emittedparticle_simulateCS.hlsl b/WickedEngine/emittedparticle_simulateCS.hlsl index 7670fc923..93c30baca 100644 --- a/WickedEngine/emittedparticle_simulateCS.hlsl +++ b/WickedEngine/emittedparticle_simulateCS.hlsl @@ -38,7 +38,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) uint forceFieldID = g_xFrame_ForceFieldArrayOffset + Gid; ShaderEntityType forceField = EntityArray[forceFieldID]; - forceFields[Gid].type = (uint)forceField.type; + forceFields[Gid].type = (uint)forceField.GetType(); forceFields[Gid].position = forceField.positionWS; forceFields[Gid].gravity = forceField.energy; forceFields[Gid].range_inverse = forceField.range; diff --git a/WickedEngine/forceFieldVisualizerPS.hlsl b/WickedEngine/forceFieldVisualizerPS.hlsl index 9826e3088..92d66cc62 100644 --- a/WickedEngine/forceFieldVisualizerPS.hlsl +++ b/WickedEngine/forceFieldVisualizerPS.hlsl @@ -14,7 +14,7 @@ float4 main(PSIn input) : SV_TARGET float4 color = forceField.energy < 0 ? float4(0, 0, 1, 1) : float4(1, 0, 0, 1); - if (forceField.type == ENTITY_TYPE_FORCEFIELD_POINT) + if (forceField.GetType() == ENTITY_TYPE_FORCEFIELD_POINT) { // point-like forcefield: float3 centerToPos = normalize(input.pos3D.xyz - forceField.positionWS.xyz); diff --git a/WickedEngine/hairparticle_simulateCS.hlsl b/WickedEngine/hairparticle_simulateCS.hlsl index 2c3086439..ff7c5ee80 100644 --- a/WickedEngine/hairparticle_simulateCS.hlsl +++ b/WickedEngine/hairparticle_simulateCS.hlsl @@ -28,7 +28,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn uint forceFieldID = g_xFrame_ForceFieldArrayOffset + groupIndex; ShaderEntityType forceField = EntityArray[forceFieldID]; - forceFields[groupIndex].type = (uint)forceField.type; + forceFields[groupIndex].type = (uint)forceField.GetType(); forceFields[groupIndex].position = forceField.positionWS; forceFields[groupIndex].gravity = forceField.energy; forceFields[groupIndex].range_inverse = forceField.range; diff --git a/WickedEngine/lightCullingCS.hlsl b/WickedEngine/lightCullingCS.hlsl index 6224948b0..cf47306aa 100644 --- a/WickedEngine/lightCullingCS.hlsl +++ b/WickedEngine/lightCullingCS.hlsl @@ -284,7 +284,12 @@ void main(ComputeShaderInput IN) { ShaderEntityType entity = EntityArray[i]; - switch (entity.type) + if (entity.GetFlags() & ENTITY_FLAG_LIGHT_STATIC) + { + continue; // static lights will be skipped here (they are used at lightmap baking) + } + + switch (entity.GetType()) { case ENTITY_TYPE_POINTLIGHT: { @@ -360,7 +365,7 @@ void main(ComputeShaderInput IN) Sphere sphere = { entity.positionVS.xyz, entity.range }; if (SphereInsideFrustum(sphere, GroupFrustum, nearClipVS, maxDepthVS)) { - if (entity.type == ENTITY_TYPE_DECAL) + if (entity.GetType() == ENTITY_TYPE_DECAL) { InterlockedAdd(t_decalCount, 1); } @@ -386,7 +391,7 @@ void main(ComputeShaderInput IN) if (uDepthMask & ConstructEntityMask(minDepthVS, __depthRangeRecip, sphere)) #endif { - if (entity.type == ENTITY_TYPE_DECAL) + if (entity.GetType() == ENTITY_TYPE_DECAL) { InterlockedAdd(o_decalCount, 1); } @@ -529,7 +534,7 @@ void main(ComputeShaderInput IN) LightingResult result = (LightingResult)0; - switch (light.type) + switch (light.GetType()) { case ENTITY_TYPE_DIRECTIONALLIGHT: { diff --git a/WickedEngine/objectHF.hlsli b/WickedEngine/objectHF.hlsli index c580c8a41..fb994eb3e 100644 --- a/WickedEngine/objectHF.hlsli +++ b/WickedEngine/objectHF.hlsli @@ -205,9 +205,14 @@ inline void ForwardLighting(inout Surface surface, inout float3 diffuse, inout f { ShaderEntityType light = EntityArray[g_xFrame_LightArrayOffset + iterator]; + if (light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC) + { + continue; // static lights will be skipped (they are used in lightmap baking) + } + LightingResult result = (LightingResult)0; - switch (light.type) + switch (light.GetType()) { case ENTITY_TYPE_DIRECTIONALLIGHT: { @@ -357,9 +362,14 @@ inline void TiledLighting(in float2 pixel, inout Surface surface, inout float3 d { ShaderEntityType light = EntityArray[EntityIndexList[startOffset + iterator]]; + if (light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC) + { + continue; // static lights will be skipped (they are used in lightmap baking) + } + LightingResult result = (LightingResult)0; - switch (light.type) + switch (light.GetType()) { case ENTITY_TYPE_DIRECTIONALLIGHT: { diff --git a/WickedEngine/objectPS_voxelizer.hlsl b/WickedEngine/objectPS_voxelizer.hlsl index cbb9126b2..f2b81ce55 100644 --- a/WickedEngine/objectPS_voxelizer.hlsl +++ b/WickedEngine/objectPS_voxelizer.hlsl @@ -25,9 +25,14 @@ void main(float4 pos : SV_POSITION, float3 N : NORMAL, float2 tex : TEXCOORD, fl { ShaderEntityType light = EntityArray[i]; + if (light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC) + { + continue; // static lights will be skipped (they are used in lightmap baking) + } + LightingResult result = (LightingResult)0; - switch (light.type) + switch (light.GetType()) { case ENTITY_TYPE_DIRECTIONALLIGHT: { diff --git a/WickedEngine/raytrace_lightsamplingCS.hlsl b/WickedEngine/raytrace_lightsamplingCS.hlsl index 118a67eaf..cb776762d 100644 --- a/WickedEngine/raytrace_lightsamplingCS.hlsl +++ b/WickedEngine/raytrace_lightsamplingCS.hlsl @@ -74,7 +74,7 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) float3 L = 0; float dist = 0; - switch (light.type) + switch (light.GetType()) { case ENTITY_TYPE_DIRECTIONALLIGHT: { diff --git a/WickedEngine/renderlightmapPS_direct.hlsl b/WickedEngine/renderlightmapPS_direct.hlsl new file mode 100644 index 000000000..b932cebfd --- /dev/null +++ b/WickedEngine/renderlightmapPS_direct.hlsl @@ -0,0 +1,142 @@ +#define RAYTRACE_EXIT 128 // doing the path trace in pixel shader will hang the GPU for some reason if we don't set a cap on the trace loop... +#include "globals.hlsli" +#include "ShaderInterop_TracedRendering.h" +#include "tracedRenderingHF.hlsli" +#include "raySceneIntersectHF.hlsli" + +struct Input +{ + float4 pos : SV_POSITION; + float2 uv : TEXCOORD; + float3 pos3D : WORLDPOSITION; + float3 normal : NORMAL; +}; + +float4 main(Input input) : SV_TARGET +{ + float3 N = normalize(input.normal); + float2 uv = input.uv; + float seed = xTraceRandomSeed; + float3 P = input.pos3D; + float3 finalResult = 0; + + [loop] + for (uint iterator = 0; iterator < g_xFrame_LightArrayCount; iterator++) + { + ShaderEntityType light = EntityArray[g_xFrame_LightArrayOffset + iterator]; + + if (!(light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC)) + { + continue; // dynamic lights will not be baked into lightmap + } + + LightingResult result = (LightingResult)0; + + float3 L = 0; + float dist = 0; + + switch (light.GetType()) + { + case ENTITY_TYPE_DIRECTIONALLIGHT: + { + dist = INFINITE_RAYHIT; + + float3 lightColor = light.GetColor().rgb*light.energy; + + L = light.directionWS.xyz; + + result.diffuse = lightColor; + } + break; + case ENTITY_TYPE_POINTLIGHT: + { + L = light.positionWS - P; + const float dist2 = dot(L, L); + dist = sqrt(dist2); + + [branch] + if (dist < light.range) + { + L /= dist; + + const float3 lightColor = light.GetColor().rgb*light.energy; + + result.diffuse = lightColor; + + const float range2 = light.range * light.range; + const float att = saturate(1.0 - (dist2 / range2)); + const float attenuation = att * att; + + result.diffuse *= attenuation; + } + } + break; + case ENTITY_TYPE_SPOTLIGHT: + { + L = light.positionWS - P; + const float dist2 = dot(L, L); + dist = sqrt(dist2); + + [branch] + if (dist < light.range) + { + L /= dist; + + const float3 lightColor = light.GetColor().rgb*light.energy; + + const float SpotFactor = dot(L, light.directionWS); + const float spotCutOff = light.coneAngleCos; + + [branch] + if (SpotFactor > spotCutOff) + { + result.diffuse = lightColor; + + const float range2 = light.range * light.range; + const float att = saturate(1.0 - (dist2 / range2)); + float attenuation = att * att; + attenuation *= saturate((1.0 - (1.0 - SpotFactor) * 1.0 / (1.0 - spotCutOff))); + + result.diffuse *= attenuation; + } + } + } + break; + case ENTITY_TYPE_SPHERELIGHT: + { + } + break; + case ENTITY_TYPE_DISCLIGHT: + { + } + break; + case ENTITY_TYPE_RECTANGLELIGHT: + { + } + break; + case ENTITY_TYPE_TUBELIGHT: + { + } + break; + } + + float NdotL = saturate(dot(L, N)); + + if (NdotL > 0 && dist > 0) + { + result.diffuse = max(0.0f, result.diffuse); + + float3 sampling_offset = float3(rand(seed, uv), rand(seed, uv), rand(seed, uv)) * 2 - 1; + + Ray newRay; + newRay.origin = P; + newRay.direction = L + sampling_offset * 0.025f; + newRay.direction_inverse = rcp(newRay.direction); + newRay.energy = 0; + bool hit = TraceSceneANY(newRay, dist); + finalResult = (hit ? 0 : NdotL) * (result.diffuse); + } + } + + return max(0, float4(finalResult, xTraceUserData)); +} diff --git a/WickedEngine/renderlightmapPS.hlsl b/WickedEngine/renderlightmapPS_indirect.hlsl similarity index 96% rename from WickedEngine/renderlightmapPS.hlsl rename to WickedEngine/renderlightmapPS_indirect.hlsl index b50faab1c..c937c87f3 100644 --- a/WickedEngine/renderlightmapPS.hlsl +++ b/WickedEngine/renderlightmapPS_indirect.hlsl @@ -37,12 +37,17 @@ float4 main(Input input) : SV_TARGET { ShaderEntityType light = EntityArray[g_xFrame_LightArrayOffset + iterator]; + if (!(light.GetFlags() & ENTITY_FLAG_LIGHT_STATIC)) + { + continue; // dynamic lights will not be baked into lightmap + } + LightingResult result = (LightingResult)0; float3 L = 0; float dist = 0; - switch (light.type) + switch (light.GetType()) { case ENTITY_TYPE_DIRECTIONALLIGHT: { diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h index b8f77e899..1d86e8c0b 100644 --- a/WickedEngine/wiEnums.h +++ b/WickedEngine/wiEnums.h @@ -228,7 +228,8 @@ enum PSTYPES PSTYPE_VOXELIZER, PSTYPE_VOXEL, PSTYPE_FORCEFIELDVISUALIZER, - PSTYPE_RENDERLIGHTMAP, + PSTYPE_RENDERLIGHTMAP_INDIRECT, + PSTYPE_RENDERLIGHTMAP_DIRECT, PSTYPE_LAST }; // geometry shaders diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 27185bb98..c631b838c 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -125,7 +125,7 @@ struct VoxelizedSceneData int numCones = 8; float rayStepSize = 0.5f; bool secondaryBounceEnabled = true; - bool reflectionsEnabled = false; + bool reflectionsEnabled = true; bool centerChangedThisFrame = true; UINT mips = 7; } voxelSceneData; @@ -1110,7 +1110,8 @@ GraphicsPSO* PSO_lightvisualizer[LightComponent::LIGHTTYPE_COUNT] = {}; GraphicsPSO* PSO_volumetriclight[LightComponent::LIGHTTYPE_COUNT] = {}; GraphicsPSO* PSO_enviromentallight = nullptr; -GraphicsPSO* PSO_renderlightmap = nullptr; +GraphicsPSO* PSO_renderlightmap_indirect = nullptr; +GraphicsPSO* PSO_renderlightmap_direct = nullptr; enum SKYRENDERING { @@ -1967,7 +1968,8 @@ void LoadShaders() pixelShaders[PSTYPE_VOXELIZER] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "objectPS_voxelizer.cso", wiResourceManager::PIXELSHADER)); pixelShaders[PSTYPE_VOXEL] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "voxelPS.cso", wiResourceManager::PIXELSHADER)); pixelShaders[PSTYPE_FORCEFIELDVISUALIZER] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "forceFieldVisualizerPS.cso", wiResourceManager::PIXELSHADER)); - pixelShaders[PSTYPE_RENDERLIGHTMAP] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "renderlightmapPS.cso", wiResourceManager::PIXELSHADER)); + pixelShaders[PSTYPE_RENDERLIGHTMAP_INDIRECT] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "renderlightmapPS_indirect.cso", wiResourceManager::PIXELSHADER)); + pixelShaders[PSTYPE_RENDERLIGHTMAP_DIRECT] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "renderlightmapPS_direct.cso", wiResourceManager::PIXELSHADER)); geometryShaders[GSTYPE_ENVMAP] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "envMapGS.cso", wiResourceManager::GEOMETRYSHADER)); geometryShaders[GSTYPE_ENVMAP_SKY] = static_cast(wiResourceManager::GetShaderManager().add(SHADERPATH + "envMap_skyGS.cso", wiResourceManager::GEOMETRYSHADER)); @@ -2570,7 +2572,7 @@ void LoadShaders() GraphicsPSODesc desc; desc.il = vertexLayouts[VLTYPE_RENDERLIGHTMAP]; desc.vs = vertexShaders[VSTYPE_RENDERLIGHTMAP]; - desc.ps = pixelShaders[PSTYPE_RENDERLIGHTMAP]; + desc.ps = pixelShaders[PSTYPE_RENDERLIGHTMAP_INDIRECT]; desc.rs = rasterizers[RSTYPE_DOUBLESIDED]; desc.bs = blendStates[BSTYPE_TRANSPARENT]; desc.dss = depthStencils[DSSTYPE_XRAY]; @@ -2579,8 +2581,24 @@ void LoadShaders() desc.RTFormats[0] = RTFormat_lightmap_object; desc.DSFormat = FORMAT_UNKNOWN; - RECREATE(PSO_renderlightmap); - device->CreateGraphicsPSO(&desc, PSO_renderlightmap); + RECREATE(PSO_renderlightmap_indirect); + device->CreateGraphicsPSO(&desc, PSO_renderlightmap_indirect); + } + { + GraphicsPSODesc desc; + desc.il = vertexLayouts[VLTYPE_RENDERLIGHTMAP]; + desc.vs = vertexShaders[VSTYPE_RENDERLIGHTMAP]; + desc.ps = pixelShaders[PSTYPE_RENDERLIGHTMAP_DIRECT]; + desc.rs = rasterizers[RSTYPE_DOUBLESIDED]; + desc.bs = blendStates[BSTYPE_TRANSPARENT]; + desc.dss = depthStencils[DSSTYPE_XRAY]; + + desc.numRTs = 1; + desc.RTFormats[0] = RTFormat_lightmap_object; + desc.DSFormat = FORMAT_UNKNOWN; + + RECREATE(PSO_renderlightmap_direct); + device->CreateGraphicsPSO(&desc, PSO_renderlightmap_direct); } for (int type = 0; type < SKYRENDERING_COUNT; ++type) { @@ -3731,7 +3749,7 @@ void UpdateRenderData(GRAPHICSTHREAD threadID) const int shadowIndex = light.shadowMap_index; - entityArray[entityCounter].type = light.GetType(); + entityArray[entityCounter].SetType(light.GetType()); entityArray[entityCounter].positionWS = light.position; XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformCoord(XMLoadFloat3(&entityArray[entityCounter].positionWS), viewMatrix)); entityArray[entityCounter].range = light.range; @@ -3792,6 +3810,11 @@ void UpdateRenderData(GRAPHICSTHREAD threadID) break; } + if (light.IsStatic()) + { + entityArray[entityCounter].SetFlags(ENTITY_FLAG_LIGHT_STATIC); + } + entityCounter++; } entityArrayCount_Lights = entityCounter - entityArrayOffset_Lights; @@ -3818,7 +3841,7 @@ void UpdateRenderData(GRAPHICSTHREAD threadID) continue; } - entityArray[entityCounter].type = ENTITY_TYPE_ENVMAP; + entityArray[entityCounter].SetType(ENTITY_TYPE_ENVMAP); entityArray[entityCounter].positionWS = probe.position; XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformCoord(XMLoadFloat3(&probe.position), viewMatrix)); entityArray[entityCounter].range = probe.range; @@ -3849,7 +3872,7 @@ void UpdateRenderData(GRAPHICSTHREAD threadID) } const DecalComponent& decal = scene.decals[decalIndex]; - entityArray[entityCounter].type = ENTITY_TYPE_DECAL; + entityArray[entityCounter].SetType(ENTITY_TYPE_DECAL); entityArray[entityCounter].positionWS = decal.position; XMStoreFloat3(&entityArray[entityCounter].positionVS, XMVector3TransformCoord(XMLoadFloat3(&decal.position), viewMatrix)); entityArray[entityCounter].range = decal.range; @@ -3877,7 +3900,7 @@ void UpdateRenderData(GRAPHICSTHREAD threadID) const ForceFieldComponent& force = scene.forces[i]; - entityArray[entityCounter].type = force.type; + entityArray[entityCounter].SetType(force.type); entityArray[entityCounter].positionWS = force.position; entityArray[entityCounter].energy = force.gravity; entityArray[entityCounter].range = 1.0f / max(0.0001f, force.range); // avoid division in shader @@ -4330,7 +4353,7 @@ void DrawLights(const CameraComponent& camera, GRAPHICSTHREAD threadID) for (uint32_t lightIndex : culling.culledLights) { const LightComponent& light = scene.lights[lightIndex]; - if (light.GetType() != type) + if (light.GetType() != type || light.IsStatic()) continue; switch (type) @@ -4774,7 +4797,7 @@ void DrawForShadowMap(const CameraComponent& camera, GRAPHICSTHREAD threadID, ui for (uint32_t lightIndex : culling.culledLights) { const LightComponent& light = scene.lights[lightIndex]; - if (light.GetType() != type || !light.IsCastingShadow()) + if (light.GetType() != type || !light.IsCastingShadow() || light.IsStatic()) { continue; } @@ -7619,8 +7642,6 @@ void RenderObjectLightMap(ObjectComponent& object, bool updateBVHAndScene, GRAPH instance->Create(transform.world); device->InvalidateBufferAccess(&dynamicVertexBufferPools[threadID], threadID); - device->BindGraphicsPSO(PSO_renderlightmap, threadID); - GPUBuffer* vbs[] = { mesh.vertexBuffer_POS.get(), mesh.vertexBuffer_ATL.get(), @@ -7651,6 +7672,12 @@ void RenderObjectLightMap(ObjectComponent& object, bool updateBVHAndScene, GRAPH device->BindConstantBuffer(VS, constantBuffers[CBTYPE_RAYTRACE], CB_GETBINDSLOT(TracedRenderingCB), threadID); device->BindConstantBuffer(PS, constantBuffers[CBTYPE_RAYTRACE], CB_GETBINDSLOT(TracedRenderingCB), threadID); + // Render direct lighting part: + device->BindGraphicsPSO(PSO_renderlightmap_direct, threadID); + device->DrawIndexedInstanced((int)mesh.indices.size(), 1, 0, 0, 0, threadID); + + // Render indirect lighting part: + device->BindGraphicsPSO(PSO_renderlightmap_indirect, threadID); device->DrawIndexedInstanced((int)mesh.indices.size(), 1, 0, 0, 0, threadID); object.lightmapIterationCount++; diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h index 6c8cb5d34..be6fc5a7b 100644 --- a/WickedEngine/wiSceneSystem.h +++ b/WickedEngine/wiSceneSystem.h @@ -581,6 +581,7 @@ namespace wiSceneSystem CAST_SHADOW = 1 << 0, VOLUMETRICS = 1 << 1, VISUALIZER = 1 << 2, + LIGHTMAPONLY_STATIC = 1 << 3, }; uint32_t _flags = EMPTY; XMFLOAT3 color = XMFLOAT3(1, 1, 1); @@ -622,10 +623,12 @@ namespace wiSceneSystem inline void SetCastShadow(bool value) { if (value) { _flags |= CAST_SHADOW; } else { _flags &= ~CAST_SHADOW; } } inline void SetVolumetricsEnabled(bool value) { if (value) { _flags |= VOLUMETRICS; } else { _flags &= ~VOLUMETRICS; } } inline void SetVisualizerEnabled(bool value) { if (value) { _flags |= VISUALIZER; } else { _flags &= ~VISUALIZER; } } + inline void SetStatic(bool value) { if (value) { _flags |= LIGHTMAPONLY_STATIC; } else { _flags &= ~LIGHTMAPONLY_STATIC; } } inline bool IsCastingShadow() const { return _flags & CAST_SHADOW; } inline bool IsVolumetricsEnabled() const { return _flags & VOLUMETRICS; } inline bool IsVisualizerEnabled() const { return _flags & VISUALIZER; } + inline bool IsStatic() const { return _flags & LIGHTMAPONLY_STATIC; } inline float GetRange() const { return range; } diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index a3f690872..f923c4475 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 24; // minor bug fixes, alterations, refactors, updates - const int revision = 15; + const int revision = 16; long GetVersion() diff --git a/features.txt b/features.txt index beb47f771..499467241 100644 --- a/features.txt +++ b/features.txt @@ -82,3 +82,5 @@ Volumetric light scattering Smooth Particle Hydrodynamics (SPH) Fluid Simulation GPU Path Tracing Entity-Component System +Lightmaps +Lightmap baking with GPU Path Trace diff --git a/models/lightmap_bake_test.wiscene b/models/lightmap_bake_test.wiscene index 08c03cc9e..c2d96a68d 100644 Binary files a/models/lightmap_bake_test.wiscene and b/models/lightmap_bake_test.wiscene differ