new feature: volumetric light scattering

This commit is contained in:
turanszkij
2018-03-17 20:27:06 +00:00
parent 6d77c13d0d
commit 00fd6ce281
22 changed files with 439 additions and 80 deletions
+15
View File
@@ -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);
+1
View File
@@ -35,6 +35,7 @@ public:
wiSlider* biasSlider;
wiCheckBox* shadowCheckBox;
wiCheckBox* haloCheckBox;
wiCheckBox* volumetricsCheckBox;
wiButton* addLightButton;
wiColorPicker* colorPicker;
wiComboBox* typeSelectorComboBox;
+1
View File
@@ -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
+18 -4
View File
@@ -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;
+1
View File
@@ -56,6 +56,7 @@ protected:
, rtWaterRipple
, rtLinearDepth
, rtParticle
, rtVolumetricLights
, rtFinal[2]
, rtDof[3]
, rtTemporalAA[2]
+10 -1
View File
@@ -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">
+1 -1
View File
@@ -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]; \
+6
View File
@@ -0,0 +1,6 @@
#include "volumeLightHF.hlsli"
float4 main(VertexToPixel PSIn) : SV_TARGET
{
return max(PSIn.col,0);
}
+1 -1
View File
@@ -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))
{
-11
View File
@@ -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));
}
+55
View File
@@ -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));
}
+67
View File
@@ -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));
}
+1 -1
View File
@@ -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
View File
@@ -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,
+9
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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)
{
+1
View File
@@ -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);
+1 -1
View File
@@ -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()
+1
View File
@@ -77,3 +77,4 @@ Ocean simulation (FFT)
Translucent shadows
Refraction caustics
Local parallax-corrected environment maps
Volumetric light scattering