envprobe: ocean and recursive reflection support (#1556)
This commit is contained in:
@@ -10,7 +10,7 @@ class nullbuf_t : public std::streambuf
|
||||
{
|
||||
protected:
|
||||
virtual int_type overflow(int_type ch) override
|
||||
{
|
||||
{
|
||||
return traits_type::not_eof(ch);
|
||||
}
|
||||
} nullbuf;
|
||||
@@ -174,8 +174,6 @@ wi::vector<ShaderEntry> shaders = {
|
||||
{"shadingRateClassificationCS", wi::graphics::ShaderStage::CS },
|
||||
{"shadingRateClassificationCS_DEBUG", wi::graphics::ShaderStage::CS },
|
||||
{"aerialPerspectiveCS", wi::graphics::ShaderStage::CS },
|
||||
{"aerialPerspectiveCS_capture", wi::graphics::ShaderStage::CS },
|
||||
{"aerialPerspectiveCS_capture_MSAA", wi::graphics::ShaderStage::CS },
|
||||
{"skyAtmosphere_cameraVolumeLutCS", wi::graphics::ShaderStage::CS },
|
||||
{"skyAtmosphere_transmittanceLutCS", wi::graphics::ShaderStage::CS },
|
||||
{"skyAtmosphere_skyViewLutCS", wi::graphics::ShaderStage::CS },
|
||||
@@ -230,6 +228,7 @@ wi::vector<ShaderEntry> shaders = {
|
||||
{"imagePS", wi::graphics::ShaderStage::PS },
|
||||
{"emittedparticlePS_soft_lighting", wi::graphics::ShaderStage::PS },
|
||||
{"oceanSurfacePS", wi::graphics::ShaderStage::PS },
|
||||
{"oceanSurfacePS_envmap", wi::graphics::ShaderStage::PS },
|
||||
{"hairparticlePS", wi::graphics::ShaderStage::PS },
|
||||
{"hairparticlePS_simple", wi::graphics::ShaderStage::PS },
|
||||
{"hairparticlePS_prepass", wi::graphics::ShaderStage::PS },
|
||||
|
||||
@@ -1421,6 +1421,7 @@ struct alignas(16) ShaderCamera
|
||||
position = {};
|
||||
output_index = 0;
|
||||
clip_plane = {};
|
||||
reflection_plane = float4(0, 1, 0, 0);
|
||||
forward = {};
|
||||
z_near = {};
|
||||
up = {};
|
||||
|
||||
@@ -345,6 +345,7 @@
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)objectPS_prepass_depthonly_alphatest.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)oceanSurfacePS_envmap.hlsl" />
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)paintdecalPS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
|
||||
</FxCompile>
|
||||
@@ -738,8 +739,6 @@
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Compute</ShaderType>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)aerialPerspectiveCS.hlsl" />
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)aerialPerspectiveCS_capture.hlsl" />
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)aerialPerspectiveCS_capture_MSAA.hlsl" />
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)skyAtmosphere_cameraVolumeLutCS.hlsl" />
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)skyAtmosphere_skyLuminanceLutCS.hlsl">
|
||||
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compute</ShaderType>
|
||||
|
||||
@@ -977,12 +977,6 @@
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)skyAtmosphere_cameraVolumeLutCS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)aerialPerspectiveCS_capture.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)aerialPerspectiveCS_capture_MSAA.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)windCS.hlsl">
|
||||
<Filter>CS</Filter>
|
||||
</FxCompile>
|
||||
@@ -1139,6 +1133,9 @@
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)voxelgridVS.hlsl">
|
||||
<Filter>VS</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="$(MSBuildThisFileDirectory)oceanSurfacePS_envmap.hlsl">
|
||||
<Filter>PS</Filter>
|
||||
</FxCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ShaderInterop.h">
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#define AERIALPERSPECTIVE_CAPTURE
|
||||
#include "aerialPerspectiveCS.hlsl"
|
||||
@@ -1,2 +0,0 @@
|
||||
#define MSAA
|
||||
#include "aerialPerspectiveCS_capture.hlsl"
|
||||
@@ -545,16 +545,6 @@ inline half3 GetAmbient(in float3 N)
|
||||
{
|
||||
half3 ambient;
|
||||
|
||||
#ifdef ENVMAPRENDERING
|
||||
|
||||
// Set realistic_sky_stationary to true so we capture ambient at float3(0.0, 0.0, 0.0), similar to the standard sky to avoid flickering and weird behavior
|
||||
ambient = lerp(
|
||||
GetDynamicSkyColor(float3(0, -1, 0), false, false, true),
|
||||
GetDynamicSkyColor(float3(0, 1, 0), false, false, true),
|
||||
saturate(N.y * 0.5 + 0.5));
|
||||
|
||||
#else
|
||||
|
||||
[branch]
|
||||
if (GetScene().globalprobe >= 0)
|
||||
{
|
||||
@@ -564,8 +554,6 @@ inline half3 GetAmbient(in float3 N)
|
||||
cubemap.GetDimensions(0, dim.x, dim.y, mipcount);
|
||||
ambient = cubemap.SampleLevel(sampler_linear_clamp, N, mipcount).rgb;
|
||||
}
|
||||
|
||||
#endif // ENVMAPRENDERING
|
||||
|
||||
#ifndef NO_FLAT_AMBIENT
|
||||
// This is not entirely correct if we have probes, because it shouldn't be added twice.
|
||||
@@ -583,20 +571,6 @@ inline half3 GetAmbient(in float3 N)
|
||||
inline half3 EnvironmentReflection_Global(in Surface surface)
|
||||
{
|
||||
half3 envColor;
|
||||
|
||||
#ifdef ENVMAPRENDERING
|
||||
|
||||
// There is no access to envmaps, so approximate sky color:
|
||||
// Set realistic_sky_stationary to true so we capture environment at float3(0.0, 0.0, 0.0), similar to the standard sky to avoid flickering and weird behavior
|
||||
float3 skycolor_real = GetDynamicSkyColor(surface.R, false, false, true); // false: disable sun disk and clouds
|
||||
float3 skycolor_rough = lerp(
|
||||
GetDynamicSkyColor(float3(0, -1, 0), false, false, true),
|
||||
GetDynamicSkyColor(float3(0, 1, 0), false, false, true),
|
||||
saturate(surface.R.y * 0.5 + 0.5));
|
||||
|
||||
envColor = lerp(skycolor_real, skycolor_rough, surface.roughness) * surface.F;
|
||||
|
||||
#else
|
||||
|
||||
[branch]
|
||||
if (GetScene().globalprobe < 0)
|
||||
@@ -623,8 +597,6 @@ inline half3 EnvironmentReflection_Global(in Surface surface)
|
||||
envColor += cubemap.SampleLevel(sampler_linear_clamp, surface.clearcoat.R, MIP).rgb * surface.clearcoat.F;
|
||||
#endif // CLEARCOAT
|
||||
|
||||
#endif // ENVMAPRENDERING
|
||||
|
||||
return envColor;
|
||||
}
|
||||
|
||||
|
||||
@@ -808,11 +808,11 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace APPEND_COVER
|
||||
|
||||
#ifdef OBJECTSHADER_USE_COMMON
|
||||
half wet = input.ao_wet.y;
|
||||
if(wet > 0)
|
||||
if (wet > 0)
|
||||
{
|
||||
surface.albedo = lerp(surface.albedo, 0, wet);
|
||||
surface.roughness = clamp(surface.roughness * sqr(1 - wet), 0.01, 1);
|
||||
surface.N = normalize(lerp(surface.N, input.nor, wet));
|
||||
surface.albedo = lerp(surface.albedo, 0, wet); // darken color when wet
|
||||
surface.roughness = clamp(surface.roughness * saturate(sqr((1 - wet) * 2 - 1)), 0.01, 1); // decrease eoughness when wet, but only at shoreline, not deeper underwater (sand underwater shouldn't be shiny)
|
||||
surface.N = normalize(lerp(surface.N, input.nor, wet)); // blend to vertex normal when wet
|
||||
}
|
||||
#endif // OBJECTSHADER_USE_COMMON
|
||||
|
||||
@@ -1116,9 +1116,9 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace APPEND_COVER
|
||||
|
||||
// Transparent objects has been rendered separately from opaque, so let's apply it now.
|
||||
// Must also be applied before fog since fog is layered over.
|
||||
#ifdef TRANSPARENT
|
||||
#if defined(TRANSPARENT) || defined(ENVMAPRENDERING)
|
||||
ApplyAerialPerspective(ScreenCoord, surface.P, color);
|
||||
#endif // TRANSPARENT
|
||||
#endif // defined(TRANSPARENT) || defined(ENVMAPRENDERING)
|
||||
|
||||
|
||||
ApplyFog(dist, surface.V, color);
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
|
||||
struct PSIn
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
min16uint cameraIndex : CAMERAINDEX;
|
||||
|
||||
inline float3 GetPos3D()
|
||||
{
|
||||
return GetCamera().screen_to_world(pos);
|
||||
return GetCameraIndexed(cameraIndex).screen_to_world(pos);
|
||||
}
|
||||
|
||||
inline float3 GetViewVector()
|
||||
{
|
||||
return GetCamera().screen_to_nearplane(pos) - GetPos3D(); // ortho support, cannot use cameraPos!
|
||||
return GetCameraIndexed(cameraIndex).screen_to_nearplane(pos) - GetPos3D(); // ortho support, cannot use cameraPos!
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -14,9 +14,10 @@ Texture2D<float4> texture_gradientmap : register(t1);
|
||||
[earlydepthstencil]
|
||||
float4 main(PSIn input) : SV_TARGET
|
||||
{
|
||||
float lineardepth = GetCamera().IsOrtho() ? ((1 - input.pos.z) * GetCamera().z_far) : input.pos.w;
|
||||
ShaderCamera camera = GetCameraIndexed(input.cameraIndex);
|
||||
float lineardepth = camera.IsOrtho() ? ((1 - input.pos.z) * camera.z_far) : input.pos.w;
|
||||
half4 color = xOceanWaterColor;
|
||||
float2 ScreenCoord = input.pos.xy * GetCamera().internal_resolution_rcp;
|
||||
float2 ScreenCoord = input.pos.xy * camera.internal_resolution_rcp;
|
||||
|
||||
float3 V = input.GetViewVector();
|
||||
float dist = length(V);
|
||||
@@ -30,9 +31,9 @@ float4 main(PSIn input) : SV_TARGET
|
||||
half4 gradient = lerp(gradientNear, gradientFar, gradient_fade);
|
||||
|
||||
[branch]
|
||||
if (GetCamera().texture_waterriples_index >= 0)
|
||||
if (camera.texture_waterriples_index >= 0)
|
||||
{
|
||||
gradient.rg += bindless_textures_half4[descriptor_index(GetCamera().texture_waterriples_index)].SampleLevel(sampler_linear_clamp, ScreenCoord, 0).rg * 0.025;
|
||||
gradient.rg += bindless_textures_half4[descriptor_index(camera.texture_waterriples_index)].SampleLevel(sampler_linear_clamp, ScreenCoord, 0).rg * 0.025;
|
||||
}
|
||||
|
||||
Surface surface;
|
||||
@@ -54,24 +55,28 @@ float4 main(PSIn input) : SV_TARGET
|
||||
Lighting lighting;
|
||||
lighting.create(0, 0, GetAmbient(surface.N), 0);
|
||||
|
||||
#ifdef FORWARD
|
||||
ForwardLighting(surface, lighting);
|
||||
#else
|
||||
TiledLighting(surface, lighting, GetFlatTileIndex(pixel));
|
||||
#endif // FORWARD
|
||||
|
||||
const float bump_strength = 0.1;
|
||||
|
||||
float4 water_plane = GetCamera().reflection_plane;
|
||||
float4 water_plane = camera.reflection_plane;
|
||||
|
||||
[branch]
|
||||
if (GetCamera().texture_reflection_index >= 0)
|
||||
if (camera.texture_reflection_index >= 0)
|
||||
{
|
||||
//REFLECTION
|
||||
float4 reflectionPos = mul(GetCamera().reflection_view_projection, float4(surface.P, 1));
|
||||
float4 reflectionPos = mul(camera.reflection_view_projection, float4(surface.P, 1));
|
||||
float2 reflectionUV = clipspace_to_uv(reflectionPos.xy / reflectionPos.w) + surface.N.xz * bump_strength;
|
||||
half4 reflectiveColor = bindless_textures[descriptor_index(GetCamera().texture_reflection_index)].SampleLevel(sampler_linear_mirror, reflectionUV, 0);
|
||||
half4 reflectiveColor = bindless_textures[descriptor_index(camera.texture_reflection_index)].SampleLevel(sampler_linear_mirror, reflectionUV, 0);
|
||||
[branch]
|
||||
if(GetCamera().texture_reflection_depth_index >=0)
|
||||
if(camera.texture_reflection_depth_index >=0)
|
||||
{
|
||||
float reflectiveDepth = bindless_textures[descriptor_index(GetCamera().texture_reflection_depth_index)].SampleLevel(sampler_point_clamp, reflectionUV, 0).r;
|
||||
float3 reflectivePosition = reconstruct_position(reflectionUV, reflectiveDepth, GetCamera().reflection_inverse_view_projection);
|
||||
float reflectiveDepth = bindless_textures[descriptor_index(camera.texture_reflection_depth_index)].SampleLevel(sampler_point_clamp, reflectionUV, 0).r;
|
||||
float3 reflectivePosition = reconstruct_position(reflectionUV, reflectiveDepth, camera.reflection_inverse_view_projection);
|
||||
float water_depth = -dot(float4(reflectivePosition, 1), water_plane);
|
||||
water_depth += texture_ocean_displacementmap.SampleLevel(sampler_linear_wrap, reflectivePosition.xz * xOceanPatchSizeRecip, 0).z; // texture contains xzy!
|
||||
reflectiveColor.rgb = lerp(color.rgb, reflectiveColor.rgb, saturate(exp(-water_depth * color.a)));
|
||||
@@ -86,11 +91,11 @@ float4 main(PSIn input) : SV_TARGET
|
||||
float water_depth = FLT_MAX;
|
||||
|
||||
[branch]
|
||||
if (GetCamera().texture_refraction_index >= 0)
|
||||
if (camera.texture_refraction_index >= 0)
|
||||
{
|
||||
// Water refraction:
|
||||
const float camera_above_water = dot(float4(GetCamera().position, 1), water_plane) < 0;
|
||||
Texture2D texture_refraction = bindless_textures[descriptor_index(GetCamera().texture_refraction_index)];
|
||||
const float camera_above_water = dot(float4(camera.position, 1), water_plane) < 0;
|
||||
Texture2D texture_refraction = bindless_textures[descriptor_index(camera.texture_refraction_index)];
|
||||
// First sample using full perturbation:
|
||||
float2 refraction_uv = ScreenCoord.xy + surface.N.xz * bump_strength;
|
||||
float refraction_depth = find_max_depth(refraction_uv, 2, 2);
|
||||
@@ -126,33 +131,37 @@ float4 main(PSIn input) : SV_TARGET
|
||||
}
|
||||
|
||||
#if 1
|
||||
// FOAM:
|
||||
float water_depth_diff = abs(texture_lineardepth[pixel] * GetCamera().z_far - lineardepth); // Note: for the shore foam, this is more accurate than water plane distance
|
||||
float foam_shore = saturate(exp(-water_depth_diff * 2));
|
||||
float foam_wave = pow(saturate(gradient.a), 4) * saturate(exp(-water_depth * 0.1));
|
||||
float foam_combined = saturate(foam_shore + foam_wave);
|
||||
float foam_simplex = 0;
|
||||
foam_simplex += smoothstep(0, 0.8, noise_simplex_2D(surface.P.xz * 1 + GetTime()));
|
||||
foam_simplex += smoothstep(0, 0.8, noise_simplex_2D(surface.P.xz * 2 + GetTime()));
|
||||
foam_simplex += smoothstep(0, 0.8, noise_simplex_2D(surface.P.zx * 4 - GetTime() * 2));
|
||||
float foam_voronoi = 0;
|
||||
foam_voronoi += smoothstep(0.5, 0.8, noise_voronoi(surface.P.xz * 1, GetTime()).x);
|
||||
foam_voronoi += smoothstep(0.5, 0.8, noise_voronoi(surface.P.xz * 2, GetTime()).x);
|
||||
foam_voronoi += smoothstep(0.5, 0.8, noise_voronoi(surface.P.xz * 4, GetTime()).x);
|
||||
float foam = 0;
|
||||
foam += foam_voronoi * foam_simplex * foam_combined;
|
||||
foam += smoothstep(0.5, 0.6, saturate(foam_combined + 0.1));
|
||||
foam *= 2;
|
||||
foam = saturate(foam);
|
||||
surface.albedo = lerp(surface.albedo, 0.6, foam);
|
||||
surface.refraction.a *= 1 - foam;
|
||||
surface.refraction.a = saturate(surface.refraction.a + saturate(exp(-water_depth_diff * 4)));
|
||||
[branch]
|
||||
if (camera.texture_lineardepth_index >= 0)
|
||||
{
|
||||
// FOAM:
|
||||
float water_depth_diff = abs(texture_lineardepth[pixel] * camera.z_far - lineardepth); // Note: for the shore foam, this is more accurate than water plane distance
|
||||
float foam_shore = saturate(exp(-water_depth_diff * 2));
|
||||
float foam_wave = pow(saturate(gradient.a), 4) * saturate(exp(-water_depth * 0.1));
|
||||
float foam_combined = saturate(foam_shore + foam_wave);
|
||||
float foam_simplex = 0;
|
||||
foam_simplex += smoothstep(0, 0.8, noise_simplex_2D(surface.P.xz * 1 + GetTime()));
|
||||
foam_simplex += smoothstep(0, 0.8, noise_simplex_2D(surface.P.xz * 2 + GetTime()));
|
||||
foam_simplex += smoothstep(0, 0.8, noise_simplex_2D(surface.P.zx * 4 - GetTime() * 2));
|
||||
float foam_voronoi = 0;
|
||||
foam_voronoi += smoothstep(0.5, 0.8, noise_voronoi(surface.P.xz * 1, GetTime()).x);
|
||||
foam_voronoi += smoothstep(0.5, 0.8, noise_voronoi(surface.P.xz * 2, GetTime()).x);
|
||||
foam_voronoi += smoothstep(0.5, 0.8, noise_voronoi(surface.P.xz * 4, GetTime()).x);
|
||||
float foam = 0;
|
||||
foam += foam_voronoi * foam_simplex * foam_combined;
|
||||
foam += smoothstep(0.5, 0.6, saturate(foam_combined + 0.1));
|
||||
foam *= 2;
|
||||
foam = saturate(foam);
|
||||
surface.albedo = lerp(surface.albedo, 0.6, foam);
|
||||
surface.refraction.a *= 1 - foam;
|
||||
surface.refraction.a = saturate(surface.refraction.a + saturate(exp(-water_depth_diff * 4)));
|
||||
}
|
||||
#endif
|
||||
|
||||
ApplyLighting(surface, lighting, color);
|
||||
|
||||
// Blend out at distance:
|
||||
color.a = saturate(1 - saturate(dist / GetCamera().z_far - 0.8) * 5.0); // fade will be on edge and inwards 20%
|
||||
color.a = saturate(1 - saturate(dist / camera.z_far - 0.8) * 5.0); // fade will be on edge and inwards 20%
|
||||
|
||||
ApplyAerialPerspective(ScreenCoord, surface.P, color);
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#define ENVMAPRENDERING
|
||||
#define FORWARD
|
||||
#include "oceanSurfacePS.hlsl"
|
||||
@@ -3,9 +3,13 @@
|
||||
|
||||
Texture2D<float4> texture_displacementmap : register(t0);
|
||||
|
||||
PSIn main(uint vertexID : SV_VertexID)
|
||||
PSIn main(uint vertexID : SV_VertexID, uint instanceID : SV_InstanceID, out uint RTIndex : SV_RenderTargetArrayIndex)
|
||||
{
|
||||
PSIn Out;
|
||||
Out.cameraIndex = instanceID;
|
||||
|
||||
ShaderCamera camera = GetCameraIndexed(Out.cameraIndex);
|
||||
RTIndex = camera.output_index;
|
||||
|
||||
float2 dim = xOceanScreenSpaceParams.xy;
|
||||
float2 invdim = xOceanScreenSpaceParams.zw;
|
||||
@@ -18,9 +22,9 @@ PSIn main(uint vertexID : SV_VertexID)
|
||||
Out.pos.xy *= max(1, xOceanSurfaceDisplacementTolerance); // extrude screen space grid to tolerate displacement
|
||||
|
||||
// Perform ray tracing of screen grid and plane surface to unproject to world space:
|
||||
float4 unprojNEAR = mul(GetCamera().inverse_view_projection, float4(Out.pos.xy, 1, 1));
|
||||
float4 unprojNEAR = mul(camera.inverse_view_projection, float4(Out.pos.xy, 1, 1));
|
||||
unprojNEAR.xyz /= unprojNEAR.w;
|
||||
float4 unprojFAR = mul(GetCamera().inverse_view_projection, float4(Out.pos.xy, 0, 1));
|
||||
float4 unprojFAR = mul(camera.inverse_view_projection, float4(Out.pos.xy, 0, 1));
|
||||
unprojFAR.xyz /= unprojFAR.w;
|
||||
const float3 d = normalize(unprojNEAR.xyz - unprojFAR.xyz);
|
||||
const float3 o = unprojNEAR.xyz;
|
||||
@@ -32,13 +36,13 @@ PSIn main(uint vertexID : SV_VertexID)
|
||||
{
|
||||
// Displace surface:
|
||||
float3 displacement = texture_displacementmap.SampleLevel(sampler_linear_wrap, uv, 0).xzy;
|
||||
float dist = length(worldPos - GetCamera().position);
|
||||
displacement *= saturate(1 - saturate(dist / GetCamera().z_far - 0.8) * 5.0); // fade will be on edge and inwards 20%
|
||||
float dist = length(worldPos - camera.position);
|
||||
displacement *= saturate(1 - saturate(dist / camera.z_far - 0.8) * 5.0); // fade will be on edge and inwards 20%
|
||||
worldPos += displacement;
|
||||
}
|
||||
|
||||
// Reproject displaced surface and output:
|
||||
Out.pos = mul(GetCamera().view_projection, float4(worldPos, 1));
|
||||
Out.pos = mul(camera.view_projection, float4(worldPos, 1));
|
||||
Out.uv = uv;
|
||||
|
||||
return Out;
|
||||
|
||||
@@ -48,7 +48,6 @@ inline void ForwardLighting(inout Surface surface, inout Lighting lighting)
|
||||
// Apply environment maps:
|
||||
half4 envmapAccumulation = 0;
|
||||
|
||||
#ifndef ENVMAPRENDERING
|
||||
#ifndef DISABLE_LOCALENVPMAPS
|
||||
[branch]
|
||||
if (xForwardEnvProbeMask != 0)
|
||||
@@ -91,7 +90,6 @@ inline void ForwardLighting(inout Surface surface, inout Lighting lighting)
|
||||
}
|
||||
}
|
||||
#endif // DISABLE_LOCALENVPMAPS
|
||||
#endif //ENVMAPRENDERING
|
||||
|
||||
// Apply global envmap where there is no local envmap information:
|
||||
[branch]
|
||||
@@ -288,9 +286,7 @@ inline uint GetFlatTileIndex(min16uint2 pixel)
|
||||
inline void TiledLighting(inout Surface surface, inout Lighting lighting, uint flatTileIndex)
|
||||
{
|
||||
if (GetFrame().options & OPTION_BIT_FORCE_UNLIT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_ENVMAPS
|
||||
// Apply environment maps:
|
||||
|
||||
@@ -208,16 +208,12 @@ struct Surface
|
||||
}
|
||||
f0 = material.GetSpecular() * specularMap.rgb * specularMap.a;
|
||||
|
||||
#ifndef ENVMAPRENDERING
|
||||
if (GetFrame().options & OPTION_BIT_FORCE_DIFFUSE_LIGHTING)
|
||||
#endif // ENVMAPRENDERING
|
||||
{
|
||||
f0 = surfaceMap.b = surfaceMap.a = 0;
|
||||
}
|
||||
|
||||
#ifndef ENVMAPRENDERING
|
||||
if (GetFrame().options & OPTION_BIT_FORCE_UNLIT)
|
||||
#endif // ENVMAPRENDERING
|
||||
{
|
||||
albedo = baseColor.rgb;
|
||||
}
|
||||
@@ -308,9 +304,7 @@ struct Surface
|
||||
F = smoothstep(0.1, 0.5, F);
|
||||
#endif // CARTOON
|
||||
|
||||
#ifndef ENVMAPRENDERING
|
||||
if (GetFrame().options & OPTION_BIT_FORCE_DIFFUSE_LIGHTING || GetFrame().options & OPTION_BIT_FORCE_UNLIT)
|
||||
#endif // ENVMAPRENDERING
|
||||
{
|
||||
F = 0;
|
||||
}
|
||||
|
||||
@@ -321,8 +321,6 @@ namespace wi::enums
|
||||
CSTYPE_POSTPROCESS_MOTIONBLUR_CHEAP,
|
||||
CSTYPE_POSTPROCESS_BLOOMSEPARATE,
|
||||
CSTYPE_POSTPROCESS_AERIALPERSPECTIVE,
|
||||
CSTYPE_POSTPROCESS_AERIALPERSPECTIVE_CAPTURE,
|
||||
CSTYPE_POSTPROCESS_AERIALPERSPECTIVE_CAPTURE_MSAA,
|
||||
CSTYPE_POSTPROCESS_VOLUMETRICCLOUDS_SHAPENOISE,
|
||||
CSTYPE_POSTPROCESS_VOLUMETRICCLOUDS_DETAILNOISE,
|
||||
CSTYPE_POSTPROCESS_VOLUMETRICCLOUDS_CURLNOISE,
|
||||
|
||||
@@ -285,6 +285,22 @@ namespace wi::graphics
|
||||
return CreateBufferCleared(desc, 0, buffer, alias, alias_offset);
|
||||
}
|
||||
|
||||
// This can be used to create a texture filled with a single value
|
||||
bool CreateTextureCleared(const TextureDesc* desc, uint8_t value, Texture* texture, const GPUResource* alias = nullptr, uint64_t alias_offset = 0ull) const
|
||||
{
|
||||
wi::vector<uint8_t> texturedata(ComputeTextureMemorySizeInBytes(*desc));
|
||||
std::fill(texturedata.begin(), texturedata.end(), value);
|
||||
wi::vector<SubresourceData> initdata;
|
||||
CreateTextureSubresourceDatas(*desc, texturedata.data(), initdata);
|
||||
return CreateTexture(desc, initdata.data(), texture, alias, alias_offset);
|
||||
}
|
||||
|
||||
// This can be used to create a texture filled with zeroes
|
||||
bool CreateTextureZeroed(const TextureDesc* desc, Texture* texture, const GPUResource* alias = nullptr, uint64_t alias_offset = 0ull) const
|
||||
{
|
||||
return CreateTextureCleared(desc, 0, texture, alias, alias_offset);
|
||||
}
|
||||
|
||||
// Execute a single GPU barrier
|
||||
void Barrier(const GPUBarrier& barrier, CommandList cmd)
|
||||
{
|
||||
|
||||
@@ -24,13 +24,14 @@ namespace wi
|
||||
Shader oceanSurfVS;
|
||||
Shader wireframePS;
|
||||
Shader oceanSurfPS;
|
||||
Shader oceanSurfPS_envmap;
|
||||
|
||||
RasterizerState rasterizerState;
|
||||
RasterizerState wireRS;
|
||||
DepthStencilState depthStencilState, depthStencilState_occlusionTest;
|
||||
BlendState blendState, blendState_occlusionTest;
|
||||
|
||||
PipelineState PSO, PSO_wire, PSO_occlusionTest;
|
||||
PipelineState PSO, PSO_envmap, PSO_wire, PSO_occlusionTest;
|
||||
|
||||
|
||||
void LoadShaders()
|
||||
@@ -42,6 +43,7 @@ namespace wi
|
||||
wi::renderer::LoadShader(ShaderStage::VS, oceanSurfVS, "oceanSurfaceVS.cso");
|
||||
|
||||
wi::renderer::LoadShader(ShaderStage::PS, oceanSurfPS, "oceanSurfacePS.cso");
|
||||
wi::renderer::LoadShader(ShaderStage::PS, oceanSurfPS_envmap, "oceanSurfacePS_envmap.cso");
|
||||
wi::renderer::LoadShader(ShaderStage::PS, wireframePS, "oceanSurfaceSimplePS.cso");
|
||||
|
||||
|
||||
@@ -56,6 +58,9 @@ namespace wi
|
||||
desc.dss = &depthStencilState;
|
||||
device->CreatePipelineState(&desc, &PSO);
|
||||
|
||||
desc.ps = &oceanSurfPS_envmap;
|
||||
device->CreatePipelineState(&desc, &PSO_envmap);
|
||||
|
||||
desc.ps = &wireframePS;
|
||||
desc.rs = &wireRS;
|
||||
device->CreatePipelineState(&desc, &PSO_wire);
|
||||
@@ -474,6 +479,63 @@ namespace wi
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
|
||||
void Ocean::RenderForCubemap(CommandList cmd) const
|
||||
{
|
||||
GraphicsDevice* device = wi::graphics::GetDevice();
|
||||
|
||||
device->EventBegin("Ocean Rendering into Cubemap", cmd);
|
||||
|
||||
const uint2 dim = uint2(64, 64);
|
||||
const uint index_count = dim.x * dim.y * 6;
|
||||
const uint64_t indexbuffer_required_size = index_count * sizeof(uint16_t);
|
||||
static std::mutex locker;
|
||||
locker.lock(); // in case two threads draw the ocean the same time, index buffer creation must be locked
|
||||
if (indexBuffer_cubemap.GetDesc().size != indexbuffer_required_size)
|
||||
{
|
||||
wi::vector<uint16_t> index_data(index_count);
|
||||
size_t counter = 0;
|
||||
for (uint16_t x = 0; x < dim.x - 1; x++)
|
||||
{
|
||||
for (uint16_t y = 0; y < dim.y - 1; y++)
|
||||
{
|
||||
uint16_t lowerLeft = x + y * dim.x;
|
||||
uint16_t lowerRight = (x + 1) + y * dim.x;
|
||||
uint16_t topLeft = x + (y + 1) * dim.x;
|
||||
uint16_t topRight = (x + 1) + (y + 1) * dim.x;
|
||||
|
||||
index_data[counter++] = topLeft;
|
||||
index_data[counter++] = lowerLeft;
|
||||
index_data[counter++] = lowerRight;
|
||||
|
||||
index_data[counter++] = topLeft;
|
||||
index_data[counter++] = lowerRight;
|
||||
index_data[counter++] = topRight;
|
||||
}
|
||||
}
|
||||
|
||||
GPUBufferDesc desc;
|
||||
desc.bind_flags = BindFlag::INDEX_BUFFER;
|
||||
desc.size = indexbuffer_required_size;
|
||||
device->CreateBuffer(&desc, index_data.data(), &indexBuffer_cubemap);
|
||||
device->SetName(&indexBuffer_cubemap, "Ocean::indexBuffer_cubemap");
|
||||
}
|
||||
locker.unlock();
|
||||
|
||||
device->BindPipelineState(&PSO_envmap, cmd);
|
||||
|
||||
OceanCB cb = GetOceanCBAtDim(params, dim);
|
||||
device->BindDynamicConstantBuffer(cb, CB_GETBINDSLOT(OceanCB), cmd);
|
||||
|
||||
device->BindResource(&displacementMap, 0, cmd);
|
||||
device->BindResource(&gradientMap, 1, cmd);
|
||||
|
||||
device->BindIndexBuffer(&indexBuffer_cubemap, IndexBufferFormat::UINT16, 0, cmd);
|
||||
|
||||
device->DrawIndexedInstanced(index_count, 6, 0, 0, 0, cmd); // 6 instance for each cube side
|
||||
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
|
||||
void Ocean::Render(const CameraComponent& camera, CommandList cmd) const
|
||||
{
|
||||
GraphicsDevice* device = wi::graphics::GetDevice();
|
||||
@@ -605,4 +667,11 @@ namespace wi
|
||||
return &gradientMap;
|
||||
}
|
||||
|
||||
const wi::primitive::AABB Ocean::GetAABB(const XMFLOAT3& camera_pos) const
|
||||
{
|
||||
wi::primitive::AABB aabb;
|
||||
aabb.createFromHalfWidth(XMFLOAT3(camera_pos.x, params.waterHeight, camera_pos.z), XMFLOAT3(1000, 10, 1000));
|
||||
return aabb;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "wiFFTGenerator.h"
|
||||
#include "wiScene_Decl.h"
|
||||
#include "wiMath.h"
|
||||
#include "wiPrimitive.h"
|
||||
|
||||
namespace wi
|
||||
{
|
||||
@@ -42,6 +43,7 @@ namespace wi
|
||||
|
||||
void UpdateDisplacementMap(wi::graphics::CommandList cmd) const;
|
||||
void RenderForOcclusionTest(const wi::scene::CameraComponent& camera, wi::graphics::CommandList cmd) const;
|
||||
void RenderForCubemap(wi::graphics::CommandList cmd) const;
|
||||
void Render(const wi::scene::CameraComponent& camera, wi::graphics::CommandList cmd) const;
|
||||
|
||||
void CopyDisplacementMapReadback(wi::graphics::CommandList cmd) const;
|
||||
@@ -49,6 +51,8 @@ namespace wi
|
||||
const wi::graphics::Texture* getDisplacementMap() const;
|
||||
const wi::graphics::Texture* getGradientMap() const;
|
||||
|
||||
const wi::primitive::AABB GetAABB(const XMFLOAT3& camera_pos) const;
|
||||
|
||||
static void Initialize();
|
||||
|
||||
bool IsValid() const { return displacementMap.IsValid(); }
|
||||
@@ -97,5 +101,6 @@ namespace wi
|
||||
wi::graphics::GPUBuffer constantBuffer;
|
||||
mutable wi::graphics::GPUBuffer indexBuffer;
|
||||
mutable wi::graphics::GPUBuffer indexBuffer_occlusionTest;
|
||||
mutable wi::graphics::GPUBuffer indexBuffer_cubemap;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1241,6 +1241,10 @@ namespace wi
|
||||
cmd_updatetextures = device->BeginCommandList();
|
||||
cmd = cmd_updatetextures;
|
||||
device->WaitCommandList(cmd, cmd_prepareframe_async);
|
||||
if (cmd_ocean.IsValid())
|
||||
{
|
||||
device->WaitCommandList(cmd, cmd_ocean);
|
||||
}
|
||||
wi::jobsystem::Execute(ctx, [cmd, this](wi::jobsystem::JobArgs args) {
|
||||
wi::renderer::BindCommonResources(cmd);
|
||||
wi::renderer::BindCameraCB(
|
||||
|
||||
+25
-72
@@ -1055,8 +1055,6 @@ void LoadShaders()
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_MOTIONBLUR_CHEAP], "motionblurCS_cheap.cso"); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_BLOOMSEPARATE], "bloomseparateCS.cso"); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_AERIALPERSPECTIVE], "aerialPerspectiveCS.cso"); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_AERIALPERSPECTIVE_CAPTURE], "aerialPerspectiveCS_capture.cso"); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_AERIALPERSPECTIVE_CAPTURE_MSAA], "aerialPerspectiveCS_capture_MSAA.cso"); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_VOLUMETRICCLOUDS_SHAPENOISE], "volumetricCloud_shapenoiseCS.cso"); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_VOLUMETRICCLOUDS_DETAILNOISE], "volumetricCloud_detailnoiseCS.cso"); });
|
||||
wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::CS, shaders[CSTYPE_POSTPROCESS_VOLUMETRICCLOUDS_CURLNOISE], "volumetricCloud_curlnoiseCS.cso"); });
|
||||
@@ -3070,7 +3068,7 @@ inline void CreateCubemapCameras(const XMFLOAT3& position, float zNearP, float z
|
||||
shcams[5].init(position, XMFLOAT4(0, 0.707f, 0.707f, 0), zNearP, zFarP, XM_PIDIV2); //-z
|
||||
}
|
||||
|
||||
ForwardEntityMaskCB ForwardEntityCullingCPU(const Visibility& vis, const AABB& batch_aabb, RENDERPASS renderPass)
|
||||
ForwardEntityMaskCB ForwardEntityCullingCPU(const Visibility& vis, const AABB& batch_aabb)
|
||||
{
|
||||
// Performs CPU light culling for a renderable batch:
|
||||
// Similar to GPU-based tiled light culling, but this is only for simple forward passes (drawcall-granularity)
|
||||
@@ -3107,17 +3105,14 @@ ForwardEntityMaskCB ForwardEntityCullingCPU(const Visibility& vis, const AABB& b
|
||||
}
|
||||
}
|
||||
|
||||
if (renderPass != RENDERPASS_ENVMAPCAPTURE)
|
||||
for (size_t i = 0; i < std::min(size_t(32), vis.visibleEnvProbes.size()); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < std::min(size_t(32), vis.visibleEnvProbes.size()); ++i)
|
||||
const uint32_t probeIndex = vis.visibleEnvProbes[vis.visibleEnvProbes.size() - 1 - i]; // note: reverse order, for correct blending!
|
||||
const AABB& probe_aabb = vis.scene->aabb_probes[probeIndex];
|
||||
if (probe_aabb.intersects(batch_aabb))
|
||||
{
|
||||
const uint32_t probeIndex = vis.visibleEnvProbes[vis.visibleEnvProbes.size() - 1 - i]; // note: reverse order, for correct blending!
|
||||
const AABB& probe_aabb = vis.scene->aabb_probes[probeIndex];
|
||||
if (probe_aabb.intersects(batch_aabb))
|
||||
{
|
||||
const uint8_t bucket_place = uint8_t(i % 32);
|
||||
cb.xForwardEnvProbeMask |= 1 << bucket_place;
|
||||
}
|
||||
const uint8_t bucket_place = uint8_t(i % 32);
|
||||
cb.xForwardEnvProbeMask |= 1 << bucket_place;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3244,7 +3239,7 @@ void RenderMeshes(
|
||||
|
||||
if (forwardLightmaskRequest)
|
||||
{
|
||||
ForwardEntityMaskCB cb = ForwardEntityCullingCPU(vis, instancedBatch.aabb, renderPass);
|
||||
ForwardEntityMaskCB cb = ForwardEntityCullingCPU(vis, instancedBatch.aabb);
|
||||
device->BindDynamicConstantBuffer(cb, CB_GETBINDSLOT(ForwardEntityMaskCB), cmd);
|
||||
}
|
||||
|
||||
@@ -9109,12 +9104,9 @@ void RefreshEnvProbes(const Visibility& vis, CommandList cmd)
|
||||
desc.mip_levels = 1;
|
||||
desc.bind_flags = BindFlag::DEPTH_STENCIL | BindFlag::SHADER_RESOURCE;
|
||||
desc.format = format_depthbuffer_envprobe;
|
||||
desc.layout = ResourceState::SHADER_RESOURCE;
|
||||
desc.layout = ResourceState::DEPTHSTENCIL;
|
||||
desc.sample_count = required_sample_count;
|
||||
if (required_sample_count == 1)
|
||||
{
|
||||
desc.misc_flags = ResourceMiscFlag::TEXTURECUBE;
|
||||
}
|
||||
desc.misc_flags = ResourceMiscFlag::TRANSIENT_ATTACHMENT;
|
||||
device->CreateTexture(&desc, nullptr, &envrenderingDepthBuffer);
|
||||
device->SetName(&envrenderingDepthBuffer, "envrenderingDepthBuffer");
|
||||
render_textures[id_depth.raw] = envrenderingDepthBuffer;
|
||||
@@ -9249,10 +9241,7 @@ void RefreshEnvProbes(const Visibility& vis, CommandList cmd)
|
||||
RenderPassImage::DepthStencil(
|
||||
&envrenderingDepthBuffer,
|
||||
RenderPassImage::LoadOp::CLEAR,
|
||||
RenderPassImage::StoreOp::STORE,
|
||||
ResourceState::SHADER_RESOURCE,
|
||||
ResourceState::DEPTHSTENCIL,
|
||||
ResourceState::SHADER_RESOURCE
|
||||
RenderPassImage::StoreOp::DONTCARE
|
||||
),
|
||||
};
|
||||
device->RenderPassBegin(rp, arraysize(rp), cmd);
|
||||
@@ -9260,21 +9249,18 @@ void RefreshEnvProbes(const Visibility& vis, CommandList cmd)
|
||||
else
|
||||
{
|
||||
const RenderPassImage rp[] = {
|
||||
RenderPassImage::DepthStencil(
|
||||
&envrenderingDepthBuffer,
|
||||
RenderPassImage::LoadOp::CLEAR,
|
||||
RenderPassImage::StoreOp::STORE,
|
||||
ResourceState::SHADER_RESOURCE,
|
||||
ResourceState::DEPTHSTENCIL,
|
||||
ResourceState::SHADER_RESOURCE
|
||||
),
|
||||
RenderPassImage::RenderTarget(
|
||||
&envrenderingColorBuffer,
|
||||
RenderPassImage::LoadOp::CLEAR,
|
||||
RenderPassImage::StoreOp::STORE,
|
||||
ResourceState::SHADER_RESOURCE,
|
||||
ResourceState::SHADER_RESOURCE
|
||||
)
|
||||
),
|
||||
RenderPassImage::DepthStencil(
|
||||
&envrenderingDepthBuffer,
|
||||
RenderPassImage::LoadOp::CLEAR,
|
||||
RenderPassImage::StoreOp::DONTCARE
|
||||
),
|
||||
};
|
||||
device->RenderPassBegin(rp, arraysize(rp), cmd);
|
||||
}
|
||||
@@ -9333,6 +9319,14 @@ void RefreshEnvProbes(const Visibility& vis, CommandList cmd)
|
||||
device->DrawInstanced(240, 6, 0, 0, cmd); // 6 instances so it will be replicated for every cubemap face
|
||||
}
|
||||
|
||||
if (vis.scene->ocean.IsValid() && vis.scene->weather.IsOceanEnabled())
|
||||
{
|
||||
ForwardEntityMaskCB cb = ForwardEntityCullingCPU(vis, vis.scene->ocean.GetAABB(probe.position));
|
||||
device->BindDynamicConstantBuffer(cb, CB_GETBINDSLOT(ForwardEntityMaskCB), cmd);
|
||||
|
||||
vis.scene->ocean.RenderForCubemap(cmd);
|
||||
}
|
||||
|
||||
if (probe_aabb.layerMask & vis.layerMask) // only draw light visualizers if this is a hand placed probe
|
||||
{
|
||||
DrawLightVisualizers(vis, cmd, 6); // 6 instances so it will be replicated for every cubemap face
|
||||
@@ -9340,47 +9334,6 @@ void RefreshEnvProbes(const Visibility& vis, CommandList cmd)
|
||||
|
||||
device->RenderPassEnd(cmd);
|
||||
|
||||
// Compute Aerial Perspective for environment map
|
||||
if (vis.scene->weather.IsRealisticSky() && vis.scene->weather.IsRealisticSkyAerialPerspective() && (probe_aabb.layerMask & vis.layerMask))
|
||||
{
|
||||
if (probe.IsMSAA())
|
||||
{
|
||||
device->EventBegin("Aerial Perspective Capture [MSAA]", cmd);
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_AERIALPERSPECTIVE_CAPTURE_MSAA], cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
device->EventBegin("Aerial Perspective Capture", cmd);
|
||||
device->BindComputeShader(&shaders[CSTYPE_POSTPROCESS_AERIALPERSPECTIVE_CAPTURE], cmd);
|
||||
}
|
||||
|
||||
device->BindResource(&envrenderingDepthBuffer, 0, cmd);
|
||||
|
||||
TextureDesc desc = envrenderingColorBuffer.GetDesc();
|
||||
|
||||
AerialPerspectiveCapturePushConstants push = {};
|
||||
push.resolution.x = desc.width;
|
||||
push.resolution.y = desc.height;
|
||||
push.resolution_rcp.x = 1.0f / push.resolution.x;
|
||||
push.resolution_rcp.y = 1.0f / push.resolution.y;
|
||||
push.texture_output = device->GetDescriptorIndex(&envrenderingColorBuffer, SubresourceType::UAV);
|
||||
|
||||
device->PushConstants(&push, sizeof(push), cmd);
|
||||
|
||||
device->Barrier(GPUBarrier::Image(&envrenderingColorBuffer, ResourceState::SHADER_RESOURCE, ResourceState::UNORDERED_ACCESS), cmd);
|
||||
|
||||
device->Dispatch(
|
||||
(desc.width + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
(desc.height + POSTPROCESS_BLOCKSIZE - 1) / POSTPROCESS_BLOCKSIZE,
|
||||
6,
|
||||
cmd
|
||||
);
|
||||
|
||||
device->Barrier(GPUBarrier::Image(&envrenderingColorBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), cmd);
|
||||
|
||||
device->EventEnd(cmd);
|
||||
}
|
||||
|
||||
GenerateMipChain(envrenderingColorBuffer, MIPGENFILTER_LINEAR, cmd);
|
||||
|
||||
// Filter the enviroment map mip chain according to BRDF:
|
||||
|
||||
@@ -2313,7 +2313,7 @@ namespace wi::scene
|
||||
desc.mip_levels = GetMipCount(resolution, resolution, 1, 16);
|
||||
desc.misc_flags = ResourceMiscFlag::TEXTURECUBE;
|
||||
desc.layout = ResourceState::SHADER_RESOURCE;
|
||||
device->CreateTexture(&desc, nullptr, &texture);
|
||||
device->CreateTextureZeroed(&desc, &texture);
|
||||
device->SetName(&texture, "EnvironmentProbeComponent::texture");
|
||||
subresource = -1;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wi::version
|
||||
// minor features, major updates, breaking compatibility changes
|
||||
const int minor = 72;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 40;
|
||||
const int revision = 41;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user