Refactor material shaders generator to use modular features as extensions
This commit is contained in:
123
Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl
Normal file
123
Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl
Normal file
@@ -0,0 +1,123 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
@0// Forward Shading: Defines
|
||||
#define MAX_LOCAL_LIGHTS 4
|
||||
@1// Forward Shading: Includes
|
||||
#include "./Flax/LightingCommon.hlsl"
|
||||
#if USE_REFLECTIONS
|
||||
#include "./Flax/ReflectionsCommon.hlsl"
|
||||
#endif
|
||||
#include "./Flax/Lighting.hlsl"
|
||||
#include "./Flax/ShadowsSampling.hlsl"
|
||||
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||
@2// Forward Shading: Constants
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
float3 Dummy2;
|
||||
uint LocalLightsCount;
|
||||
LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
@3// Forward Shading: Resources
|
||||
TextureCube EnvProbe : register(t__SRV__);
|
||||
TextureCube SkyLightTexture : register(t__SRV__);
|
||||
Texture2DArray DirectionalLightShadowMap : register(t__SRV__);
|
||||
@4// Forward Shading: Utilities
|
||||
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||
@5// Forward Shading: Shaders
|
||||
// Pixel Shader function for Forward Pass
|
||||
META_PS(USE_FORWARD, FEATURE_LEVEL_ES2)
|
||||
float4 PS_Forward(PixelInput input) : SV_Target0
|
||||
{
|
||||
float4 output = 0;
|
||||
|
||||
#if USE_DITHERED_LOD_TRANSITION
|
||||
// LOD masking
|
||||
ClipLODTransition(input);
|
||||
#endif
|
||||
|
||||
// Get material parameters
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
// Masking
|
||||
#if MATERIAL_MASKED
|
||||
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
|
||||
#endif
|
||||
|
||||
// Add emissive light
|
||||
output = float4(material.Emissive, material.Opacity);
|
||||
|
||||
#if MATERIAL_SHADING_MODEL != SHADING_MODEL_UNLIT
|
||||
|
||||
// Setup GBuffer data as proxy for lighting
|
||||
GBufferSample gBuffer;
|
||||
gBuffer.Normal = material.WorldNormal;
|
||||
gBuffer.Roughness = material.Roughness;
|
||||
gBuffer.Metalness = material.Metalness;
|
||||
gBuffer.Color = material.Color;
|
||||
gBuffer.Specular = material.Specular;
|
||||
gBuffer.AO = material.AO;
|
||||
gBuffer.ViewPos = mul(float4(materialInput.WorldPosition, 1), ViewMatrix).xyz;
|
||||
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
|
||||
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
|
||||
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#else
|
||||
gBuffer.CustomData = float4(0, 0, 0, 0);
|
||||
#endif
|
||||
gBuffer.WorldPos = materialInput.WorldPosition;
|
||||
gBuffer.ShadingModel = MATERIAL_SHADING_MODEL;
|
||||
|
||||
// Calculate lighting from a single directional light
|
||||
float4 shadowMask = 1.0f;
|
||||
if (DirectionalLight.CastShadows > 0)
|
||||
{
|
||||
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
|
||||
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
|
||||
}
|
||||
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
||||
|
||||
// Calculate lighting from sky light
|
||||
light += GetSkyLightLighting(SkyLight, gBuffer, SkyLightTexture);
|
||||
|
||||
// Calculate lighting from local lights
|
||||
LOOP
|
||||
for (uint localLightIndex = 0; localLightIndex < LocalLightsCount; localLightIndex++)
|
||||
{
|
||||
const LightData localLight = LocalLights[localLightIndex];
|
||||
bool isSpotLight = localLight.SpotAngles.x > -2.0f;
|
||||
shadowMask = 1.0f;
|
||||
light += GetLighting(ViewPos, localLight, gBuffer, shadowMask, true, isSpotLight);
|
||||
}
|
||||
|
||||
#if USE_REFLECTIONS
|
||||
// Calculate reflections
|
||||
light.rgb += GetEnvProbeLighting(ViewPos, EnvProbe, EnvironmentProbe, gBuffer) * light.a;
|
||||
#endif
|
||||
|
||||
// Add lighting (apply ambient occlusion)
|
||||
output.rgb += light.rgb * gBuffer.AO;
|
||||
|
||||
#if USE_FOG
|
||||
// Calculate exponential height fog
|
||||
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0);
|
||||
|
||||
// Apply fog to the output color
|
||||
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_TRANSPARENT
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_ADDITIVE
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a * fog.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_MULTIPLY
|
||||
output = float4(lerp(float3(1, 1, 1), output.rgb, fog.aaa * fog.aaa), output.a);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#define MATERIAL 1
|
||||
@3
|
||||
|
||||
#include "./Flax/Common.hlsl"
|
||||
#include "./Flax/MaterialCommon.hlsl"
|
||||
#include "./Flax/GBufferCommon.hlsl"
|
||||
@@ -22,7 +21,7 @@ float4 ViewInfo;
|
||||
float4 ScreenSize;
|
||||
@1META_CB_END
|
||||
|
||||
// Material shader resources
|
||||
// Shader resources
|
||||
@2
|
||||
// Interpolants passed from the vertex shader
|
||||
struct VertexOutput
|
||||
|
||||
@@ -2,19 +2,13 @@
|
||||
// Version: @0
|
||||
|
||||
#define MATERIAL 1
|
||||
#define MAX_LOCAL_LIGHTS 4
|
||||
@3
|
||||
// Ribbons don't use sorted indices so overlap the segment distances buffer on the slot
|
||||
#define HAS_SORTED_INDICES (!defined(_VS_Ribbon))
|
||||
|
||||
#include "./Flax/Common.hlsl"
|
||||
#include "./Flax/MaterialCommon.hlsl"
|
||||
#include "./Flax/GBufferCommon.hlsl"
|
||||
#include "./Flax/LightingCommon.hlsl"
|
||||
#if USE_REFLECTIONS
|
||||
#include "./Flax/ReflectionsCommon.hlsl"
|
||||
#endif
|
||||
#include "./Flax/Lighting.hlsl"
|
||||
#include "./Flax/ShadowsSampling.hlsl"
|
||||
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||
#include "./Flax/Matrix.hlsl"
|
||||
@7
|
||||
struct SpriteInput
|
||||
@@ -55,44 +49,19 @@ uint RibbonSegmentCount;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
@1META_CB_END
|
||||
|
||||
// Secondary constantant buffer (for lighting)
|
||||
META_CB_BEGIN(1, LightingData)
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
float3 Dummy1;
|
||||
uint LocalLightsCount;
|
||||
LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
META_CB_END
|
||||
|
||||
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||
|
||||
// Particles attributes buffer
|
||||
ByteAddressBuffer ParticlesData : register(t0);
|
||||
|
||||
// Ribbons don't use sorted indices so overlap the segment distances buffer on the slot
|
||||
#define HAS_SORTED_INDICES (!defined(_VS_Ribbon))
|
||||
|
||||
#if HAS_SORTED_INDICES
|
||||
|
||||
// Sorted particles indices
|
||||
Buffer<uint> SortedIndices : register(t1);
|
||||
|
||||
#else
|
||||
|
||||
// Ribbon particles segments distances buffer
|
||||
Buffer<float> SegmentDistances : register(t1);
|
||||
|
||||
#endif
|
||||
|
||||
// Shader resources
|
||||
TextureCube EnvProbe : register(t2);
|
||||
TextureCube SkyLightTexture : register(t3);
|
||||
Texture2DArray DirectionalLightShadowMap : register(t4);
|
||||
@2
|
||||
|
||||
// Interpolants passed from the vertex shader
|
||||
struct VertexOutput
|
||||
{
|
||||
@@ -711,97 +680,6 @@ VertexOutput VS_Ribbon(uint vertexIndex : SV_VertexID)
|
||||
return output;
|
||||
}
|
||||
|
||||
// Pixel Shader function for Forward Pass
|
||||
META_PS(USE_FORWARD, FEATURE_LEVEL_ES2)
|
||||
float4 PS_Forward(PixelInput input) : SV_Target0
|
||||
{
|
||||
float4 output = 0;
|
||||
|
||||
// Get material parameters
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
// Masking
|
||||
#if MATERIAL_MASKED
|
||||
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
|
||||
#endif
|
||||
|
||||
// Add emissive light
|
||||
output = float4(material.Emissive, material.Opacity);
|
||||
|
||||
#if MATERIAL_SHADING_MODEL != SHADING_MODEL_UNLIT
|
||||
|
||||
// Setup GBuffer data as proxy for lighting
|
||||
GBufferSample gBuffer;
|
||||
gBuffer.Normal = material.WorldNormal;
|
||||
gBuffer.Roughness = material.Roughness;
|
||||
gBuffer.Metalness = material.Metalness;
|
||||
gBuffer.Color = material.Color;
|
||||
gBuffer.Specular = material.Specular;
|
||||
gBuffer.AO = material.AO;
|
||||
gBuffer.ViewPos = mul(float4(materialInput.WorldPosition, 1), ViewMatrix).xyz;
|
||||
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
|
||||
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
|
||||
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#else
|
||||
gBuffer.CustomData = float4(0, 0, 0, 0);
|
||||
#endif
|
||||
gBuffer.WorldPos = materialInput.WorldPosition;
|
||||
gBuffer.ShadingModel = MATERIAL_SHADING_MODEL;
|
||||
|
||||
// Calculate lighting from a single directional light
|
||||
float4 shadowMask = 1.0f;
|
||||
if (DirectionalLight.CastShadows > 0)
|
||||
{
|
||||
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
|
||||
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
|
||||
}
|
||||
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
||||
|
||||
// Calculate lighting from sky light
|
||||
light += GetSkyLightLighting(SkyLight, gBuffer, SkyLightTexture);
|
||||
|
||||
// Calculate lighting from local lights
|
||||
LOOP
|
||||
for (uint localLightIndex = 0; localLightIndex < LocalLightsCount; localLightIndex++)
|
||||
{
|
||||
const LightData localLight = LocalLights[localLightIndex];
|
||||
bool isSpotLight = localLight.SpotAngles.x > -2.0f;
|
||||
shadowMask = 1.0f;
|
||||
light += GetLighting(ViewPos, localLight, gBuffer, shadowMask, true, isSpotLight);
|
||||
}
|
||||
|
||||
#if USE_REFLECTIONS
|
||||
// Calculate reflections
|
||||
light.rgb += GetEnvProbeLighting(ViewPos, EnvProbe, EnvironmentProbe, gBuffer) * light.a;
|
||||
#endif
|
||||
|
||||
// Add lighting (apply ambient occlusion)
|
||||
output.rgb += light.rgb * gBuffer.AO;
|
||||
|
||||
#if USE_FOG
|
||||
// Calculate exponential height fog
|
||||
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0);
|
||||
|
||||
// Apply fog to the output color
|
||||
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_TRANSPARENT
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_ADDITIVE
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a * fog.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_MULTIPLY
|
||||
output = float4(lerp(float3(1, 1, 1), output.rgb, fog.aaa * fog.aaa), output.a);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Pixel Shader function for Depth Pass
|
||||
META_PS(true, FEATURE_LEVEL_ES2)
|
||||
void PS_Depth(PixelInput input
|
||||
|
||||
@@ -20,7 +20,7 @@ float4 ScreenSize;
|
||||
float4 TemporalAAJitter;
|
||||
@1META_CB_END
|
||||
|
||||
// Material shader resources
|
||||
// Shader resources
|
||||
@2
|
||||
// Interpolants passed to the pixel shader
|
||||
struct PixelInput
|
||||
|
||||
@@ -30,9 +30,8 @@ float3 GeometrySize;
|
||||
float Dummy1;
|
||||
@1META_CB_END
|
||||
|
||||
// Material shader resources
|
||||
// Shader resources
|
||||
@2
|
||||
|
||||
// Geometry data passed though the graphics rendering stages up to the pixel shader
|
||||
struct GeometryData
|
||||
{
|
||||
|
||||
@@ -2,19 +2,10 @@
|
||||
// Version: @0
|
||||
|
||||
#define MATERIAL 1
|
||||
#define MAX_LOCAL_LIGHTS 4
|
||||
@3
|
||||
|
||||
#include "./Flax/Common.hlsl"
|
||||
#include "./Flax/MaterialCommon.hlsl"
|
||||
#include "./Flax/GBufferCommon.hlsl"
|
||||
#include "./Flax/LightingCommon.hlsl"
|
||||
#if USE_REFLECTIONS
|
||||
#include "./Flax/ReflectionsCommon.hlsl"
|
||||
#endif
|
||||
#include "./Flax/Lighting.hlsl"
|
||||
#include "./Flax/ShadowsSampling.hlsl"
|
||||
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
@@ -38,26 +29,8 @@ float3 GeometrySize;
|
||||
float Dummy1;
|
||||
@1META_CB_END
|
||||
|
||||
// Secondary constantant buffer (for lighting)
|
||||
META_CB_BEGIN(1, LightingData)
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
float3 Dummy2;
|
||||
uint LocalLightsCount;
|
||||
LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
META_CB_END
|
||||
|
||||
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||
|
||||
// Shader resources
|
||||
TextureCube EnvProbe : register(t0);
|
||||
TextureCube SkyLightTexture : register(t1);
|
||||
Texture2DArray DirectionalLightShadowMap : register(t2);
|
||||
@2
|
||||
|
||||
// Interpolants passed from the vertex shader
|
||||
struct VertexOutput
|
||||
{
|
||||
@@ -564,103 +537,6 @@ void ClipLODTransition(PixelInput input)
|
||||
|
||||
#endif
|
||||
|
||||
// Pixel Shader function for Forward Pass
|
||||
META_PS(USE_FORWARD, FEATURE_LEVEL_ES2)
|
||||
float4 PS_Forward(PixelInput input) : SV_Target0
|
||||
{
|
||||
float4 output = 0;
|
||||
|
||||
#if USE_DITHERED_LOD_TRANSITION
|
||||
// LOD masking
|
||||
ClipLODTransition(input);
|
||||
// TODO: make model LOD transition smoother for transparent materials by using opacity to reduce aliasing
|
||||
#endif
|
||||
|
||||
// Get material parameters
|
||||
MaterialInput materialInput = GetMaterialInput(input);
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
// Masking
|
||||
#if MATERIAL_MASKED
|
||||
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
|
||||
#endif
|
||||
|
||||
// Add emissive light
|
||||
output = float4(material.Emissive, material.Opacity);
|
||||
|
||||
#if MATERIAL_SHADING_MODEL != SHADING_MODEL_UNLIT
|
||||
|
||||
// Setup GBuffer data as proxy for lighting
|
||||
GBufferSample gBuffer;
|
||||
gBuffer.Normal = material.WorldNormal;
|
||||
gBuffer.Roughness = material.Roughness;
|
||||
gBuffer.Metalness = material.Metalness;
|
||||
gBuffer.Color = material.Color;
|
||||
gBuffer.Specular = material.Specular;
|
||||
gBuffer.AO = material.AO;
|
||||
gBuffer.ViewPos = mul(float4(materialInput.WorldPosition, 1), ViewMatrix).xyz;
|
||||
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
|
||||
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
|
||||
gBuffer.CustomData = float4(material.SubsurfaceColor, material.Opacity);
|
||||
#else
|
||||
gBuffer.CustomData = float4(0, 0, 0, 0);
|
||||
#endif
|
||||
gBuffer.WorldPos = materialInput.WorldPosition;
|
||||
gBuffer.ShadingModel = MATERIAL_SHADING_MODEL;
|
||||
|
||||
// Calculate lighting from a single directional light
|
||||
float4 shadowMask = 1.0f;
|
||||
if (DirectionalLight.CastShadows > 0)
|
||||
{
|
||||
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
|
||||
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
|
||||
}
|
||||
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
||||
|
||||
// Calculate lighting from sky light
|
||||
light += GetSkyLightLighting(SkyLight, gBuffer, SkyLightTexture);
|
||||
|
||||
// Calculate lighting from local lights
|
||||
LOOP
|
||||
for (uint localLightIndex = 0; localLightIndex < LocalLightsCount; localLightIndex++)
|
||||
{
|
||||
const LightData localLight = LocalLights[localLightIndex];
|
||||
bool isSpotLight = localLight.SpotAngles.x > -2.0f;
|
||||
shadowMask = 1.0f;
|
||||
light += GetLighting(ViewPos, localLight, gBuffer, shadowMask, true, isSpotLight);
|
||||
}
|
||||
|
||||
#if USE_REFLECTIONS
|
||||
// Calculate reflections
|
||||
light.rgb += GetEnvProbeLighting(ViewPos, EnvProbe, EnvironmentProbe, gBuffer) * light.a;
|
||||
#endif
|
||||
|
||||
// Add lighting (apply ambient occlusion)
|
||||
output.rgb += light.rgb * gBuffer.AO;
|
||||
|
||||
#if USE_FOG
|
||||
// Calculate exponential height fog
|
||||
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0);
|
||||
|
||||
// Apply fog to the output color
|
||||
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_TRANSPARENT
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_ADDITIVE
|
||||
output = float4(output.rgb * fog.a + fog.rgb, output.a * fog.a);
|
||||
#elif MATERIAL_BLEND == MATERIAL_BLEND_MULTIPLY
|
||||
output = float4(lerp(float3(1, 1, 1), output.rgb, fog.aaa * fog.aaa), output.a);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Pixel Shader function for Depth Pass
|
||||
META_PS(true, FEATURE_LEVEL_ES2)
|
||||
void PS_Depth(PixelInput input
|
||||
|
||||
@@ -42,9 +42,8 @@ Texture2D Heightmap : register(t0);
|
||||
Texture2D Splatmap0 : register(t1);
|
||||
Texture2D Splatmap1 : register(t2);
|
||||
|
||||
// Material shader resources
|
||||
// Shader resources
|
||||
@2
|
||||
|
||||
// Geometry data passed though the graphics rendering stages up to the pixel shader
|
||||
struct GeometryData
|
||||
{
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
#include "MaterialShaderFeatures.h"
|
||||
#include "MaterialParams.h"
|
||||
#include "Engine/Engine/Time.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/GPULimits.h"
|
||||
#include "Engine/Graphics/Models/SkinnedMeshDrawData.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
#include "Engine/Level/Actors/EnvironmentProbe.h"
|
||||
#include "Engine/Renderer/DepthOfFieldPass.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/Models/SkinnedMeshDrawData.h"
|
||||
#include "Engine/Graphics/Shaders/GPUConstantBuffer.h"
|
||||
#include "Engine/Graphics/Shaders/GPUShader.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
#include "Engine/Renderer/ShadowsPass.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#if USE_EDITOR
|
||||
#include "Engine/Renderer/Lightmaps.h"
|
||||
@@ -39,17 +40,6 @@ PACK_STRUCT(struct ForwardMaterialShaderData {
|
||||
float Dummy1;
|
||||
});
|
||||
|
||||
PACK_STRUCT(struct ForwardMaterialShaderLightingData {
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
Vector3 Dummy2;
|
||||
uint32 LocalLightsCount;
|
||||
LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
});
|
||||
|
||||
DrawPass ForwardMaterialShader::GetDrawModes() const
|
||||
{
|
||||
return _drawModes;
|
||||
@@ -66,19 +56,17 @@ void ForwardMaterialShader::Bind(BindParameters& params)
|
||||
// Prepare
|
||||
auto context = params.GPUContext;
|
||||
auto& view = params.RenderContext.View;
|
||||
auto cache = params.RenderContext.List;
|
||||
auto& drawCall = *params.FirstDrawCall;
|
||||
const auto cb0 = _shader->GetCB(0);
|
||||
const bool hasCb0 = cb0 && cb0->GetSize() != 0;
|
||||
ASSERT(hasCb0 && "TODO: fix it"); // TODO: always make cb pointer valid even if cb is missing
|
||||
const auto cb1 = _shader->GetCB(1);
|
||||
const bool hasCb1 = cb1 && cb1->GetSize() != 0;
|
||||
byte* cb = _cb0Data.Get();
|
||||
auto materialData = reinterpret_cast<ForwardMaterialShaderData*>(cb);
|
||||
cb += sizeof(ForwardMaterialShaderData);
|
||||
int32 srv = 0;
|
||||
|
||||
// Setup features
|
||||
ForwardShadingFeature::Bind(params, cb, srv);
|
||||
|
||||
// Setup parameters
|
||||
MaterialParameter::BindMeta bindMeta;
|
||||
@@ -131,124 +119,12 @@ void ForwardMaterialShader::Bind(BindParameters& params)
|
||||
materialData->GeometrySize = drawCall.Surface.GeometrySize;
|
||||
}
|
||||
|
||||
// Setup lighting constants data
|
||||
if (hasCb1)
|
||||
{
|
||||
auto& lightingData = *reinterpret_cast<ForwardMaterialShaderLightingData*>(_cb1Data.Get());
|
||||
const int32 envProbeShaderRegisterIndex = 0;
|
||||
const int32 skyLightShaderRegisterIndex = 1;
|
||||
const int32 dirLightShaderRegisterIndex = 2;
|
||||
|
||||
// Set fog input
|
||||
if (cache->Fog)
|
||||
{
|
||||
cache->Fog->GetExponentialHeightFogData(view, lightingData.ExponentialHeightFog);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightingData.ExponentialHeightFog.FogMinOpacity = 1.0f;
|
||||
lightingData.ExponentialHeightFog.ApplyDirectionalInscattering = 0.0f;
|
||||
}
|
||||
|
||||
// Set directional light input
|
||||
if (cache->DirectionalLights.HasItems())
|
||||
{
|
||||
const auto& dirLight = cache->DirectionalLights.First();
|
||||
const auto shadowPass = ShadowsPass::Instance();
|
||||
const bool useShadow = shadowPass->LastDirLightIndex == 0;
|
||||
if (useShadow)
|
||||
{
|
||||
lightingData.DirectionalLightShadow = shadowPass->LastDirLight;
|
||||
context->BindSR(dirLightShaderRegisterIndex, shadowPass->LastDirLightShadowMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->UnBindSR(dirLightShaderRegisterIndex);
|
||||
}
|
||||
dirLight.SetupLightData(&lightingData.DirectionalLight, view, useShadow);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightingData.DirectionalLight.Color = Vector3::Zero;
|
||||
lightingData.DirectionalLight.CastShadows = 0.0f;
|
||||
context->UnBindSR(dirLightShaderRegisterIndex);
|
||||
}
|
||||
|
||||
// Set sky light
|
||||
if (cache->SkyLights.HasItems())
|
||||
{
|
||||
auto& skyLight = cache->SkyLights.First();
|
||||
skyLight.SetupLightData(&lightingData.SkyLight, view, false);
|
||||
const auto texture = skyLight.Image ? skyLight.Image->GetTexture() : nullptr;
|
||||
context->BindSR(skyLightShaderRegisterIndex, GET_TEXTURE_VIEW_SAFE(texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
Platform::MemoryClear(&lightingData.SkyLight, sizeof(lightingData.SkyLight));
|
||||
context->UnBindSR(skyLightShaderRegisterIndex);
|
||||
}
|
||||
|
||||
// Set reflection probe data
|
||||
EnvironmentProbe* probe = nullptr;
|
||||
// TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it
|
||||
for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++)
|
||||
{
|
||||
const auto p = cache->EnvironmentProbes[i];
|
||||
if (p->GetSphere().Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
|
||||
{
|
||||
probe = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (probe && probe->GetProbe())
|
||||
{
|
||||
probe->SetupProbeData(&lightingData.EnvironmentProbe);
|
||||
const auto texture = probe->GetProbe()->GetTexture();
|
||||
context->BindSR(envProbeShaderRegisterIndex, GET_TEXTURE_VIEW_SAFE(texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
lightingData.EnvironmentProbe.Data1 = Vector4::Zero;
|
||||
context->UnBindSR(envProbeShaderRegisterIndex);
|
||||
}
|
||||
|
||||
// Set local lights
|
||||
lightingData.LocalLightsCount = 0;
|
||||
for (int32 i = 0; i < cache->PointLights.Count(); i++)
|
||||
{
|
||||
const auto& light = cache->PointLights[i];
|
||||
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
|
||||
{
|
||||
light.SetupLightData(&lightingData.LocalLights[lightingData.LocalLightsCount], view, false);
|
||||
lightingData.LocalLightsCount++;
|
||||
if (lightingData.LocalLightsCount == MAX_LOCAL_LIGHTS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int32 i = 0; i < cache->SpotLights.Count(); i++)
|
||||
{
|
||||
const auto& light = cache->SpotLights[i];
|
||||
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
|
||||
{
|
||||
light.SetupLightData(&lightingData.LocalLights[lightingData.LocalLightsCount], view, false);
|
||||
lightingData.LocalLightsCount++;
|
||||
if (lightingData.LocalLightsCount == MAX_LOCAL_LIGHTS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bind constants
|
||||
if (hasCb0)
|
||||
{
|
||||
context->UpdateCB(cb0, _cb0Data.Get());
|
||||
context->BindCB(0, cb0);
|
||||
}
|
||||
if (hasCb1)
|
||||
{
|
||||
context->UpdateCB(cb1, _cb1Data.Get());
|
||||
context->BindCB(1, cb1);
|
||||
}
|
||||
|
||||
// Select pipeline state based on current pass and render mode
|
||||
const bool wireframe = (_info.FeaturesFlags & MaterialFeaturesFlags::Wireframe) != 0 || view.Mode == ViewMode::Wireframe;
|
||||
|
||||
@@ -143,11 +143,6 @@ bool MaterialShader::Load(MemoryReadStream& shaderCacheStream, const MaterialInf
|
||||
{
|
||||
_cb0Data.Resize(cb0->GetSize(), false);
|
||||
}
|
||||
const auto cb1 = _shader->GetCB(1);
|
||||
if (cb1)
|
||||
{
|
||||
_cb1Data.Resize(cb1->GetSize(), false);
|
||||
}
|
||||
|
||||
// Initialize the material based on type (create pipeline states and setup)
|
||||
if (Load())
|
||||
@@ -163,6 +158,5 @@ void MaterialShader::Unload()
|
||||
{
|
||||
_isLoaded = false;
|
||||
_cb0Data.Resize(0, false);
|
||||
_cb1Data.Resize(0, false);
|
||||
_shader->ReleaseGPU();
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ protected:
|
||||
bool _isLoaded;
|
||||
GPUShader* _shader;
|
||||
Array<byte> _cb0Data;
|
||||
Array<byte> _cb1Data;
|
||||
MaterialInfo _info;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -155,23 +155,30 @@ bool LightmapFeature::Bind(MaterialShader::BindParameters& params, byte*& cb, in
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
void ForwardShadingFeature::Generate(GeneratorData& data)
|
||||
{
|
||||
data.Template = TEXT("Features/ForwardShading.hlsl");
|
||||
data.ConstantsSize = sizeof(Data);
|
||||
data.ResourcesCount = SRVs;
|
||||
}
|
||||
|
||||
void TessellationFeature::Generate(GeneratorData& data)
|
||||
{
|
||||
data.Template = TEXT("Tessellation.hlsl");
|
||||
data.Template = TEXT("Features/Tessellation.hlsl");
|
||||
data.ConstantsSize = 0;
|
||||
data.ResourcesCount = 0;
|
||||
}
|
||||
|
||||
void LightmapFeature::Generate(GeneratorData& data)
|
||||
{
|
||||
data.Template = TEXT("Lightmap.hlsl");
|
||||
data.Template = TEXT("Features/Lightmap.hlsl");
|
||||
data.ConstantsSize = sizeof(Data);
|
||||
data.ResourcesCount = SRVs;
|
||||
}
|
||||
|
||||
void DistortionFeature::Generate(GeneratorData& data)
|
||||
{
|
||||
data.Template = TEXT("Distortion.hlsl");
|
||||
data.Template = TEXT("Features/Distortion.hlsl");
|
||||
data.ConstantsSize = 0;
|
||||
data.ResourcesCount = 0;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ struct ForwardShadingFeature : MaterialShaderFeature
|
||||
});
|
||||
|
||||
static void Bind(MaterialShader::BindParameters& params, byte*& cb, int32& srv);
|
||||
#if USE_EDITOR
|
||||
static void Generate(GeneratorData& data);
|
||||
#endif
|
||||
};
|
||||
|
||||
// Material shader feature that adds geometry hardware tessellation (using Hull and Domain shaders).
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "ParticleMaterialShader.h"
|
||||
#include "MaterialShaderFeatures.h"
|
||||
#include "MaterialParams.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
#include "Engine/Renderer/ShadowsPass.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/Shaders/GPUConstantBuffer.h"
|
||||
#include "Engine/Engine/Time.h"
|
||||
#include "Engine/Renderer/DrawCall.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Graphics/RenderView.h"
|
||||
#include "Engine/Graphics/GPUContext.h"
|
||||
#include "Engine/Graphics/GPUDevice.h"
|
||||
#include "Engine/Graphics/Shaders/GPUShader.h"
|
||||
#include "Engine/Graphics/GPULimits.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Graphics/Shaders/GPUShader.h"
|
||||
#include "Engine/Graphics/Shaders/GPUConstantBuffer.h"
|
||||
#include "Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.h"
|
||||
#include "Engine/Content/Assets/CubeTexture.h"
|
||||
#include "Engine/Level/Actors/EnvironmentProbe.h"
|
||||
|
||||
#define MAX_LOCAL_LIGHTS 4
|
||||
|
||||
@@ -49,17 +48,6 @@ PACK_STRUCT(struct ParticleMaterialShaderData {
|
||||
Matrix WorldMatrixInverseTransposed;
|
||||
});
|
||||
|
||||
PACK_STRUCT(struct ParticleMaterialShaderLightingData {
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
Vector3 Dummy1;
|
||||
uint32 LocalLightsCount;
|
||||
LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
});
|
||||
|
||||
DrawPass ParticleMaterialShader::GetDrawModes() const
|
||||
{
|
||||
return _drawModes;
|
||||
@@ -70,20 +58,18 @@ void ParticleMaterialShader::Bind(BindParameters& params)
|
||||
// Prepare
|
||||
auto context = params.GPUContext;
|
||||
auto& view = params.RenderContext.View;
|
||||
auto cache = params.RenderContext.List;
|
||||
auto& drawCall = *params.FirstDrawCall;
|
||||
const uint32 sortedIndicesOffset = drawCall.Particle.Module->SortedIndicesOffset;
|
||||
const auto cb0 = _shader->GetCB(0);
|
||||
const bool hasCb0 = cb0->GetSize() != 0;
|
||||
ASSERT(hasCb0 && "TODO: fix it"); // TODO: always make cb pointer valid even if cb is missing
|
||||
const auto cb1 = _shader->GetCB(1);
|
||||
const bool hasCb1 = cb1 && cb1->GetSize() != 0;
|
||||
byte* cb = _cb0Data.Get();
|
||||
auto materialData = reinterpret_cast<ParticleMaterialShaderData*>(cb);
|
||||
cb += sizeof(ParticleMaterialShaderData);
|
||||
int32 srv = 0;
|
||||
|
||||
int32 srv = 2;
|
||||
|
||||
// Setup features
|
||||
ForwardShadingFeature::Bind(params, cb, srv);
|
||||
|
||||
// Setup parameters
|
||||
MaterialParameter::BindMeta bindMeta;
|
||||
@@ -95,25 +81,23 @@ void ParticleMaterialShader::Bind(BindParameters& params)
|
||||
bindMeta.CanSampleGBuffer = true;
|
||||
MaterialParams::Bind(params.ParamsLink, bindMeta);
|
||||
|
||||
// Setup particles data and attributes binding info
|
||||
// Setup particles data
|
||||
context->BindSR(0, drawCall.Particle.Particles->GPU.Buffer->View());
|
||||
context->BindSR(1, drawCall.Particle.Particles->GPU.SortedIndices ? drawCall.Particle.Particles->GPU.SortedIndices->View() : nullptr);
|
||||
|
||||
// Setup particles attributes binding info
|
||||
if (hasCb0)
|
||||
{
|
||||
context->BindSR(0, drawCall.Particle.Particles->GPU.Buffer->View());
|
||||
if (drawCall.Particle.Particles->GPU.SortedIndices)
|
||||
context->BindSR(1, drawCall.Particle.Particles->GPU.SortedIndices->View());
|
||||
|
||||
if (hasCb0)
|
||||
const auto& p = *params.ParamsLink->This;
|
||||
for (int32 i = 0; i < p.Count(); i++)
|
||||
{
|
||||
const auto& p = *params.ParamsLink->This;
|
||||
for (int32 i = 0; i < p.Count(); i++)
|
||||
const auto& param = p.At(i);
|
||||
if (param.GetParameterType() == MaterialParameterType::Integer && param.GetName().StartsWith(TEXT("Particle.")))
|
||||
{
|
||||
const auto& param = p.At(i);
|
||||
if (param.GetParameterType() == MaterialParameterType::Integer && param.GetName().StartsWith(TEXT("Particle.")))
|
||||
{
|
||||
auto name = StringView(param.GetName().Get() + 9);
|
||||
auto name = StringView(param.GetName().Get() + 9);
|
||||
|
||||
const int32 offset = drawCall.Particle.Particles->Layout->FindAttributeOffset(name);
|
||||
*((int32*)(bindMeta.Constants + param.GetBindOffset())) = offset;
|
||||
}
|
||||
const int32 offset = drawCall.Particle.Particles->Layout->FindAttributeOffset(name);
|
||||
*((int32*)(bindMeta.Constants + param.GetBindOffset())) = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,8 +131,6 @@ void ParticleMaterialShader::Bind(BindParameters& params)
|
||||
|
||||
if (hasCb0)
|
||||
{
|
||||
const auto materialData = reinterpret_cast<ParticleMaterialShaderData*>(_cb0Data.Get());
|
||||
|
||||
materialData->RibbonWidthOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleRibbonWidth, ParticleAttribute::ValueTypes::Float, -1);
|
||||
materialData->RibbonTwistOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleRibbonTwist, ParticleAttribute::ValueTypes::Float, -1);
|
||||
materialData->RibbonFacingVectorOffset = drawCall.Particle.Particles->Layout->FindAttributeOffset(ParticleRibbonFacingVector, ParticleAttribute::ValueTypes::Vector3, -1);
|
||||
@@ -173,8 +155,6 @@ void ParticleMaterialShader::Bind(BindParameters& params)
|
||||
// Setup material constants data
|
||||
if (hasCb0)
|
||||
{
|
||||
const auto materialData = reinterpret_cast<ParticleMaterialShaderData*>(_cb0Data.Get());
|
||||
|
||||
static StringView ParticlePosition(TEXT("Position"));
|
||||
static StringView ParticleSpriteSize(TEXT("SpriteSize"));
|
||||
static StringView ParticleSpriteFacingMode(TEXT("SpriteFacingMode"));
|
||||
@@ -207,124 +187,12 @@ void ParticleMaterialShader::Bind(BindParameters& params)
|
||||
Matrix::Invert(drawCall.World, materialData->WorldMatrixInverseTransposed);
|
||||
}
|
||||
|
||||
// Setup lighting constants data
|
||||
if (hasCb1)
|
||||
{
|
||||
auto& lightingData = *reinterpret_cast<ParticleMaterialShaderLightingData*>(_cb1Data.Get());
|
||||
const int32 envProbeShaderRegisterIndex = 2;
|
||||
const int32 skyLightShaderRegisterIndex = 3;
|
||||
const int32 dirLightShaderRegisterIndex = 4;
|
||||
|
||||
// Set fog input
|
||||
if (cache->Fog)
|
||||
{
|
||||
cache->Fog->GetExponentialHeightFogData(view, lightingData.ExponentialHeightFog);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightingData.ExponentialHeightFog.FogMinOpacity = 1.0f;
|
||||
lightingData.ExponentialHeightFog.ApplyDirectionalInscattering = 0.0f;
|
||||
}
|
||||
|
||||
// Set directional light input
|
||||
if (cache->DirectionalLights.HasItems())
|
||||
{
|
||||
const auto& dirLight = cache->DirectionalLights.First();
|
||||
const auto shadowPass = ShadowsPass::Instance();
|
||||
const bool useShadow = shadowPass->LastDirLightIndex == 0;
|
||||
if (useShadow)
|
||||
{
|
||||
lightingData.DirectionalLightShadow = shadowPass->LastDirLight;
|
||||
context->BindSR(dirLightShaderRegisterIndex, shadowPass->LastDirLightShadowMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->UnBindSR(dirLightShaderRegisterIndex);
|
||||
}
|
||||
dirLight.SetupLightData(&lightingData.DirectionalLight, view, useShadow);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightingData.DirectionalLight.Color = Vector3::Zero;
|
||||
lightingData.DirectionalLight.CastShadows = 0.0f;
|
||||
context->UnBindSR(dirLightShaderRegisterIndex);
|
||||
}
|
||||
|
||||
// Set sky light
|
||||
if (cache->SkyLights.HasItems())
|
||||
{
|
||||
auto& skyLight = cache->SkyLights.Last();
|
||||
skyLight.SetupLightData(&lightingData.SkyLight, view, false);
|
||||
const auto texture = skyLight.Image ? skyLight.Image->GetTexture() : nullptr;
|
||||
context->BindSR(skyLightShaderRegisterIndex, texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
Platform::MemoryClear(&lightingData.SkyLight, sizeof(lightingData.SkyLight));
|
||||
context->UnBindSR(skyLightShaderRegisterIndex);
|
||||
}
|
||||
|
||||
// Set reflection probe data
|
||||
EnvironmentProbe* probe = nullptr;
|
||||
// TODO: optimize env probe searching for a transparent material - use spatial cache for renderer to find it
|
||||
for (int32 i = 0; i < cache->EnvironmentProbes.Count(); i++)
|
||||
{
|
||||
const auto p = cache->EnvironmentProbes[i];
|
||||
if (p->GetSphere().Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
|
||||
{
|
||||
probe = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (probe && probe->GetProbe())
|
||||
{
|
||||
probe->SetupProbeData(&lightingData.EnvironmentProbe);
|
||||
const auto texture = probe->GetProbe()->GetTexture();
|
||||
context->BindSR(envProbeShaderRegisterIndex, texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightingData.EnvironmentProbe.Data1 = Vector4::Zero;
|
||||
context->UnBindSR(envProbeShaderRegisterIndex);
|
||||
}
|
||||
|
||||
// Set local lights
|
||||
lightingData.LocalLightsCount = 0;
|
||||
for (int32 i = 0; i < cache->PointLights.Count(); i++)
|
||||
{
|
||||
const auto& light = cache->PointLights[i];
|
||||
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
|
||||
{
|
||||
light.SetupLightData(&lightingData.LocalLights[lightingData.LocalLightsCount], view, false);
|
||||
lightingData.LocalLightsCount++;
|
||||
if (lightingData.LocalLightsCount == MAX_LOCAL_LIGHTS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int32 i = 0; i < cache->SpotLights.Count(); i++)
|
||||
{
|
||||
const auto& light = cache->SpotLights[i];
|
||||
if (BoundingSphere(light.Position, light.Radius).Contains(drawCall.World.GetTranslation()) != ContainmentType::Disjoint)
|
||||
{
|
||||
light.SetupLightData(&lightingData.LocalLights[lightingData.LocalLightsCount], view, false);
|
||||
lightingData.LocalLightsCount++;
|
||||
if (lightingData.LocalLightsCount == MAX_LOCAL_LIGHTS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bind constants
|
||||
if (hasCb0)
|
||||
{
|
||||
context->UpdateCB(cb0, _cb0Data.Get());
|
||||
context->BindCB(0, cb0);
|
||||
}
|
||||
if (hasCb1)
|
||||
{
|
||||
context->UpdateCB(cb1, _cb1Data.Get());
|
||||
context->BindCB(1, cb1);
|
||||
}
|
||||
|
||||
// Bind pipeline
|
||||
context->SetState(state);
|
||||
|
||||
@@ -26,7 +26,6 @@ void PostFxMaterialShader::Bind(BindParameters& params)
|
||||
// Prepare
|
||||
auto context = params.GPUContext;
|
||||
auto& view = params.RenderContext.View;
|
||||
auto& drawCall = *params.FirstDrawCall;
|
||||
const auto cb0 = _shader->GetCB(0);
|
||||
const bool hasCb0 = cb0->GetSize() != 0;
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "GPUShaderDX11.h"
|
||||
#if GRAPHICS_API_DIRECTX11
|
||||
|
||||
#include "GPUContextDX11.h"
|
||||
#include "Engine/Core/Math/Viewport.h"
|
||||
#include "Engine/Core/Math/Rectangle.h"
|
||||
#include "GPUShaderDX11.h"
|
||||
#include "GPUShaderProgramDX11.h"
|
||||
#include "GPUPipelineStateDX11.h"
|
||||
#include "GPUTextureDX11.h"
|
||||
#include "GPUBufferDX11.h"
|
||||
#include "Engine/GraphicsDevice/DirectX/RenderToolsDX.h"
|
||||
#include "Engine/Core/Math/Viewport.h"
|
||||
#include "Engine/Core/Math/Rectangle.h"
|
||||
#include "Engine/Profiler/RenderStats.h"
|
||||
|
||||
#define DX11_CLEAR_SR_ON_STAGE_DISABLE 0
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace
|
||||
bool FeatureData::Init()
|
||||
{
|
||||
// Load template file
|
||||
const String path = Globals::EngineContentFolder / TEXT("Editor/MaterialTemplates/Features/") + Data.Template;
|
||||
const String path = Globals::EngineContentFolder / TEXT("Editor/MaterialTemplates/") + Data.Template;
|
||||
String contents;
|
||||
if (File::ReadAllText(path, contents))
|
||||
{
|
||||
@@ -188,17 +188,20 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
|
||||
ADD_FEATURE(LightmapFeature);
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == 0)
|
||||
ADD_FEATURE(DistortionFeature);
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque)
|
||||
ADD_FEATURE(ForwardShadingFeature);
|
||||
break;
|
||||
case MaterialDomain::Terrain:
|
||||
if (materialInfo.TessellationMode != TessellationMethod::None)
|
||||
ADD_FEATURE(TessellationFeature);
|
||||
ADD_FEATURE(LightmapFeature);
|
||||
break;
|
||||
default:
|
||||
case MaterialDomain::Particle:
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == 0)
|
||||
ADD_FEATURE(DistortionFeature);
|
||||
ADD_FEATURE(ForwardShadingFeature);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#undef ADD_FEATURE
|
||||
@@ -390,18 +393,14 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
|
||||
int32 srv = 0;
|
||||
switch (baseLayer->Domain)
|
||||
{
|
||||
case MaterialDomain::Surface:
|
||||
if (materialInfo.BlendMode != MaterialBlendMode::Opaque)
|
||||
srv = 3; // Forward shading resources
|
||||
break;
|
||||
case MaterialDomain::Decal:
|
||||
srv = 1;
|
||||
srv = 1; // Depth buffer
|
||||
break;
|
||||
case MaterialDomain::Terrain:
|
||||
srv = 3; // Heightmap + 2 splatmaps
|
||||
break;
|
||||
case MaterialDomain::Particle:
|
||||
srv = 5;
|
||||
srv = 2; // Particles data + Sorted indices/Ribbon segments
|
||||
break;
|
||||
}
|
||||
for (auto f : features)
|
||||
|
||||
Reference in New Issue
Block a user