diff --git a/HPL2/include/graphics/RendererDeferred2.h b/HPL2/include/graphics/RendererDeferred2.h index 067c10195..1bf62ee0c 100644 --- a/HPL2/include/graphics/RendererDeferred2.h +++ b/HPL2/include/graphics/RendererDeferred2.h @@ -181,7 +181,6 @@ namespace hpl { MaterialSet& resolveSet(MaterialSetType set); }; ResourceMaterial& resolveResourceMaterial(cMaterial* material); - uint32_t resolveObjectSlot(uint32_t uid, std::function initializeHandler); UniqueViewportData m_boundViewportData; @@ -219,16 +218,11 @@ namespace hpl { std::array m_indirectDrawArgsBuffer; std::array m_materialSampler; - folly::F14ValueMap m_objectDescriptorLookup; SharedTexture m_emptyTexture2D; SharedTexture m_emptyTextureCube; Image* m_dissolveImage; - uint32_t m_activeFrame = 0; - uint32_t m_objectIndex = 0; - uint32_t m_indirectDrawIndex = 0; - cRenderList m_rendererList; SharedRootSignature m_lightClusterRootSignature; @@ -265,10 +259,8 @@ namespace hpl { SharedShader m_translucencyRefractionShaderPremulAlpha; SharedShader m_translucencyIlluminationShaderAdd; - SharedShader m_translucencyIlluminationShaderMul; - SharedShader m_translucencyIlluminationShaderMulX2; - SharedShader m_translucencyIlluminationShaderAlpha; - SharedShader m_translucencyIlluminationShaderPremulAlpha; + + SharedShader m_translucencyWaterShader; struct BlendPipelines { SharedPipeline m_pipelineBlendAdd; @@ -309,13 +301,11 @@ namespace hpl { SharedPipeline m_translucencyIlluminationPipline; SharedPipeline m_translucencyIlluminationPiplineNoDepth; - - //BlendPipelines m_translucencyIlluminationPipline; - //BlendPipelines m_translucencyIlluminationPiplineNoDepth; + SharedPipeline m_translucencyWaterPipeline; + SharedPipeline m_translucencyWaterPipelineNoDepth; CopyTextureSubpass4 m_copySubpass; - // variables that are persistent for the frame struct TransientFrameVars { folly::F14ValueMap m_objectSlotIndex; diff --git a/HPL2/include/graphics/SceneResource.h b/HPL2/include/graphics/SceneResource.h index 12eaa042d..7590b20a1 100644 --- a/HPL2/include/graphics/SceneResource.h +++ b/HPL2/include/graphics/SceneResource.h @@ -5,6 +5,7 @@ #include "graphics/Material.h" #include "Common_3/Utilities/Math/MathTypes.h" +#include "math/cFrustum.h" #include #include @@ -48,9 +49,13 @@ namespace hpl::resource { uint32_t constexpr IsAlphaSingleChannel = 0x1; uint32_t constexpr IsHeightSingleChannel = 0x2; uint32_t constexpr UseAlphaDissolveFilter = 0x4; + uint32_t constexpr UseReflection = 0x8; + uint32_t constexpr UseRefraction = 0x16; struct ViewportInfo { static constexpr uint32_t PrmaryViewportIndex = 0; + static ViewportInfo create(cFrustum* frustum, float4 rect); + mat4 m_invViewMat; mat4 m_invProjMat; mat4 m_invViewProj; @@ -172,7 +177,7 @@ namespace hpl::resource { struct WaterMaterial { uint32_t m_diffuseTextureIndex; - uint32_t m_normalTextureIndex; + uint32_t m_normalTextureIndex; uint32_t m_cubemapTextureIndex; uint32_t m_config; diff --git a/HPL2/resource/ShaderList.fsl b/HPL2/resource/ShaderList.fsl index 2d797aa21..49b92b84c 100644 --- a/HPL2/resource/ShaderList.fsl +++ b/HPL2/resource/ShaderList.fsl @@ -451,3 +451,9 @@ #include "translucency_shade.frag.fsl" #end +#frag translucency_water_shade.frag + #define WAVE_AMPLITUDE_SCALE 0.04 + #define WAVE_FREQUENCY_SCALE 10.0 + #include "translucency_water_shade.frag.fsl" +#end + diff --git a/HPL2/resource/decal_shade.vert.fsl b/HPL2/resource/decal_shade.vert.fsl index db1cac146..44bbb4abe 100644 --- a/HPL2/resource/decal_shade.vert.fsl +++ b/HPL2/resource/decal_shade.vert.fsl @@ -1,4 +1,4 @@ -/// Copyright © 2009-2020 Frictional Games +/// Copyright � 2009-2020 Frictional Games /// Copyright 2023 Michael Pollind /// SPDX-License-Identifier: GPL-3.0 #include "scene_resource.h.fsl" diff --git a/HPL2/resource/parallax_bindless.h.fsl b/HPL2/resource/parallax_bindless.h.fsl index 5c68f04c9..f64a81215 100644 --- a/HPL2/resource/parallax_bindless.h.fsl +++ b/HPL2/resource/parallax_bindless.h.fsl @@ -5,10 +5,6 @@ #define _PARALLAX_BINDLESS_H INLINE float GetNormalizedDepth(float currentSample, float startDepth, float stopDepth, float inverseDepthRange) { - //float currentSample = 0.0; - // BeginNonUniformResourceIndex(heightIdx); - // EndNonUniformResourceIndex(); - float normalizedDepth = 0.0; if(stopDepth - startDepth > 0.0001) { diff --git a/HPL2/resource/scene_defs.h.fsl b/HPL2/resource/scene_defs.h.fsl index e02882733..ed86ce1da 100644 --- a/HPL2/resource/scene_defs.h.fsl +++ b/HPL2/resource/scene_defs.h.fsl @@ -1,8 +1,6 @@ #ifndef _SCENE_RESOURCE_DEFS_H_ #define _SCENE_RESOURCE_DEFS_H_ -#define VK_EXT_DESCRIPTOR_INDEXING_ENABLED 1 - #define PARALLAX_MULTIPLIER 0.7 #define POINT_LIGHT_MAX_COUNT (256) @@ -20,7 +18,7 @@ #define LIGHT_CLUSTER_DATA_POS(il, ix, iy) ( LIGHT_CLUSTER_COUNT_POS(ix, iy)*LIGHT_CLUSTER_COUNT + (il) ) #define PRIMARY_VIEWPORT_INDEX 0 - +#define SCENE_MAX_REFLECTION_COUNT 10000 #define SCENE_MAX_TEXTURE_COUNT 10000 #define SCENE_MAX_TEXTURE_CUBE_COUNT 5000 @@ -53,15 +51,13 @@ STRUCT(WaterMaterial) { DATA(float, refractionScale, None); DATA(float, frenselBias, None); - DATA(float, frenselPos, None); + DATA(float, frenselPow, None); DATA(float, reflectionFadeStart, None); - DATA(float, reflectionFadeEnd, None); DATA(float, waveSpeed, None); DATA(float, waveAmplitude, None); DATA(float, waveFreq, None); - }; @@ -138,6 +134,8 @@ STRUCT(UniformObject) #define MATERIAL_IS_ALPHA_SINGLE_CHANNEL (0x1) #define MATERIAL_IS_HEIGHT_SINGLE_CHANNEL (0x2) #define MATERIAL_USE_ALPHA_DISSOLVE_FILTER (0x4) +#define MATERIAL_USE_REFLECTION (0x8) +#define MATERIAL_USE_REFRACTION (0x16) #define MATERIAL_TYPE_SOLID_DIFFUSE 1 #define MATERIAL_TYPE_SOLID_TRANSLUCENT 2 @@ -171,7 +169,7 @@ STRUCT(WorldInfo) { DATA(float, worldFogLength, None); DATA(float, oneMinusFogAlpha, None); DATA(float, fogFalloffExp, None); - DATA(uint, __pad0, NONE); + DATA(float, afT, None); DATA(uint, __pad1, NONE); DATA(uint, __pad2, NONE); DATA(float4, worldFogColor, None); diff --git a/HPL2/resource/scene_resource.h.fsl b/HPL2/resource/scene_resource.h.fsl index b00ba368b..c101fc584 100644 --- a/HPL2/resource/scene_resource.h.fsl +++ b/HPL2/resource/scene_resource.h.fsl @@ -42,14 +42,15 @@ RES(Buffer(WaterMaterial), sceneWaterMat, UPDATE_FREQ_NONE, t12, binding = 17); RES(Tex2D(float4), visibilityTexture, UPDATE_FREQ_PER_FRAME, t13, binding = 18); RES(Tex2D(float4), albedoTexture, UPDATE_FREQ_PER_FRAME, t14, binding = 19); RES(Tex2D(float4), refractionTexture, UPDATE_FREQ_PER_FRAME, t15, binding = 20); +RES(Tex2D(float4), reflectionTexture[SCENE_MAX_REFLECTION_COUNT], UPDATE_FREQ_PER_FRAME, t16, binding = 20); -RES(Tex2D(float4), dissolveTexture, UPDATE_FREQ_NONE, t16, binding = 21); +RES(Tex2D(float4), dissolveTexture, UPDATE_FREQ_NONE, t21, binding = 21); -RES(ByteBuffer, lightClustersCount, UPDATE_FREQ_PER_FRAME, t17, binding = 22); -RES(ByteBuffer, lightClusters, UPDATE_FREQ_PER_FRAME, t18, binding = 23); +RES(ByteBuffer, lightClustersCount, UPDATE_FREQ_PER_FRAME, t22, binding = 22); +RES(ByteBuffer, lightClusters, UPDATE_FREQ_PER_FRAME, t23, binding = 23); -RES(Tex2D(float4), sceneTextures[SCENE_MAX_TEXTURE_COUNT], UPDATE_FREQ_PER_FRAME, t19, binding = 24); -RES(TexCube(float4), sceneCubeTextures[SCENE_MAX_TEXTURE_CUBE_COUNT], UPDATE_FREQ_PER_FRAME, t10020, binding = 25); +RES(Tex2D(float4), sceneTextures[SCENE_MAX_TEXTURE_COUNT], UPDATE_FREQ_PER_FRAME, t24, binding = 24); +RES(TexCube(float4), sceneCubeTextures[SCENE_MAX_TEXTURE_CUBE_COUNT], UPDATE_FREQ_PER_FRAME, t10024, binding = 25); #define SCENE_OBJECT_ID_BIT 19 // 13 bits for ObjectID #define SCENE_PRIM_ID_BIT 0 // 19 bits for PrimitiveID diff --git a/HPL2/resource/translucency_water_shade.frag.fsl b/HPL2/resource/translucency_water_shade.frag.fsl new file mode 100644 index 000000000..fd4c23f0d --- /dev/null +++ b/HPL2/resource/translucency_water_shade.frag.fsl @@ -0,0 +1,144 @@ +#include "scene_resource.h.fsl" +#include "packing.h.fsl" +#include "parallax_bindless.h.fsl" + +STRUCT(PsIn) +{ + DATA(float4, Position, SV_Position); + DATA(float3, pos, POSITION); + DATA(float2, uv, TEXCOORD0); +#if !defined(INDIRECT_ROOT_CONSTANT) + DATA(FLAT(uint), drawID, TEXCOORD1); +#endif + DATA(float3, normal, NORMAL); + DATA(float3, tangent, TANGENT); + DATA(float3, bitangent, BITANGENT); + DATA(float4, Color, COLOR); +}; + +STRUCT(PsOut) +{ + DATA(float4, diffuse, SV_Target0); +}; + +PsOut PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID) +{ + INIT_MAIN; + PsOut Out; + #if !defined(INDIRECT_ROOT_CONSTANT) + UniformObject obj = Get(sceneObjects)[In.drawID]; + #else + UniformObject obj = Get(sceneObjects)[Get(indirectDrawId)]; + #endif + ViewportInfo viewInfo = Get(viewports)[PRIMARY_VIEWPORT_INDEX]; + + WaterMaterial material = Get(sceneWaterMat)[obj.materialIndex]; + + float waveAft = Get(worldInfo).afT * material.waveSpeed; + float waveAmplitude = material.waveAmplitude * WAVE_AMPLITUDE_SCALE; + float waveFrequency = material.waveFreq * WAVE_FREQUENCY_SCALE; + + //Get the two uv coords + float fT1 = waveAft * 0.8; + float2 vUv1 = In.uv + waveAft * 0.01f; + vUv1.x += sin(fT1 + vUv1.y * waveFrequency) * waveAmplitude; + vUv1.y += sin(fT1 + vUv1.x * waveFrequency) * waveAmplitude; + + float fT2 = waveAft * -2.6; + float2 vUv2 = In.uv + waveAft * -0.012f; + vUv2.x += sin(fT2 + vUv2.y * waveFrequency * 1.2) * waveAmplitude * 0.75; + vUv2.y += sin(fT2 + vUv2.x * waveFrequency * 1.2) * waveAmplitude * 0.75; + + //Get the normals and combine into final normal + // (No need for full unpack since there is a normalize later) + float3 vNormal1;// = SampleTex2D(Get(normalMap), Get(materialSampler), vUv1).xyz - 0.5; + float3 vNormal2;// = SampleTex2D(Get(normalMap), Get(materialSampler), vUv2).xyz - 0.5; + + const uint normalTextureIndex = material.normalTextureIndex; + BeginNonUniformResourceIndex(normalTextureIndex); + vNormal1 = SampleTex2D(Get(sceneTextures)[normalTextureIndex], Get(sceneSampler), vUv1).xyz - 0.5; + vNormal2 = SampleTex2D(Get(sceneTextures)[normalTextureIndex], Get(sceneSampler), vUv2).xyz - 0.5; + EndNonUniformResourceIndex(); + + float3 vFinalNormal = normalize(vNormal1*0.7 + vNormal2*0.3); + + //Get the diffuse color + const uint diffuseTextureIndex = material.normalTextureIndex; + float4 surfaceColor; //= SampleTex2D(Get(diffuseMap), Get(materialSampler), vUv1); + BeginNonUniformResourceIndex(diffuseTextureIndex); + surfaceColor = SampleTex2D(Get(sceneTextures)[diffuseTextureIndex], Get(sceneSampler), vUv1); + EndNonUniformResourceIndex(); + + float4 vRefractionColor = float4(1,1,1,1); + float2 vDistortedScreenPos = float2(0.0,0.0); + if((material.config & MATERIAL_USE_REFRACTION) > 0) { + float fInvDist = min(1.0 / In.pos.z, 10.0); + vDistortedScreenPos = In.Position.xy + (viewInfo.rect.z * vFinalNormal.xy * material.refractionScale * fInvDist); + vRefractionColor = SampleTex2D(Get(refractionTexture), Get(linearBorderSampler), vDistortedScreenPos * (1.0 / viewInfo.rect.zw)); + // if(vRefractionColor.a < 0.5) { + // vRefractionColor = SampleTex2D(Get(refractionMap), Get(nearestSampler), In.Position.xy * Get(viewTexel)); + // } + } + + + float4 vReflectionColor = float4(1.0,1.0,1.0,1.0); + float fFresnel = 1.0; + if((material.config & MATERIAL_USE_REFLECTION ) > 0) { + ////////////////// + //Fresnel + float3 vScreenNormal = normalize(vFinalNormal.x * In.tangent + vFinalNormal.y * In.bitangent + vFinalNormal.z * In.normal); + float3 vEyeVec = normalize(In.pos); + + float afEDotN = max(dot(-vEyeVec, vScreenNormal),0.0); + fFresnel = Fresnel(afEDotN, material.frenselBias, material.frenselPow); + + if(material.reflectionFadeEnd > 0) { + const float refractionFadeLength = material.reflectionFadeEnd - material.reflectionFadeStart; + fFresnel *= 1.0 - clamp( (In.pos.z - material.reflectionFadeStart) / refractionFadeLength, 0.0, 1.0); + } + + ////////////////// + //Cubemap + if(isTextureIndexValid(material.cubeMapTextureIndex)) { + float3 vEnvUv = reflect(vEyeVec, vScreenNormal); + + vEnvUv = mul(transpose(float3x3( + viewInfo.viewMat[0].xyz, + viewInfo.viewMat[1].xyz, + viewInfo.viewMat[2].xyz)), vEnvUv); + // vEnvUv = mul(Get(invViewRotationMat), float4(vEnvUv.x, vEnvUv.y, vEnvUv.z, 1)).xyz; + //vReflectionColor = SampleTexCube(Get(cubeMap), Get(materialSampler), vEnvUv); + + const uint cubeMapTextureIndex = material.cubeMapTextureIndex; + BeginNonUniformResourceIndex(cubeMapTextureIndex); + vReflectionColor = SampleTexCube(Get(sceneCubeTextures)[cubeMapTextureIndex], Get(sceneSampler), vEnvUv); + EndNonUniformResourceIndex(); + } else { + //vReflectionColor = SampleTex2D(Get(reflectionMap)[ReflectionBuffer(Get(options))], Get(nearestSampler), vDistortedScreenPos * Get(viewTexel)); + } + } + + + float3 vLightDir = normalize(float3(0.5, 0.5, 0.5)); + float fLDotN = max(dot(vLightDir, vFinalNormal),0.0); + float fDiffuse = fLDotN * 0.5 + 0.5; + float fSpecular = pow(fLDotN,16.0); + + float fFogAmount = 0.0; + if ((Get(worldInfo).worldFlags & WORLD_FLAG_IS_FOG_ENABLED) > 0) { + fFogAmount = pow(clamp((-In.pos.z - Get(worldInfo).worldFogStart) / Get(worldInfo).worldFogLength, 0.0, 1.0), Get(worldInfo).fogFalloffExp) * Get(worldInfo).worldFogColor.a; + } + + if ((material.config & MATERIAL_USE_REFLECTION ) > 0) { + Out.diffuse.rgb = (surfaceColor.xyz * vRefractionColor.xyz + vReflectionColor.xyz * fFresnel) * (1.0-fFogAmount) + Get(worldInfo).worldFogColor.xyz*fFogAmount; + } else { + Out.diffuse.rgb = (surfaceColor.xyz * vRefractionColor.xyz * fDiffuse + float3(fSpecular, fSpecular, fSpecular)) * (1.0-fFogAmount) + Get(worldInfo).worldFogColor.xyz*fFogAmount; + } + + Out.diffuse.w = 1.0; + RETURN(Out); +} + + + + diff --git a/HPL2/sources/graphics/RendererDeferred2.cpp b/HPL2/sources/graphics/RendererDeferred2.cpp index c34cb5d98..0fa88da03 100644 --- a/HPL2/sources/graphics/RendererDeferred2.cpp +++ b/HPL2/sources/graphics/RendererDeferred2.cpp @@ -374,11 +374,8 @@ namespace hpl { { "translucency_refraction_shade_premul_alpha.frag", &m_translucencyRefractionShaderPremulAlpha }, // illumination { "translucency_shade_illumination_add.frag", &m_translucencyIlluminationShaderAdd }, - { "translucency_shade_illumination_mul.frag", &m_translucencyIlluminationShaderMul }, - { "translucency_shade_illumination_mulX2.frag", &m_translucencyIlluminationShaderMulX2 }, - { "translucency_shade_illumination_alpha.frag", &m_translucencyIlluminationShaderAlpha }, - { "translucency_shade_illumination_premul_alpha.frag", - &m_translucencyIlluminationShaderPremulAlpha } }; + // water + { "translucency_water_shade.frag", &m_translucencyWaterShader } }; for (auto& init : translucencyShadersInit) { init.shader->Load(forgeRenderer->Rend(), [&](Shader** shader) { ShaderLoadDesc loadDesc = {}; @@ -432,15 +429,12 @@ namespace hpl { m_translucencyShaderAlpha.m_handle, m_translucencyShaderPremulAlpha.m_handle, m_translucencyIlluminationShaderAdd.m_handle, - m_translucencyIlluminationShaderMul.m_handle, - m_translucencyIlluminationShaderMulX2.m_handle, - m_translucencyIlluminationShaderAlpha.m_handle, m_translucencyRefractionShaderAdd.m_handle, + m_translucencyWaterShader.m_handle, m_translucencyRefractionShaderMul.m_handle, m_translucencyRefractionShaderMulX2.m_handle, m_translucencyRefractionShaderAlpha.m_handle, - m_translucencyRefractionShaderPremulAlpha.m_handle, - m_translucencyIlluminationShaderPremulAlpha.m_handle }; + m_translucencyRefractionShaderPremulAlpha.m_handle }; std::array vbShadeSceneSamplers = { m_samplerLinearClampToBorder.m_handle, m_samplerMaterial.m_handle, m_samplerNearEdgeClamp.m_handle, @@ -543,6 +537,8 @@ namespace hpl { addPipeline(forgeRenderer->Rend(), &pipelineDesc, pipeline); return true; }); + + m_visbilityEmitBufferPass.Load(forgeRenderer->Rend(), [&](Pipeline** pipeline) { std::array colorFormats = { ColorBufferFormat }; RasterizerStateDesc rasterizerStateDesc = {}; @@ -955,6 +951,49 @@ namespace hpl { return true; }); } + + { + BlendStateDesc blendStateDesc{}; + blendStateDesc.mColorWriteMasks[0] = ColorMask::COLOR_MASK_RED | ColorMask::COLOR_MASK_GREEN | ColorMask::COLOR_MASK_BLUE; + blendStateDesc.mRenderTargetMask = BLEND_STATE_TARGET_0; + blendStateDesc.mIndependentBlend = false; + + PipelineDesc pipelineDesc = {}; + pipelineDesc.mType = PIPELINE_TYPE_GRAPHICS; + auto& pipelineSettings = pipelineDesc.mGraphicsDesc; + pipelineSettings.mPrimitiveTopo = PRIMITIVE_TOPO_TRI_LIST; + pipelineSettings.mRenderTargetCount = colorFormats.size(); + pipelineSettings.pColorFormats = colorFormats.data(); + pipelineSettings.mSampleCount = SAMPLE_COUNT_1; + pipelineSettings.mSampleQuality = 0; + pipelineSettings.pBlendState = &blendStateDesc; + pipelineSettings.mDepthStencilFormat = DepthBufferFormat; + pipelineSettings.pRootSignature = m_sceneRootSignature.m_handle; + pipelineSettings.pVertexLayout = &vertexLayout; + + RasterizerStateDesc rasterizerStateDesc = {}; + rasterizerStateDesc.mCullMode = CULL_MODE_FRONT; + rasterizerStateDesc.mFrontFace = FRONT_FACE_CCW; + pipelineSettings.pRasterizerState = &rasterizerStateDesc; + + blendStateDesc.mSrcFactors[0] = BC_ONE; + blendStateDesc.mDstFactors[0] = BC_ZERO; + blendStateDesc.mBlendModes[0] = BlendMode::BM_ADD; + pipelineSettings.pShaderProgram = m_translucencyWaterShader.m_handle; + + + pipelineSettings.pDepthState = &depthStateDesc; + m_translucencyWaterPipeline.Load(forgeRenderer->Rend(), [&](Pipeline** pipeline) { + addPipeline(forgeRenderer->Rend(), &pipelineDesc, pipeline); + return true; + }); + + pipelineSettings.pDepthState = &noDepthStateDesc; + m_translucencyWaterPipelineNoDepth.Load(forgeRenderer->Rend(), [&](Pipeline** pipeline) { + addPipeline(forgeRenderer->Rend(), &pipelineDesc, pipeline); + return true; + }); + } } struct { SharedShader* shader; @@ -1284,11 +1323,10 @@ namespace hpl { auto& opaqueSet = graphicsAllocator->resolveSet(GraphicsAllocator::AllocationSet::OpaqueSet); std::array params = { - DescriptorData{ .pName = "dissolveTexture", .ppTextures = &m_dissolveImage->GetTexture().m_handle }, DescriptorData{ .pName = "sceneDiffuseMat", .ppBuffers = &m_diffuseMatUniformBuffer.m_handle }, DescriptorData{ .pName = "sceneTranslucentMat", .ppBuffers = &m_translucencyMatBuffer.m_handle }, - // DescriptorData{ .pName = "sceneFilters", .mCount = samplers.size(), .ppSamplers = samplers.data() }, + DescriptorData{ .pName = "sceneWaterMat", .ppBuffers = &m_waterMatBuffer.m_handle }, DescriptorData{ .pName = "vtxOpaqueIndex", .ppBuffers = &opaqueSet.indexBuffer().m_handle }, DescriptorData{ .pName = "vtxOpaquePosition", .ppBuffers = &opaqueSet.getStreamBySemantic(ShaderSemantic::SEMANTIC_POSITION)->buffer().m_handle }, @@ -1636,12 +1674,16 @@ namespace hpl { RangeSubsetAlloc::RangeSubset range; eMaterialBlendMode blend; }; - enum class TranslucentDrawType : uint8_t { Translucency, TranslucencyIllumination, Particle, Water }; + enum class TranslucentDrawType : uint8_t { + Translucency, + Particle, + Water + }; struct TranslucentArgs { TranslucentDrawType type; iRenderable* renderable; - bool m_refraction; - bool m_reflection; + Pipeline* pipeline; + Pipeline* illuminationPipline; uint32_t indirectDrawIndex; uint32_t numberIndecies; uint32_t indexOffset; @@ -1698,8 +1740,10 @@ namespace hpl { translucenctArgs.push_back({ TranslucentDrawType::Particle, renderable, - false, - false, + material->GetDepthTest()? + m_particlePipeline.getPipelineByBlendMode(material->GetBlendMode()).m_handle: + m_particlePipelineNoDepth.getPipelineByBlendMode(material->GetBlendMode()).m_handle, + nullptr, frameVars.m_particleIndex, packet.m_unified.m_numIndices, packet.m_unified.m_subAllocation->indexOffset(), @@ -1758,6 +1802,38 @@ namespace hpl { } case MaterialID::Water: { + materialSet.m_slot = IndexPoolHandle(&m_waterIndexPool); + BufferUpdateDesc updateDesc = { m_translucencyMatBuffer.m_handle, + sizeof(resource::WaterMaterial) * materialSet.m_slot.get() }; + beginUpdateResource(&updateDesc); + auto& waterMaterial = (*reinterpret_cast(updateDesc.pMappedData)); + struct { + eMaterialTexture m_type; + uint32_t* m_value; + } textures[] = { + { eMaterialTexture_Diffuse, &waterMaterial.m_diffuseTextureIndex }, + { eMaterialTexture_NMap, &waterMaterial.m_normalTextureIndex }, + { eMaterialTexture_CubeMap, &waterMaterial.m_cubemapTextureIndex }, + }; + for (auto& tex : textures) { + (*tex.m_value) = resourceMaterial.m_textureHandles[tex.m_type]; + } + + waterMaterial.m_config = + (isReflection ? resource::UseReflection : 0) | + (isRefraction ? resource::UseRefraction : 0); + + waterMaterial.m_refractionScale = descriptor.m_water.m_refractionScale; + waterMaterial.m_frenselBias = descriptor.m_water.m_frenselBias; + waterMaterial.m_frenselPow = descriptor.m_water.m_frenselPow; + + waterMaterial.m_reflectionFadeStart = descriptor.m_water.m_reflectionFadeStart; + waterMaterial.m_reflectionFadeEnd = descriptor.m_water.m_reflectionFadeEnd; + waterMaterial.m_waveSpeed = descriptor.m_water.m_waveSpeed; + waterMaterial.m_waveAmplitude = descriptor.m_water.m_waveAmplitude; + + waterMaterial.m_waveFreq = descriptor.m_water.m_waveFreq; + endUpdateResource(&updateDesc); break; } default: @@ -1792,12 +1868,24 @@ namespace hpl { if (descriptor.m_id == MaterialID::Water) { return TranslucentDrawType::Water; } - return (cubeMap && !isRefraction) ? TranslucentDrawType::TranslucencyIllumination - : TranslucentDrawType::Translucency; + return TranslucentDrawType::Translucency; })(), renderable, - isRefraction, - isReflection, + ([&]() { + if (isRefraction) { + if (material->GetDepthTest()) { + return m_translucencyRefractionPipline.getPipelineByBlendMode(material->GetBlendMode()).m_handle; + } + return m_translucencyRefractionPiplineNoDepth.getPipelineByBlendMode(material->GetBlendMode()).m_handle; + } + if (material->GetDepthTest()) { + return m_translucencyPipline.getPipelineByBlendMode(material->GetBlendMode()).m_handle; + } + return m_translucencyPiplineNoDepth.getPipelineByBlendMode(material->GetBlendMode()).m_handle; + })(), + (cubeMap && !isRefraction) ? (material->GetDepthTest() ? m_translucencyIlluminationPipline.m_handle + : m_translucencyIlluminationPiplineNoDepth.m_handle) + : nullptr, slot, packet.m_unified.m_numIndices, packet.m_unified.m_subAllocation->indexOffset(), @@ -2323,12 +2411,7 @@ namespace hpl { particleSet.cmdBindGeometrySet(cmd, semantics); cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorConstSet.m_handle); cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorPerFrameSet[frame.m_frameIndex].m_handle); - if (pMaterial->GetDepthTest()) { - cmdBindPipeline(cmd, m_particlePipeline.getPipelineByBlendMode(pMaterial->GetBlendMode()).m_handle); - } else { - cmdBindPipeline(cmd, m_particlePipelineNoDepth.getPipelineByBlendMode(pMaterial->GetBlendMode()).m_handle); - } - + cmdBindPipeline(cmd, arg.pipeline); if (m_supportIndirectRootConstant) { const uint32_t pushConstantIndex = getDescriptorIndexFromName(m_sceneRootSignature.m_handle, "indirectRootConstant"); @@ -2337,7 +2420,24 @@ namespace hpl { cmdDrawIndexedInstanced(cmd, arg.numberIndecies, arg.indexOffset, 1, arg.vertexOffset, arg.indirectDrawIndex); break; } - case TranslucentDrawType::TranslucencyIllumination: + case TranslucentDrawType::Water: { + std::array semantics = { ShaderSemantic::SEMANTIC_POSITION, + ShaderSemantic::SEMANTIC_TEXCOORD0, + ShaderSemantic::SEMANTIC_NORMAL, + ShaderSemantic::SEMANTIC_TANGENT, + ShaderSemantic::SEMANTIC_COLOR }; + opaqueSet.cmdBindGeometrySet(cmd, semantics); + cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorConstSet.m_handle); + cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorPerFrameSet[frame.m_frameIndex].m_handle); + cmdBindPipeline(cmd, m_translucencyWaterPipeline.m_handle); + if (m_supportIndirectRootConstant) { + const uint32_t pushConstantIndex = + getDescriptorIndexFromName(m_sceneRootSignature.m_handle, "indirectRootConstant"); + cmdBindPushConstants(cmd, m_sceneRootSignature.m_handle, pushConstantIndex, &arg.indirectDrawIndex); + } + cmdDrawIndexedInstanced(cmd, arg.numberIndecies, arg.indexOffset, 1, arg.vertexOffset, arg.indirectDrawIndex); + break; + } case TranslucentDrawType::Translucency: { std::array semantics = { ShaderSemantic::SEMANTIC_POSITION, @@ -2348,20 +2448,7 @@ namespace hpl { opaqueSet.cmdBindGeometrySet(cmd, semantics); cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorConstSet.m_handle); cmdBindDescriptorSet(cmd, 0, m_sceneDescriptorPerFrameSet[frame.m_frameIndex].m_handle); - - if (arg.m_refraction) { - if (pMaterial->GetDepthTest()) { - cmdBindPipeline(cmd, m_translucencyRefractionPipline.getPipelineByBlendMode(pMaterial->GetBlendMode()).m_handle); - } else { - cmdBindPipeline(cmd, m_translucencyRefractionPiplineNoDepth.getPipelineByBlendMode(pMaterial->GetBlendMode()).m_handle); - } - } else { - if (pMaterial->GetDepthTest()) { - cmdBindPipeline(cmd, m_translucencyPipline.getPipelineByBlendMode(pMaterial->GetBlendMode()).m_handle); - } else { - cmdBindPipeline(cmd, m_translucencyPiplineNoDepth.getPipelineByBlendMode(pMaterial->GetBlendMode()).m_handle); - } - } + cmdBindPipeline(cmd, arg.pipeline); if (m_supportIndirectRootConstant) { const uint32_t pushConstantIndex = @@ -2370,12 +2457,8 @@ namespace hpl { } cmdDrawIndexedInstanced(cmd, arg.numberIndecies, arg.indexOffset, 1, arg.vertexOffset, arg.indirectDrawIndex); - if (arg.type == TranslucentDrawType::TranslucencyIllumination) { - if (pMaterial->GetDepthTest()) { - cmdBindPipeline(cmd, m_translucencyIlluminationPipline.m_handle); - } else { - cmdBindPipeline(cmd, m_translucencyIlluminationPiplineNoDepth.m_handle); - } + if (arg.illuminationPipline) { + cmdBindPipeline(cmd, arg.illuminationPipline); cmdDrawIndexedInstanced(cmd, arg.numberIndecies, arg.indexOffset, 1, arg.vertexOffset, arg.indirectDrawIndex); } break; diff --git a/HPL2/sources/graphics/SceneResource.cpp b/HPL2/sources/graphics/SceneResource.cpp index 46b020da4..d123ff1cc 100644 --- a/HPL2/sources/graphics/SceneResource.cpp +++ b/HPL2/sources/graphics/SceneResource.cpp @@ -1,10 +1,25 @@ #include "graphics/SceneResource.h" #include "graphics/Material.h" +#include "math/cFrustum.h" #include "tinyimageformat_query.h" #include namespace hpl::resource { + ViewportInfo ViewportInfo::create(cFrustum* apFrustum, float4 rect) { + ViewportInfo info; + info.m_viewMat = apFrustum->GetViewMat(); + info.m_projMat = apFrustum->GetProjectionMat(); + info.m_invProjMat = inverse(apFrustum->GetProjectionMat()); + info.m_invViewMat = inverse(apFrustum->GetViewMat()); + info.m_invViewProj = inverse(info.m_projMat * info.m_viewMat); + info.m_zFar = apFrustum->GetFarPlane(); + info.m_zNear = apFrustum->GetNearPlane(); + info.m_rect = rect;//float4(0.0f, 0.0f, static_cast(viewportDatum->m_size.x), static_cast(viewportDatum->m_size.y)); + info.m_cameraPosition = v3ToF3(cMath::ToForgeVec3(apFrustum->GetOrigin())); + return info; + } + uint32_t textureFilterIdx(TextureAntistropy anisotropy, eTextureWrap wrap, eTextureFilter filter) { const uint32_t anisotropyGroup = (static_cast(eTextureFilter_LastEnum) * static_cast(eTextureWrap_LastEnum)) *