new feature: volumetric light scattering
This commit is contained in:
@@ -121,6 +121,18 @@ LightWindow::LightWindow(wiGUI* gui) : GUI(gui), light(nullptr)
|
||||
shadowCheckBox->SetTooltip("Set light as shadow caster. Many shadow casters can affect performance!");
|
||||
lightWindow->AddWidget(shadowCheckBox);
|
||||
|
||||
volumetricsCheckBox = new wiCheckBox("Volumetric Scattering: ");
|
||||
volumetricsCheckBox->SetPos(XMFLOAT2(x, y += step));
|
||||
volumetricsCheckBox->OnClick([&](wiEventArgs args) {
|
||||
if (light != nullptr)
|
||||
{
|
||||
light->volumetrics = args.bValue;
|
||||
}
|
||||
});
|
||||
volumetricsCheckBox->SetEnabled(false);
|
||||
volumetricsCheckBox->SetTooltip("Compute volumetric light scattering effect. The scattering is modulated by fog settings!");
|
||||
lightWindow->AddWidget(volumetricsCheckBox);
|
||||
|
||||
haloCheckBox = new wiCheckBox("Visualizer: ");
|
||||
haloCheckBox->SetPos(XMFLOAT2(x, y += step));
|
||||
haloCheckBox->OnClick([&](wiEventArgs args) {
|
||||
@@ -217,6 +229,8 @@ void LightWindow::SetLight(Light* light)
|
||||
shadowCheckBox->SetCheck(light->shadow);
|
||||
haloCheckBox->SetEnabled(true);
|
||||
haloCheckBox->SetCheck(!light->noHalo);
|
||||
volumetricsCheckBox->SetEnabled(true);
|
||||
volumetricsCheckBox->SetCheck(light->volumetrics);
|
||||
colorPicker->SetEnabled(true);
|
||||
typeSelectorComboBox->SetEnabled(true);
|
||||
typeSelectorComboBox->SetSelected((int)light->GetType());
|
||||
@@ -233,6 +247,7 @@ void LightWindow::SetLight(Light* light)
|
||||
biasSlider->SetEnabled(false);
|
||||
shadowCheckBox->SetEnabled(false);
|
||||
haloCheckBox->SetEnabled(false);
|
||||
volumetricsCheckBox->SetEnabled(false);
|
||||
energySlider->SetEnabled(false);
|
||||
colorPicker->SetEnabled(false);
|
||||
typeSelectorComboBox->SetEnabled(false);
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
wiSlider* biasSlider;
|
||||
wiCheckBox* shadowCheckBox;
|
||||
wiCheckBox* haloCheckBox;
|
||||
wiCheckBox* volumetricsCheckBox;
|
||||
wiButton* addLightButton;
|
||||
wiColorPicker* colorPicker;
|
||||
wiComboBox* typeSelectorComboBox;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
This file contains changelog of wiArchive versions
|
||||
|
||||
17: serialized light scattering property
|
||||
16: environment probes are now serialized into Model
|
||||
15: removed redundant matrix store from hair paticle serializator
|
||||
14: serialize emitter property: shaderType
|
||||
|
||||
@@ -29,6 +29,7 @@ wiRenderTarget
|
||||
, Renderable3DComponent::rtWaterRipple
|
||||
, Renderable3DComponent::rtLinearDepth
|
||||
, Renderable3DComponent::rtParticle
|
||||
, Renderable3DComponent::rtVolumetricLights
|
||||
, Renderable3DComponent::rtFinal[2]
|
||||
, Renderable3DComponent::rtDof[3]
|
||||
, Renderable3DComponent::rtTemporalAA[2]
|
||||
@@ -72,6 +73,9 @@ void Renderable3DComponent::ResizeBuffers()
|
||||
rtParticle.Initialize(
|
||||
(UINT)(wiRenderer::GetInternalResolution().x*getParticleDownSample()), (UINT)(wiRenderer::GetInternalResolution().y*getParticleDownSample())
|
||||
, false, wiRenderer::RTFormat_hdr);
|
||||
rtVolumetricLights.Initialize(
|
||||
(UINT)(wiRenderer::GetInternalResolution().x*0.25f), (UINT)(wiRenderer::GetInternalResolution().y*0.25f)
|
||||
, false, wiRenderer::RTFormat_hdr);
|
||||
rtWaterRipple.Initialize(
|
||||
wiRenderer::GetInternalResolution().x, wiRenderer::GetInternalResolution().y
|
||||
, false, wiRenderer::RTFormat_waterripple);
|
||||
@@ -373,6 +377,12 @@ void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRende
|
||||
wiRenderer::GetDevice()->EventEnd(threadID);
|
||||
}
|
||||
|
||||
if (getVolumeLightsEnabled())
|
||||
{
|
||||
rtVolumetricLights.Activate(threadID, 0, 0, 0, 0);
|
||||
wiRenderer::DrawVolumeLights(wiRenderer::getCamera(), threadID);
|
||||
}
|
||||
|
||||
if (getEmittedParticlesEnabled())
|
||||
{
|
||||
rtParticle.Activate(threadID, 0, 0, 0, 0);
|
||||
@@ -402,10 +412,7 @@ void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRende
|
||||
RenderTransparentScene(rtSceneCopy, threadID);
|
||||
|
||||
wiRenderer::DrawTrails(threadID, rtSceneCopy.GetTexture());
|
||||
if (getVolumeLightsEnabled())
|
||||
{
|
||||
wiRenderer::DrawVolumeLights(wiRenderer::getCamera(), threadID);
|
||||
}
|
||||
wiRenderer::DrawLightVisualizers(wiRenderer::getCamera(), threadID);
|
||||
|
||||
fx.presentFullScreen = true;
|
||||
|
||||
@@ -416,6 +423,13 @@ void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRende
|
||||
wiRenderer::GetDevice()->EventEnd(threadID);
|
||||
}
|
||||
|
||||
if (getVolumeLightsEnabled())
|
||||
{
|
||||
wiRenderer::GetDevice()->EventBegin("Contribute Volumetric Lights", threadID);
|
||||
wiImage::Draw(rtVolumetricLights.GetTexture(), fx, threadID);
|
||||
wiRenderer::GetDevice()->EventEnd(threadID);
|
||||
}
|
||||
|
||||
if (getLightShaftsEnabled()) {
|
||||
wiRenderer::GetDevice()->EventBegin("Contribute LightShafts", threadID);
|
||||
fx.blendFlag = BLENDMODE_ADDITIVE;
|
||||
|
||||
@@ -56,6 +56,7 @@ protected:
|
||||
, rtWaterRipple
|
||||
, rtLinearDepth
|
||||
, rtParticle
|
||||
, rtVolumetricLights
|
||||
, rtFinal[2]
|
||||
, rtDof[3]
|
||||
, rtTemporalAA[2]
|
||||
|
||||
@@ -612,7 +612,16 @@
|
||||
<FxCompile Include="verticalBlurPS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="volumeLightPS.hlsl">
|
||||
<FxCompile Include="lightVisualizerPS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="volumetricLight_DirectionalPS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="volumetricLight_PointPS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="volumetricLight_SpotPS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="voxelClearOnlyNormalCS.hlsl">
|
||||
|
||||
@@ -240,9 +240,6 @@
|
||||
<FxCompile Include="verticalBlurPS.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="volumeLightPS.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="fxaa.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
@@ -693,6 +690,18 @@
|
||||
<FxCompile Include="objectPS_hologram.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="lightVisualizerPS.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="volumetricLight_PointPS.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="volumetricLight_SpotPS.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="volumetricLight_DirectionalPS.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="PS">
|
||||
|
||||
@@ -26,7 +26,7 @@ struct LightOutputType
|
||||
#define DEFERREDLIGHT_MAKEPARAMS \
|
||||
ShaderEntityType light = EntityArray[PSIn.lightIndex]; \
|
||||
float3 diffuse, specular; \
|
||||
float2 ScreenCoord = float2(1, -1) * PSIn.pos2D.xy / PSIn.pos2D.w * 0.5f + 0.5f; \
|
||||
float2 ScreenCoord = PSIn.pos2D.xy / PSIn.pos2D.w * float2(0.5f, -0.5f) + 0.5f; \
|
||||
float depth = texture_depth[PSIn.pos.xy]; \
|
||||
float4 baseColor = texture_gbuffer0[PSIn.pos.xy]; \
|
||||
float4 g1 = texture_gbuffer1[PSIn.pos.xy]; \
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "volumeLightHF.hlsli"
|
||||
|
||||
float4 main(VertexToPixel PSIn) : SV_TARGET
|
||||
{
|
||||
return max(PSIn.col,0);
|
||||
}
|
||||
@@ -40,7 +40,7 @@ void main(float4 pos : SV_POSITION, float3 N : NORMAL, float2 tex : TEXCOORD, fl
|
||||
{
|
||||
float4 ShPos = mul(float4(P, 1), MatrixArray[light.additionalData_index + 0]);
|
||||
ShPos.xyz /= ShPos.w;
|
||||
float3 ShTex = ShPos.xyz*float3(1, -1, 1) / 2.0f + 0.5f;
|
||||
float3 ShTex = ShPos.xyz * float3(0.5f, -0.5f, 0.5f) + 0.5f;
|
||||
|
||||
[branch]if ((saturate(ShTex.x) == ShTex.x) && (saturate(ShTex.y) == ShTex.y) && (saturate(ShTex.z) == ShTex.z))
|
||||
{
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "volumeLightHF.hlsli"
|
||||
//#include "depthConvertHF.hlsli"
|
||||
//#include "effectHF_PS.hlsli"
|
||||
//#include "fogHF.hlsli"
|
||||
|
||||
float4 main(VertexToPixel PSIn) : SV_TARGET
|
||||
{
|
||||
//float4 color = PSIn.col;
|
||||
//color.rgb = applyFog(color.rgb,xHorizon,getFog(getLinearDepth(PSIn.pos2D.z/PSIn.pos2D.w),xFogSEH));
|
||||
return max(PSIn.col,0);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "deferredLightHF.hlsli"
|
||||
#include "fogHF.hlsli"
|
||||
|
||||
float4 main(VertexToPixel input) : SV_TARGET
|
||||
{
|
||||
ShaderEntityType light = EntityArray[(uint)g_xColor.x];
|
||||
|
||||
if (light.additionalData_index < 0)
|
||||
{
|
||||
// Dirlight volume has no meaning without shadows!!
|
||||
return 0;
|
||||
}
|
||||
|
||||
float2 ScreenCoord = input.pos2D.xy / input.pos2D.w * float2(0.5f, -0.5f) + 0.5f;
|
||||
float depth = max(input.pos.z, texture_depth.SampleLevel(sampler_linear_clamp, ScreenCoord, 0));
|
||||
float3 P = getPosition(ScreenCoord, depth);
|
||||
float3 V = g_xCamera_CamPos - P;
|
||||
float cameraDistance = length(V);
|
||||
V /= cameraDistance;
|
||||
|
||||
float marchedDistance = 0;
|
||||
float3 accumulation = 0;
|
||||
|
||||
const float3 L = light.directionWS;
|
||||
|
||||
// Perform ray marching to integrate light volume along view ray:
|
||||
float sum = 0;
|
||||
while (marchedDistance < cameraDistance)
|
||||
{
|
||||
float3 attenuation = 1;
|
||||
|
||||
float4 ShPos = mul(float4(P, 1), MatrixArray[light.additionalData_index + 0]);
|
||||
ShPos.xyz /= ShPos.w;
|
||||
float3 ShTex = ShPos.xyz * float3(0.5f, -0.5f, 0.5f) + 0.5f;
|
||||
|
||||
[branch]if ((saturate(ShTex.x) == ShTex.x) && (saturate(ShTex.y) == ShTex.y) && (saturate(ShTex.z) == ShTex.z))
|
||||
{
|
||||
attenuation *= shadowCascade(ShPos, ShTex.xy, light.shadowKernel, light.shadowBias, light.additionalData_index + 0);
|
||||
}
|
||||
|
||||
attenuation *= GetFog(cameraDistance - marchedDistance);
|
||||
|
||||
accumulation += attenuation;
|
||||
|
||||
const float stepSize = 0.5f;
|
||||
marchedDistance += stepSize;
|
||||
P = P + V * stepSize;
|
||||
|
||||
sum += 1.0f;
|
||||
}
|
||||
|
||||
accumulation /= sum;
|
||||
|
||||
return max(0, float4(accumulation * light.GetColor().rgb * light.energy, 1));
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "deferredLightHF.hlsli"
|
||||
#include "fogHF.hlsli"
|
||||
|
||||
float4 main(VertexToPixel input) : SV_TARGET
|
||||
{
|
||||
ShaderEntityType light = EntityArray[(uint)g_xColor.x];
|
||||
|
||||
float2 ScreenCoord = input.pos2D.xy / input.pos2D.w * float2(0.5f, -0.5f) + 0.5f;
|
||||
float depth = max(input.pos.z, texture_depth.SampleLevel(sampler_linear_clamp, ScreenCoord, 0));
|
||||
float3 P = getPosition(ScreenCoord, depth);
|
||||
float3 V = g_xCamera_CamPos - P;
|
||||
float cameraDistance = length(V);
|
||||
V /= cameraDistance;
|
||||
|
||||
float marchedDistance = 0;
|
||||
float accumulation = 0;
|
||||
|
||||
float3 L = light.positionWS - P;
|
||||
float dist = length(L);
|
||||
L /= dist;
|
||||
|
||||
// reposition ray start to be inside light all times:
|
||||
dist = min(dist, light.range);
|
||||
P = light.positionWS - L * dist;
|
||||
|
||||
// Perform ray marching to integrate light volume along view ray:
|
||||
float sum = 0;
|
||||
while (dist <= light.range && marchedDistance < cameraDistance)
|
||||
{
|
||||
float att = (light.energy * (light.range / (light.range + 1 + dist)));
|
||||
float attenuation = (att * (light.range - dist) / light.range);
|
||||
|
||||
[branch]
|
||||
if (light.additionalData_index >= 0) {
|
||||
attenuation *= texture_shadowarray_cube.SampleCmpLevelZero(sampler_cmp_depth, float4(-L, light.additionalData_index), 1 - dist / light.range * (1 - light.shadowBias)).r;
|
||||
}
|
||||
|
||||
attenuation *= GetFog(cameraDistance - marchedDistance);
|
||||
|
||||
accumulation += attenuation;
|
||||
|
||||
const float stepSize = 0.1f;
|
||||
marchedDistance += stepSize;
|
||||
P = P + V * stepSize;
|
||||
L = light.positionWS - P;
|
||||
dist = length(L);
|
||||
L /= dist;
|
||||
|
||||
sum += 1.0f;
|
||||
}
|
||||
|
||||
accumulation /= sum;
|
||||
|
||||
return max(0, float4(accumulation.xxx * light.GetColor().rgb * light.energy, 1));
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "deferredLightHF.hlsli"
|
||||
#include "fogHF.hlsli"
|
||||
|
||||
float4 main(VertexToPixel input) : SV_TARGET
|
||||
{
|
||||
ShaderEntityType light = EntityArray[(uint)g_xColor.x];
|
||||
|
||||
float2 ScreenCoord = input.pos2D.xy / input.pos2D.w * float2(0.5f, -0.5f) + 0.5f;
|
||||
float depth = max(input.pos.z, texture_depth.SampleLevel(sampler_linear_clamp, ScreenCoord, 0));
|
||||
float3 P = getPosition(ScreenCoord, depth);
|
||||
float3 V = g_xCamera_CamPos - P;
|
||||
float cameraDistance = length(V);
|
||||
V /= cameraDistance;
|
||||
|
||||
float marchedDistance = 0;
|
||||
float3 accumulation = 0;
|
||||
|
||||
float3 L = light.positionWS - P;
|
||||
float dist = length(L);
|
||||
L /= dist;
|
||||
|
||||
// Perform ray marching to integrate light volume along view ray:
|
||||
float sum = 0;
|
||||
while (dist <= light.range && marchedDistance < cameraDistance)
|
||||
{
|
||||
float SpotFactor = dot(L, light.directionWS);
|
||||
float spotCutOff = light.coneAngleCos;
|
||||
|
||||
[branch]
|
||||
if (SpotFactor > spotCutOff)
|
||||
{
|
||||
float att = (light.energy * (light.range / (light.range + 1 + dist)));
|
||||
float3 attenuation = (att * (light.range - dist) / light.range);
|
||||
attenuation *= saturate((1.0 - (1.0 - SpotFactor) * 1.0 / (1.0 - spotCutOff)));
|
||||
|
||||
[branch]
|
||||
if (light.additionalData_index >= 0)
|
||||
{
|
||||
float4 ShPos = mul(float4(P, 1), MatrixArray[light.additionalData_index + 0]);
|
||||
ShPos.xyz /= ShPos.w;
|
||||
float2 ShTex = ShPos.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);
|
||||
[branch]
|
||||
if ((saturate(ShTex.x) == ShTex.x) && (saturate(ShTex.y) == ShTex.y))
|
||||
{
|
||||
attenuation *= shadowCascade(ShPos, ShTex.xy, light.shadowKernel, light.shadowBias, light.additionalData_index);
|
||||
}
|
||||
}
|
||||
|
||||
attenuation *= GetFog(distance(P, g_xCamera_CamPos));
|
||||
|
||||
accumulation += attenuation;
|
||||
}
|
||||
|
||||
const float stepSize = 0.1f;
|
||||
marchedDistance += stepSize;
|
||||
P = P + V * stepSize;
|
||||
L = light.positionWS - P;
|
||||
dist = length(L);
|
||||
L /= dist;
|
||||
|
||||
sum += 1.0f;
|
||||
}
|
||||
|
||||
accumulation /= sum;
|
||||
|
||||
return max(0, float4(accumulation * light.GetColor().rgb * light.energy, 1));
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
using namespace std;
|
||||
|
||||
// this should always be only INCREMENTED and only if a new serialization is implemeted somewhere!
|
||||
uint64_t __archiveVersion = 16;
|
||||
uint64_t __archiveVersion = 17;
|
||||
// this is the version number of which below the archive is not compatible with the current version
|
||||
uint64_t __archiveVersionBarrier = 1;
|
||||
|
||||
|
||||
+10
-7
@@ -127,12 +127,12 @@ enum VSTYPES
|
||||
VSTYPE_DIRLIGHT,
|
||||
VSTYPE_POINTLIGHT,
|
||||
VSTYPE_SPOTLIGHT,
|
||||
VSTYPE_VOLUMESPOTLIGHT,
|
||||
VSTYPE_VOLUMEPOINTLIGHT,
|
||||
VSTYPE_VOLUMESPHERELIGHT,
|
||||
VSTYPE_VOLUMEDISCLIGHT,
|
||||
VSTYPE_VOLUMERECTANGLELIGHT,
|
||||
VSTYPE_VOLUMETUBELIGHT,
|
||||
VSTYPE_LIGHTVISUALIZER_SPOTLIGHT,
|
||||
VSTYPE_LIGHTVISUALIZER_POINTLIGHT,
|
||||
VSTYPE_LIGHTVISUALIZER_SPHERELIGHT,
|
||||
VSTYPE_LIGHTVISUALIZER_DISCLIGHT,
|
||||
VSTYPE_LIGHTVISUALIZER_RECTANGLELIGHT,
|
||||
VSTYPE_LIGHTVISUALIZER_TUBELIGHT,
|
||||
VSTYPE_SKY,
|
||||
VSTYPE_DECAL,
|
||||
VSTYPE_ENVMAP,
|
||||
@@ -204,7 +204,10 @@ enum PSTYPES
|
||||
PSTYPE_DISCLIGHT,
|
||||
PSTYPE_RECTANGLELIGHT,
|
||||
PSTYPE_TUBELIGHT,
|
||||
PSTYPE_VOLUMELIGHT,
|
||||
PSTYPE_LIGHTVISUALIZER,
|
||||
PSTYPE_VOLUMETRICLIGHT_DIRECTIONAL,
|
||||
PSTYPE_VOLUMETRICLIGHT_POINT,
|
||||
PSTYPE_VOLUMETRICLIGHT_SPOT,
|
||||
PSTYPE_SHADOWCUBEMAPRENDER,
|
||||
PSTYPE_SHADOWCUBEMAPRENDER_ALPHATEST,
|
||||
PSTYPE_DECAL,
|
||||
|
||||
@@ -4134,6 +4134,7 @@ Light::Light():Transform() {
|
||||
SetType(LightType::POINT);
|
||||
shadow = false;
|
||||
noHalo = false;
|
||||
volumetrics = false;
|
||||
lensFlareRimTextures.resize(0);
|
||||
lensFlareNames.resize(0);
|
||||
shadowMap_index = -1;
|
||||
@@ -4369,6 +4370,10 @@ void Light::Serialize(wiArchive& archive)
|
||||
archive >> width;
|
||||
archive >> height;
|
||||
}
|
||||
if (archive.GetVersion() >= 17)
|
||||
{
|
||||
archive >> volumetrics;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4390,6 +4395,10 @@ void Light::Serialize(wiArchive& archive)
|
||||
archive << width;
|
||||
archive << height;
|
||||
}
|
||||
if (archive.GetVersion() >= 17)
|
||||
{
|
||||
archive << volumetrics;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
@@ -902,6 +902,7 @@ struct Light : public Cullable , public Transform
|
||||
|
||||
XMFLOAT4 color;
|
||||
XMFLOAT4 enerDis;
|
||||
bool volumetrics = false;
|
||||
bool noHalo;
|
||||
bool shadow;
|
||||
std::vector<wiGraphicsTypes::Texture2D*> lensFlareRimTextures;
|
||||
|
||||
+172
-50
@@ -1157,7 +1157,8 @@ GraphicsPSO* GetImpostorPSO(SHADERTYPE shaderType)
|
||||
}
|
||||
|
||||
GraphicsPSO* PSO_deferredlight[Light::LIGHTTYPE_COUNT] = {};
|
||||
GraphicsPSO* PSO_volumelight[Light::LIGHTTYPE_COUNT] = {};
|
||||
GraphicsPSO* PSO_lightvisualizer[Light::LIGHTTYPE_COUNT] = {};
|
||||
GraphicsPSO* PSO_volumetriclight[Light::LIGHTTYPE_COUNT] = {};
|
||||
GraphicsPSO* PSO_enviromentallight = nullptr;
|
||||
|
||||
enum SKYRENDERING
|
||||
@@ -1358,12 +1359,12 @@ void wiRenderer::LoadShaders()
|
||||
vertexShaders[VSTYPE_DIRLIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "dirLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_POINTLIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "pointLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_SPOTLIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "spotLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_VOLUMESPOTLIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vSpotLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_VOLUMEPOINTLIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vPointLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_VOLUMESPHERELIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vSphereLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_VOLUMEDISCLIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vDiscLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_VOLUMERECTANGLELIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vRectangleLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_VOLUMETUBELIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vTubeLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_LIGHTVISUALIZER_SPOTLIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vSpotLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_LIGHTVISUALIZER_POINTLIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vPointLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_LIGHTVISUALIZER_SPHERELIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vSphereLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_LIGHTVISUALIZER_DISCLIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vDiscLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_LIGHTVISUALIZER_RECTANGLELIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vRectangleLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_LIGHTVISUALIZER_TUBELIGHT] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "vTubeLightVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_DECAL] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "decalVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_ENVMAP] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "envMapVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
vertexShaders[VSTYPE_ENVMAP_SKY] = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "envMap_skyVS.cso", wiResourceManager::VERTEXSHADER))->vertexShader;
|
||||
@@ -1431,7 +1432,10 @@ void wiRenderer::LoadShaders()
|
||||
pixelShaders[PSTYPE_DISCLIGHT] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "discLightPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_RECTANGLELIGHT] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "rectangleLightPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_TUBELIGHT] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "tubeLightPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_VOLUMELIGHT] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "volumeLightPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_LIGHTVISUALIZER] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "volumeLightPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_VOLUMETRICLIGHT_DIRECTIONAL] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "volumetricLight_DirectionalPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_VOLUMETRICLIGHT_POINT] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "volumetricLight_PointPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_VOLUMETRICLIGHT_SPOT] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "volumetricLight_SpotPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_DECAL] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "decalPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_ENVMAP] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "envMapPS.cso", wiResourceManager::PIXELSHADER));
|
||||
pixelShaders[PSTYPE_ENVMAP_SKY_STATIC] = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(SHADERPATH + "envMap_skyPS_static.cso", wiResourceManager::PIXELSHADER));
|
||||
@@ -1901,55 +1905,88 @@ void wiRenderer::LoadShaders()
|
||||
|
||||
|
||||
|
||||
// volume lights:
|
||||
if (type == Light::DIRECTIONAL)
|
||||
// light visualizers:
|
||||
if (type != Light::DIRECTIONAL)
|
||||
{
|
||||
continue;
|
||||
|
||||
desc.dss = depthStencils[DSSTYPE_DEPTHREAD];
|
||||
desc.ps = pixelShaders[PSTYPE_LIGHTVISUALIZER];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Light::POINT:
|
||||
desc.bs = blendStates[BSTYPE_ADDITIVE];
|
||||
desc.vs = vertexShaders[VSTYPE_LIGHTVISUALIZER_POINTLIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_FRONT];
|
||||
break;
|
||||
case Light::SPOT:
|
||||
desc.bs = blendStates[BSTYPE_ADDITIVE];
|
||||
desc.vs = vertexShaders[VSTYPE_LIGHTVISUALIZER_SPOTLIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_DOUBLESIDED];
|
||||
break;
|
||||
case Light::SPHERE:
|
||||
desc.bs = blendStates[BSTYPE_OPAQUE];
|
||||
desc.vs = vertexShaders[VSTYPE_LIGHTVISUALIZER_SPHERELIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_FRONT];
|
||||
break;
|
||||
case Light::DISC:
|
||||
desc.bs = blendStates[BSTYPE_OPAQUE];
|
||||
desc.vs = vertexShaders[VSTYPE_LIGHTVISUALIZER_DISCLIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_FRONT];
|
||||
break;
|
||||
case Light::RECTANGLE:
|
||||
desc.bs = blendStates[BSTYPE_OPAQUE];
|
||||
desc.vs = vertexShaders[VSTYPE_LIGHTVISUALIZER_RECTANGLELIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_BACK];
|
||||
break;
|
||||
case Light::TUBE:
|
||||
desc.bs = blendStates[BSTYPE_OPAQUE];
|
||||
desc.vs = vertexShaders[VSTYPE_LIGHTVISUALIZER_TUBELIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_FRONT];
|
||||
break;
|
||||
}
|
||||
|
||||
desc.numRTs = 1;
|
||||
desc.RTFormats[0] = RTFormat_hdr;
|
||||
desc.DSFormat = DSFormat_full;
|
||||
|
||||
RECREATE(PSO_lightvisualizer[type]);
|
||||
device->CreateGraphicsPSO(&desc, PSO_lightvisualizer[type]);
|
||||
}
|
||||
|
||||
desc.dss = depthStencils[DSSTYPE_DEPTHREAD];
|
||||
desc.ps = pixelShaders[PSTYPE_VOLUMELIGHT];
|
||||
|
||||
switch (type)
|
||||
// volumetric lights:
|
||||
if (type <= Light::SPOT)
|
||||
{
|
||||
case Light::POINT:
|
||||
desc.dss = depthStencils[DSSTYPE_XRAY];
|
||||
desc.bs = blendStates[BSTYPE_ADDITIVE];
|
||||
desc.vs = vertexShaders[VSTYPE_VOLUMEPOINTLIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_FRONT];
|
||||
break;
|
||||
case Light::SPOT:
|
||||
desc.bs = blendStates[BSTYPE_ADDITIVE];
|
||||
desc.vs = vertexShaders[VSTYPE_VOLUMESPOTLIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_DOUBLESIDED];
|
||||
break;
|
||||
case Light::SPHERE:
|
||||
desc.bs = blendStates[BSTYPE_OPAQUE];
|
||||
desc.vs = vertexShaders[VSTYPE_VOLUMESPHERELIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_FRONT];
|
||||
break;
|
||||
case Light::DISC:
|
||||
desc.bs = blendStates[BSTYPE_OPAQUE];
|
||||
desc.vs = vertexShaders[VSTYPE_VOLUMEDISCLIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_FRONT];
|
||||
break;
|
||||
case Light::RECTANGLE:
|
||||
desc.bs = blendStates[BSTYPE_OPAQUE];
|
||||
desc.vs = vertexShaders[VSTYPE_VOLUMERECTANGLELIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_BACK];
|
||||
break;
|
||||
case Light::TUBE:
|
||||
desc.bs = blendStates[BSTYPE_OPAQUE];
|
||||
desc.vs = vertexShaders[VSTYPE_VOLUMETUBELIGHT];
|
||||
desc.rs = rasterizers[RSTYPE_FRONT];
|
||||
break;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Light::DIRECTIONAL:
|
||||
desc.vs = vertexShaders[VSTYPE_DIRLIGHT];
|
||||
desc.ps = pixelShaders[PSTYPE_VOLUMETRICLIGHT_DIRECTIONAL];
|
||||
break;
|
||||
case Light::POINT:
|
||||
desc.vs = vertexShaders[VSTYPE_POINTLIGHT];
|
||||
desc.ps = pixelShaders[PSTYPE_VOLUMETRICLIGHT_POINT];
|
||||
break;
|
||||
case Light::SPOT:
|
||||
desc.vs = vertexShaders[VSTYPE_SPOTLIGHT];
|
||||
desc.ps = pixelShaders[PSTYPE_VOLUMETRICLIGHT_SPOT];
|
||||
break;
|
||||
}
|
||||
|
||||
desc.numRTs = 1;
|
||||
desc.RTFormats[0] = RTFormat_hdr;
|
||||
desc.DSFormat = FORMAT_UNKNOWN;
|
||||
|
||||
RECREATE(PSO_volumetriclight[type]);
|
||||
device->CreateGraphicsPSO(&desc, PSO_volumetriclight[type]);
|
||||
}
|
||||
|
||||
desc.numRTs = 1;
|
||||
desc.RTFormats[0] = RTFormat_hdr;
|
||||
desc.DSFormat = DSFormat_full;
|
||||
|
||||
RECREATE(PSO_volumelight[type]);
|
||||
device->CreateGraphicsPSO(&desc, PSO_volumelight[type]);
|
||||
}
|
||||
{
|
||||
GraphicsPSODesc desc;
|
||||
@@ -4409,14 +4446,14 @@ void wiRenderer::DrawLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
wiProfiler::GetInstance().EndRange(threadID);
|
||||
GetDevice()->EventEnd(threadID);
|
||||
}
|
||||
void wiRenderer::DrawVolumeLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
void wiRenderer::DrawLightVisualizers(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
{
|
||||
const FrameCulling& culling = frameCullings[camera];
|
||||
const CulledList& culledLights = culling.culledLights;
|
||||
|
||||
if(!culledLights.empty())
|
||||
{
|
||||
GetDevice()->EventBegin("Light Volume Render", threadID);
|
||||
GetDevice()->EventBegin("Light Visualizer Render", threadID);
|
||||
|
||||
GetDevice()->BindPrimitiveTopology(TRIANGLELIST,threadID);
|
||||
|
||||
@@ -4426,7 +4463,7 @@ void wiRenderer::DrawVolumeLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
|
||||
for (int type = Light::POINT; type < Light::LIGHTTYPE_COUNT; ++type)
|
||||
{
|
||||
GetDevice()->BindGraphicsPSO(PSO_volumelight[type], threadID);
|
||||
GetDevice()->BindGraphicsPSO(PSO_lightvisualizer[type], threadID);
|
||||
|
||||
for (Cullable* c : culledLights)
|
||||
{
|
||||
@@ -4523,6 +4560,91 @@ void wiRenderer::DrawVolumeLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
|
||||
GetDevice()->EventEnd(threadID);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void wiRenderer::DrawVolumeLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
{
|
||||
const FrameCulling& culling = frameCullings[camera];
|
||||
const CulledList& culledLights = culling.culledLights;
|
||||
|
||||
if (!culledLights.empty())
|
||||
{
|
||||
GetDevice()->EventBegin("Volumetric Light Render", threadID);
|
||||
|
||||
GetDevice()->BindPrimitiveTopology(TRIANGLELIST, threadID);
|
||||
|
||||
|
||||
for (int type = 0; type < Light::LIGHTTYPE_COUNT; ++type)
|
||||
{
|
||||
GraphicsPSO* pso = PSO_volumetriclight[type];
|
||||
|
||||
if (pso == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GetDevice()->BindGraphicsPSO(pso, threadID);
|
||||
|
||||
for (Cullable* c : culledLights)
|
||||
{
|
||||
Light* l = (Light*)c;
|
||||
if (l->GetType() == type && l->volumetrics)
|
||||
{
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Light::DIRECTIONAL:
|
||||
case Light::SPHERE:
|
||||
case Light::DISC:
|
||||
case Light::RECTANGLE:
|
||||
case Light::TUBE:
|
||||
{
|
||||
MiscCB miscCb;
|
||||
miscCb.mColor.x = (float)l->entityArray_index;
|
||||
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID);
|
||||
|
||||
GetDevice()->Draw(3, 0, threadID); // full screen triangle
|
||||
}
|
||||
break;
|
||||
case Light::POINT:
|
||||
{
|
||||
MiscCB miscCb;
|
||||
miscCb.mColor.x = (float)l->entityArray_index;
|
||||
float sca = l->enerDis.y + 1;
|
||||
miscCb.mTransform = XMMatrixTranspose(XMMatrixScaling(sca, sca, sca)*XMMatrixTranslation(l->translation.x, l->translation.y, l->translation.z) * camera->GetViewProjection());
|
||||
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID);
|
||||
|
||||
GetDevice()->Draw(240, 0, threadID); // icosphere
|
||||
}
|
||||
break;
|
||||
case Light::SPOT:
|
||||
{
|
||||
MiscCB miscCb;
|
||||
miscCb.mColor.x = (float)l->entityArray_index;
|
||||
const float coneS = (const float)(l->enerDis.z / XM_PIDIV4);
|
||||
miscCb.mTransform = XMMatrixTranspose(
|
||||
XMMatrixScaling(coneS*l->enerDis.y, l->enerDis.y, coneS*l->enerDis.y)*
|
||||
XMMatrixRotationQuaternion(XMLoadFloat4(&l->rotation))*
|
||||
XMMatrixTranslationFromVector(XMLoadFloat3(&l->translation)) *
|
||||
camera->GetViewProjection()
|
||||
);
|
||||
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID);
|
||||
|
||||
GetDevice()->Draw(192, 0, threadID); // cone
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GetDevice()->EventEnd(threadID);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void wiRenderer::DrawLensFlares(GRAPHICSTHREAD threadID)
|
||||
{
|
||||
|
||||
@@ -476,6 +476,7 @@ public:
|
||||
static void DrawImages(GRAPHICSTHREAD threadID, wiGraphicsTypes::Texture2D* refracRes);
|
||||
static void DrawImagesNormals(GRAPHICSTHREAD threadID, wiGraphicsTypes::Texture2D* refracRes);
|
||||
static void DrawLights(Camera* camera, GRAPHICSTHREAD threadID);
|
||||
static void DrawLightVisualizers(Camera* camera, GRAPHICSTHREAD threadID);
|
||||
static void DrawVolumeLights(Camera* camera, GRAPHICSTHREAD threadID);
|
||||
static void DrawLensFlares(GRAPHICSTHREAD threadID);
|
||||
static void DrawDecals(Camera* camera, GRAPHICSTHREAD threadID);
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wiVersion
|
||||
// minor features, major updates
|
||||
const int minor = 16;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 24;
|
||||
const int revision = 25;
|
||||
|
||||
|
||||
long GetVersion()
|
||||
|
||||
@@ -77,3 +77,4 @@ Ocean simulation (FFT)
|
||||
Translucent shadows
|
||||
Refraction caustics
|
||||
Local parallax-corrected environment maps
|
||||
Volumetric light scattering
|
||||
|
||||
Reference in New Issue
Block a user