From 54a64c0d82a0a3c93b886d80fbfad025b8860750 Mon Sep 17 00:00:00 2001 From: Areloch Date: Wed, 30 Jan 2019 13:52:59 -0600 Subject: [PATCH 1/8] Shifts the verts used to match the fullscreen quad setup of vector light, utilizing FarFrustuQuadVerts --- .../source/renderInstance/renderProbeMgr.cpp | 77 ++++--------------- Engine/source/renderInstance/renderProbeMgr.h | 3 +- .../client/lighting/advanced/shaders.cs | 8 +- .../advanced/reflectionProbeArrayP.hlsl | 26 ++----- 4 files changed, 27 insertions(+), 87 deletions(-) diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 1b2f653b6..278970ae5 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -314,35 +314,27 @@ void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state) // Now build the quad for drawing full-screen vector light // passes.... this is a volatile VB and updates every frame. - GFXVertexPC verts[4]; + FarFrustumQuadVert verts[4]; { verts[0].point.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraPos); - //invCam.mulP(wsFrustumPoints[Frustum::FarTopLeft], &verts[0].normal); - //verts[0].texCoord.set(-1.0, 1.0); - //verts[0].tangent.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraOffsetPos); + invCam.mulP(wsFrustumPoints[Frustum::FarTopLeft], &verts[0].normal); + verts[0].texCoord.set(-1.0, 1.0); + verts[0].tangent.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraOffsetPos); verts[1].point.set(wsFrustumPoints[Frustum::FarTopRight] - cameraPos); - // invCam.mulP(wsFrustumPoints[Frustum::FarTopRight], &verts[1].normal); - //verts[1].texCoord.set(1.0, 1.0); - //verts[1].tangent.set(wsFrustumPoints[Frustum::FarTopRight] - cameraOffsetPos); + invCam.mulP(wsFrustumPoints[Frustum::FarTopRight], &verts[1].normal); + verts[1].texCoord.set(1.0, 1.0); + verts[1].tangent.set(wsFrustumPoints[Frustum::FarTopRight] - cameraOffsetPos); verts[2].point.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraPos); - //invCam.mulP(wsFrustumPoints[Frustum::FarBottomLeft], &verts[2].normal); - // verts[2].texCoord.set(-1.0, -1.0); - // verts[2].tangent.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraOffsetPos); + invCam.mulP(wsFrustumPoints[Frustum::FarBottomLeft], &verts[2].normal); + verts[2].texCoord.set(-1.0, -1.0); + verts[2].tangent.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraOffsetPos); verts[3].point.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraPos); - // invCam.mulP(wsFrustumPoints[Frustum::FarBottomRight], &verts[3].normal); - // verts[3].texCoord.set(1.0, -1.0); - // verts[3].tangent.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraOffsetPos); - } - - Point3F norms[4]; - { - invCam.mulP(wsFrustumPoints[Frustum::FarTopLeft], &norms[0]); - invCam.mulP(wsFrustumPoints[Frustum::FarTopRight], &norms[1]); - invCam.mulP(wsFrustumPoints[Frustum::FarBottomLeft], &norms[2]); - invCam.mulP(wsFrustumPoints[Frustum::FarBottomRight], &norms[3]); + invCam.mulP(wsFrustumPoints[Frustum::FarBottomRight], &verts[3].normal); + verts[3].texCoord.set(1.0, -1.0); + verts[3].tangent.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraOffsetPos); } mFarFrustumQuadVerts.set(GFX, 4); @@ -350,8 +342,7 @@ void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state) mFarFrustumQuadVerts.unlock(); PlaneF farPlane(wsFrustumPoints[Frustum::FarBottomLeft], wsFrustumPoints[Frustum::FarTopLeft], wsFrustumPoints[Frustum::FarTopRight]); - PlaneF vsFarPlane(norms[0], norms[1], norms[2]); - + PlaneF vsFarPlane(verts[0].normal, verts[1].normal, verts[2].normal); ReflectProbeMaterialInfo* reflProbeMat = getReflectProbeMaterial(); @@ -839,46 +830,6 @@ void RenderProbeMgr::render( SceneRenderState *state ) } // // - /*ProbeManager::ReflectionProbeArrayMaterialInfo* reflProbeArrayMat = PROBEMGR->getReflectProbeArrayMaterial(); - - for (U32 i = 0; i < ProbeRenderInst::all.size(); i++) - { - if (i > 0) - return; - - ProbeRenderInst* curEntry = ProbeRenderInst::all[i]; - - if (!reflProbeArrayMat || !reflProbeArrayMat->matInstance) - break; - - //Setup - //MatrixF probeTrans = curEntry->getTransform(); - - //if (!curEntry->mIsSkylight) - { - //if (curEntry->mProbeShapeType == ProbeRenderInst::Sphere) - // probeTrans.scale(curEntry->mRadius * 1.01f); - - //sgData.objTrans = &state-; - - reflProbeArrayMat->setProbeParameters(curEntry, state, worldToCameraXfm); - - // Set geometry - GFX->setVertexBuffer(mFarFrustumQuadVerts); - GFX->setPrimitiveBuffer(NULL); - while (reflProbeArrayMat->matInstance->setupPass(state, sgData)) - { - // Set transforms - //matrixSet.setWorld(*sgData.objTrans); - reflProbeArrayMat->matInstance->setTransforms(matrixSet, state); - reflProbeArrayMat->matInstance->setSceneInfo(state, sgData); - - GFX->drawPrimitive(GFXTriangleStrip, 0, 2); - } - } - }*/ - // - // GFX->popActiveRenderTarget(); diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index 4535f1a04..9a20ed84f 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -265,7 +265,8 @@ protected: /// The current active light manager. static RenderProbeMgr *smProbeManager; - GFXVertexBufferHandle mFarFrustumQuadVerts; + typedef GFXVertexPNTT FarFrustumQuadVert; + GFXVertexBufferHandle mFarFrustumQuadVerts; /// This helper function sets the shader constansts /// for the stock 4 light forward lighting code. diff --git a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs index 281f0dac5..6540e3e55 100644 --- a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs +++ b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs @@ -293,7 +293,7 @@ new ShaderData( ReflectionProbeShader ) samplerNames[4] = "$irradianceCubemap"; samplerNames[5] = "$BRDFTexture";*/ - DXVertexShaderFile = "shaders/common/lighting/advanced/reflectionProbeArrayV.hlsl"; + DXVertexShaderFile = "shaders/common/lighting/advanced/farFrustumQuadV.hlsl"; DXPixelShaderFile = "shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl"; OGLVertexShaderFile = "shaders/common/lighting/advanced/gl/reflectionProbeArrayV.glsl"; @@ -302,9 +302,9 @@ new ShaderData( ReflectionProbeShader ) samplerNames[0] = "$deferredBuffer"; samplerNames[1] = "$colorBuffer"; samplerNames[2] = "$matInfoBuffer"; - samplerNames[3] = "$cubeMap"; - samplerNames[4] = "$irradianceCubemap"; - samplerNames[5] = "$BRDFTexture"; + samplerNames[3] = "$BRDFTexture"; + samplerNames[4] = "$cubeMap"; + samplerNames[5] = "$irradianceCubemap"; pixVersion = 3.0; }; diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl index 4cf858cf8..1a7053376 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl @@ -4,13 +4,6 @@ #include "../../lighting.hlsl" #include "../../torque.hlsl" -struct ConvexConnectP -{ - float4 pos : TORQUE_POSITION; - float4 uv0 : TEXCOORD1; - float4 vsEyeDir : TEXCOORD2; -}; - TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0); TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 1); TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 2); @@ -95,22 +88,15 @@ float defineBoxSpaceInfluence(Surface surface, int id) return max(localDir.x, max(localDir.y, localDir.z)) * -1; } -float4 main( ConvexConnectP IN ) : SV_TARGET +float4 main( FarFrustumQuadConnectP IN ) : SV_TARGET { - // Compute scene UV - //float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; - //float2 IN.uv0 = getUVFromSSPos( ssPos, rtParams0 ); - - //eye ray WS/LS - float3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); - float3 wsEyeRay = mul(cameraToWorld, float4(vsEyeRay, 0)).xyz; - //unpack normal and linear depth float4 normDepth = TORQUE_DEFERRED_UNCONDITION(deferredBuffer, IN.uv0.xy); - + + //create surface Surface surface = createSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer), - IN.uv0.xy, eyePosWorld, wsEyeRay, cameraToWorld); + IN.uv0.xy, eyePosWorld, IN.wsEyeRay, cameraToWorld); //early out if emissive if (getFlag(surface.matFlag, 0)) { @@ -182,5 +168,7 @@ float4 main( ConvexConnectP IN ) : SV_TARGET } //final diffuse color float3 diffuse = kD * irradiance * surface.baseColor.rgb; - return float4(diffuse + specular * surface.ao, blendSum); + float4 finalColor = float4(diffuse + specular * surface.ao, blendSum); + + return finalColor; } From a0b9c8cfd6da7461c1a785b8c59f0ae89cb58dca Mon Sep 17 00:00:00 2001 From: Areloch Date: Thu, 31 Jan 2019 11:44:09 -0600 Subject: [PATCH 2/8] Broke it down to work with a single probe for confirmation of general math and behavior. --- .../source/renderInstance/renderProbeMgr.cpp | 42 ++++++--- .../advanced/reflectionProbeArrayP.hlsl | 87 +++++++++++-------- 2 files changed, 80 insertions(+), 49 deletions(-) diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 278970ae5..415b70d5d 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -679,7 +679,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) }*/ //Array rendering - static U32 MAXPROBECOUNT = 50; + static U32 MAXPROBECOUNT = 1;// 50; U32 probeCount = ProbeRenderInst::all.size(); @@ -688,7 +688,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) MatrixF trans = MatrixF::Identity; sgData.objTrans = &trans; - AlignedArray probePositions(MAXPROBECOUNT, sizeof(Point3F)); + /*AlignedArray probePositions(MAXPROBECOUNT, sizeof(Point3F)); Vector probeWorldToObj; AlignedArray probeBBMin(MAXPROBECOUNT, sizeof(Point3F)); AlignedArray probeBBMax(MAXPROBECOUNT, sizeof(Point3F)); @@ -705,7 +705,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) dMemset(probeAttenuation.getBuffer(), 0, probeAttenuation.getBufferSize()); Vector cubeMaps; - Vector irradMaps; + Vector irradMaps;*/ if (reflProbeMat && reflProbeMat->matInstance) { @@ -721,7 +721,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) MaterialParameterHandle *probeRadiusSC = reflProbeMat->matInstance->getMaterialParameterHandle("$radius"); MaterialParameterHandle *probeAttenuationSC = reflProbeMat->matInstance->getMaterialParameterHandle("$attenuation"); - U32 effectiveProbeCount = 0; + /*U32 effectiveProbeCount = 0; for (U32 i = 0; i < probeCount; i++) { @@ -763,17 +763,17 @@ void RenderProbeMgr::render( SceneRenderState *state ) } if (effectiveProbeCount != 0) - { - matParams->setSafe(numProbesSC, (float)effectiveProbeCount); + {*/ + //matParams->setSafe(numProbesSC, (float)effectiveProbeCount); - GFXCubemapArrayHandle mCubemapArray; + /*GFXCubemapArrayHandle mCubemapArray; mCubemapArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); GFXCubemapArrayHandle mIrradArray; mIrradArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); mCubemapArray->initStatic(cubeMaps.address(), cubeMaps.size()); - mIrradArray->initStatic(irradMaps.address(), irradMaps.size()); + mIrradArray->initStatic(irradMaps.address(), irradMaps.size());*/ NamedTexTarget *deferredTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName); if (deferredTarget) @@ -801,11 +801,27 @@ void RenderProbeMgr::render( SceneRenderState *state ) GFX->setTexture(3, NULL); - GFX->setCubeArrayTexture(4, mCubemapArray); - GFX->setCubeArrayTexture(5, mIrradArray); + //GFX->setCubeArrayTexture(4, mCubemapArray); + //GFX->setCubeArrayTexture(5, mIrradArray); - matParams->set(probePositionSC, probePositions); - matParams->set(probeWorldToObjSC, probeWorldToObj.address(), probeWorldToObj.size()); + ProbeRenderInst* curEntry = ProbeRenderInst::all[0]; + + Point3F probePosition = curEntry->getPosition(); + + MatrixF probeWorldToObj = curEntry->getTransform(); + probeWorldToObj.inverse(); + + Point3F probeBBMin = curEntry->mBounds.minExtents; + Point3F probeBBMax = curEntry->mBounds.maxExtents; + float probeUseSphereMode = 0; + float probeRadius = curEntry->mRadius; + float probeAttenuation = 1; + + GFX->setCubeTexture(4, curEntry->mCubemap); + GFX->setCubeTexture(5, curEntry->mIrradianceCubemap); + + matParams->set(probePositionSC, probePosition); + matParams->set(probeWorldToObjSC, probeWorldToObj); matParams->set(probeBBMinSC, probeBBMin); matParams->set(probeBBMaxSC, probeBBMax); matParams->set(probeUseSphereModeSC, probeUseSphereMode); @@ -825,7 +841,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) GFX->drawPrimitive(GFXTriangleStrip, 0, 2); } - } + //} } } // diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl index 1a7053376..d6ea44aac 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl @@ -16,18 +16,18 @@ uniform float3 eyePosWorld; //cubemap arrays require all the same size. so shared mips# value uniform float cubeMips; -#define MAX_PROBES 50 +#define MAX_PROBES 1 //50 uniform float numProbes; -TORQUE_UNIFORM_SAMPLERCUBEARRAY(cubeMapAR, 4); -TORQUE_UNIFORM_SAMPLERCUBEARRAY(irradianceCubemapAR, 5); -uniform float3 inProbePosArray[MAX_PROBES]; -uniform float4x4 worldToObjArray[MAX_PROBES]; -uniform float3 bbMinArray[MAX_PROBES]; -uniform float3 bbMaxArray[MAX_PROBES]; -uniform float useSphereMode[MAX_PROBES]; -uniform float radius[MAX_PROBES]; -uniform float2 attenuation[MAX_PROBES]; +TORQUE_UNIFORM_SAMPLERCUBE(cubeMapAR, 4); +TORQUE_UNIFORM_SAMPLERCUBE(irradianceCubemapAR, 5); +uniform float3 inProbePosArray; +uniform float4x4 worldToObjArray; +uniform float3 bbMinArray; +uniform float3 bbMaxArray; +uniform float useSphereMode; +uniform float radius; +uniform float2 attenuation; // Box Projected IBL Lighting // Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/ @@ -46,14 +46,14 @@ float3 boxProject(float3 wsPosition, float3 reflectDir, float3 boxWSPos, float3 return posonbox - boxWSPos; } -float3 iblBoxDiffuse( Surface surface, int id) +float3 iblBoxDiffuse( Surface surface) { - float3 cubeN = boxProject(surface.P, surface.N, inProbePosArray[id], bbMinArray[id], bbMaxArray[id]); + float3 cubeN = boxProject(surface.P, surface.N, inProbePosArray, bbMinArray, bbMaxArray); cubeN.z *=-1; - return TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR,cubeN,id,0).xyz; + return TORQUE_TEXCUBELOD(irradianceCubemapAR,float4(cubeN,0)).xyz; } -float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTexture), int id) +float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTexture)) { float ndotv = clamp(dot(surface.N, surfToEye), 0.0, 1.0); @@ -64,20 +64,20 @@ float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTe float lod = surface.roughness*cubeMips; float3 r = reflect(surfToEye, surface.N); float3 cubeR = normalize(r); - cubeR = boxProject(surface.P, surface.N, inProbePosArray[id], bbMinArray[id], bbMaxArray[id]); + cubeR = boxProject(surface.P, surface.N, inProbePosArray, bbMinArray, bbMaxArray); - float3 radiance = TORQUE_TEXCUBEARRAYLOD(cubeMapAR,cubeR,id,lod).xyz * (brdf.x + brdf.y); - + float3 radiance = TORQUE_TEXCUBELOD(cubeMapAR,float4(cubeR,lod)).xyz * (brdf.x + brdf.y); + return radiance; } -float defineBoxSpaceInfluence(Surface surface, int id) +float defineBoxSpaceInfluence(Surface surface) { float tempAttenVal = 3.5; //replace with per probe atten - float3 surfPosLS = mul( worldToObjArray[id], float4(surface.P,1.0)).xyz; + float3 surfPosLS = mul( worldToObjArray, float4(surface.P,1.0)).xyz; - float3 boxMinLS = inProbePosArray[id]-(float3(1,1,1)*radius[id]); - float3 boxMaxLS = inProbePosArray[id]+(float3(1,1,1)*radius[id]); + float3 boxMinLS = inProbePosArray-(float3(1,1,1)*radius); + float3 boxMaxLS = inProbePosArray+(float3(1,1,1)*radius); float boxOuterRange = length(boxMaxLS - boxMinLS); float boxInnerRange = boxOuterRange / tempAttenVal; @@ -93,23 +93,23 @@ float4 main( FarFrustumQuadConnectP IN ) : SV_TARGET //unpack normal and linear depth float4 normDepth = TORQUE_DEFERRED_UNCONDITION(deferredBuffer, IN.uv0.xy); - //create surface Surface surface = createSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer), - IN.uv0.xy, eyePosWorld, IN.wsEyeRay, cameraToWorld); + IN.uv0.xy, eyePosWorld, IN.wsEyeRay, cameraToWorld); + //early out if emissive if (getFlag(surface.matFlag, 0)) { discard; } - float blendVal[MAX_PROBES]; + float blendVal; float3 surfToEye = normalize(surface.P - eyePosWorld); int i; float blendSum = 0; float invBlendSum = 0; - for(i=0; i < numProbes; i++) + /*for(i=0; i < numProbes; i++) { float3 probeWS = inProbePosArray[i]; float3 L = probeWS - surface.P; @@ -127,22 +127,37 @@ float4 main( FarFrustumQuadConnectP IN ) : SV_TARGET } blendSum += blendVal[i]; invBlendSum +=(1.0f - blendVal[i]); - } + }*/ + + if(useSphereMode) + { + float3 L = inProbePosArray - surface.P; + blendVal = 1.0-length(L)/radius; + blendVal = max(0,blendVal); + } + else + { + blendVal = defineBoxSpaceInfluence(surface); + blendVal = max(0,blendVal); + } // Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary. // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1). // respect constraint B. // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary // and respect constraint A. - for(i=0; i < numProbes; i++) + /*for(i=0; i < numProbes; i++) { blendVal[i] = (1.0f - ( blendVal[i] / blendSum)) / (numProbes - 1); blendVal[i] *= ((1.0f - blendVal[i]) / invBlendSum); blendSum += blendVal[i]; - } + }*/ + + //float asdasg = defineBoxSpaceInfluence(surface, 0); + //return float4(asdasg,asdasg,asdasg,1); // Normalize blendVal - if (blendSum == 0.0f) // Possible with custom weight + /*if (blendSum == 0.0f) // Possible with custom weight { blendSum = 1.0f; } @@ -151,7 +166,7 @@ float4 main( FarFrustumQuadConnectP IN ) : SV_TARGET for (i = 0; i < numProbes; ++i) { blendVal[i] *= invBlendSumWeighted; - } + }*/ float3 irradiance = float3(0,0,0); float3 specular = float3(0,0,0); @@ -160,15 +175,15 @@ float4 main( FarFrustumQuadConnectP IN ) : SV_TARGET //energy conservation float3 kD = 1.0.xxx - F; kD *= 1.0 - surface.metalness; - for (i = 0; i < numProbes; ++i) - { - irradiance += blendVal[i]*iblBoxDiffuse(surface,i); + //for (i = 0; i < numProbes; ++i) + //{ + irradiance = blendVal*iblBoxDiffuse(surface); - specular += blendVal[i]*F*iblBoxSpecular(surface, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture),i); - } + specular = blendVal*F*iblBoxSpecular(surface, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture)); + //} //final diffuse color float3 diffuse = kD * irradiance * surface.baseColor.rgb; - float4 finalColor = float4(diffuse + specular * surface.ao, blendSum); + float4 finalColor = float4(diffuse + specular * surface.ao, 1); return finalColor; } From a8707b241096a6f3ff0c30deb629b1858966827b Mon Sep 17 00:00:00 2001 From: Areloch Date: Sat, 2 Feb 2019 23:28:51 -0600 Subject: [PATCH 3/8] Progress in getting array data to comply. --- .../source/renderInstance/renderProbeMgr.cpp | 316 ++++++++---------- .../advanced/reflectionProbeArrayP.hlsl | 90 +++-- 2 files changed, 174 insertions(+), 232 deletions(-) diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 415b70d5d..ae5793c77 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -638,210 +638,162 @@ void RenderProbeMgr::render( SceneRenderState *state ) ReflectProbeMaterialInfo* reflProbeMat = getReflectProbeMaterial(); - /*for (U32 i = 0; i < ProbeRenderInst::all.size(); i++) - { - ProbeRenderInst* curEntry = ProbeRenderInst::all[i]; + if (reflProbeMat == nullptr || reflProbeMat->matInstance == nullptr) + return; - if (!curEntry->mIsEnabled) - continue; + MaterialParameters *matParams = reflProbeMat->matInstance->getMaterialParameters(); - if (curEntry->numPrims == 0) - continue; + MaterialParameterHandle *numProbesSC = reflProbeMat->matInstance->getMaterialParameterHandle("$numProbes"); - if (curEntry->mIsSkylight && (!skylightMat || !skylightMat->matInstance)) - continue; - - if (!curEntry->mIsSkylight && (!reflProbeMat || !reflProbeMat->matInstance)) - break; - - if (curEntry->mIsSkylight) - { - //Setup - MatrixF probeTrans = curEntry->getTransform(); - - // Set geometry - GFX->setVertexBuffer(curEntry->vertBuffer); - GFX->setPrimitiveBuffer(curEntry->primBuffer); - probeTrans.scale(10); //force it to be big enough to surround the camera - sgData.objTrans = &probeTrans; - skylightMat->setProbeParameters(curEntry, state, worldToCameraXfm); - - while (skylightMat->matInstance->setupPass(state, sgData)) - { - // Set transforms - matrixSet.setWorld(*sgData.objTrans); - skylightMat->matInstance->setTransforms(matrixSet, state); - skylightMat->matInstance->setSceneInfo(state, sgData); - - GFX->drawPrimitive(GFXTriangleList, 0, curEntry->numPrims); - } - } - }*/ + MaterialParameterHandle *probePositionSC = reflProbeMat->matInstance->getMaterialParameterHandle("$inProbePosArray"); + MaterialParameterHandle *probeWorldToObjSC = reflProbeMat->matInstance->getMaterialParameterHandle("$worldToObjArray"); + MaterialParameterHandle *probeBBMinSC = reflProbeMat->matInstance->getMaterialParameterHandle("$bbMinArray"); + MaterialParameterHandle *probeBBMaxSC = reflProbeMat->matInstance->getMaterialParameterHandle("$bbMaxArray"); + MaterialParameterHandle *probeUseSphereModeSC = reflProbeMat->matInstance->getMaterialParameterHandle("$useSphereMode"); + MaterialParameterHandle *probeRadiusSC = reflProbeMat->matInstance->getMaterialParameterHandle("$radius"); + MaterialParameterHandle *probeAttenuationSC = reflProbeMat->matInstance->getMaterialParameterHandle("$attenuation"); //Array rendering - static U32 MAXPROBECOUNT = 1;// 50; + static U32 MAXPROBECOUNT = 50; U32 probeCount = ProbeRenderInst::all.size(); - if (probeCount != 0) + MatrixF trans = MatrixF::Identity; + sgData.objTrans = &trans; + + Vector probePositions; + Vector probeWorldToObj; + Vector probeBBMin; + Vector probeBBMax; + Vector probeUseSphereMode; + Vector probeRadius; + Vector probeAttenuation; + + probePositions.setSize(MAXPROBECOUNT); + probeWorldToObj.setSize(MAXPROBECOUNT); + probeBBMin.setSize(MAXPROBECOUNT); + probeBBMax.setSize(MAXPROBECOUNT); + probeUseSphereMode.setSize(MAXPROBECOUNT); + probeRadius.setSize(MAXPROBECOUNT); + probeAttenuation.setSize(MAXPROBECOUNT); + + //Vector cubeMaps; + //Vector irradMaps; + + U32 effectiveProbeCount = 0; + + for (U32 i = 0; i < probeCount; i++) { - MatrixF trans = MatrixF::Identity; - sgData.objTrans = &trans; + if (effectiveProbeCount >= MAXPROBECOUNT) + break; - /*AlignedArray probePositions(MAXPROBECOUNT, sizeof(Point3F)); - Vector probeWorldToObj; - AlignedArray probeBBMin(MAXPROBECOUNT, sizeof(Point3F)); - AlignedArray probeBBMax(MAXPROBECOUNT, sizeof(Point3F)); - AlignedArray probeUseSphereMode(MAXPROBECOUNT, sizeof(float)); - AlignedArray probeRadius(MAXPROBECOUNT, sizeof(float)); - AlignedArray probeAttenuation(MAXPROBECOUNT, sizeof(float)); + ProbeRenderInst* curEntry = ProbeRenderInst::all[i]; + if (!curEntry->mIsEnabled) + continue; - dMemset(probePositions.getBuffer(), 0, probePositions.getBufferSize()); - probeWorldToObj.setSize(MAXPROBECOUNT); - dMemset(probeBBMin.getBuffer(), 0, probeBBMin.getBufferSize()); - dMemset(probeBBMax.getBuffer(), 0, probeBBMax.getBufferSize()); - dMemset(probeUseSphereMode.getBuffer(), 0, probeUseSphereMode.getBufferSize()); - dMemset(probeRadius.getBuffer(), 0, probeRadius.getBufferSize()); - dMemset(probeAttenuation.getBuffer(), 0, probeAttenuation.getBufferSize()); + if (curEntry->mCubemap.isNull() || curEntry->mIrradianceCubemap.isNull()) + continue; - Vector cubeMaps; - Vector irradMaps;*/ + if (!curEntry->mCubemap->isInitialised()) + continue; - if (reflProbeMat && reflProbeMat->matInstance) + //Setup + const Point3F &probePos = curEntry->getPosition(); + probePositions[i] = probePos + curEntry->mProbePosOffset; + + MatrixF trans = curEntry->getTransform(); + trans.inverse(); + + probeWorldToObj[i] = trans; + + probeBBMin[i] = curEntry->mBounds.minExtents; + probeBBMax[i] = curEntry->mBounds.maxExtents; + + probeUseSphereMode[i] = curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0; + + probeRadius[i] = curEntry->mRadius; + probeAttenuation[i] = 1; + + //cubeMaps.push_back(curEntry->mCubemap); + //irradMaps.push_back(curEntry->mIrradianceCubemap); + + effectiveProbeCount++; + } + + if (effectiveProbeCount != 0) + { + matParams->setSafe(numProbesSC, (float)effectiveProbeCount); + + /*GFXCubemapArrayHandle mCubemapArray; + mCubemapArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); + + GFXCubemapArrayHandle mIrradArray; + mIrradArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); + + mCubemapArray->initStatic(cubeMaps.address(), cubeMaps.size()); + mIrradArray->initStatic(irradMaps.address(), irradMaps.size());*/ + + NamedTexTarget *deferredTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName); + if (deferredTarget) + GFX->setTexture(0, deferredTarget->getTexture()); + else + GFX->setTexture(0, NULL); + + NamedTexTarget *colorTarget = NamedTexTarget::find(RenderDeferredMgr::ColorBufferName); + if (colorTarget) + GFX->setTexture(1, colorTarget->getTexture()); + else + GFX->setTexture(1, NULL); + + NamedTexTarget *matinfoTarget = NamedTexTarget::find(RenderDeferredMgr::MatInfoBufferName); + if (matinfoTarget) + GFX->setTexture(2, matinfoTarget->getTexture()); + else + GFX->setTexture(2, NULL); + + if (mBrdfTexture) { - MaterialParameters *matParams = reflProbeMat->matInstance->getMaterialParameters(); + GFX->setTexture(3, mBrdfTexture); + } + else + GFX->setTexture(3, NULL); - MaterialParameterHandle *numProbesSC = reflProbeMat->matInstance->getMaterialParameterHandle("$numProbes"); + //GFX->setCubeArrayTexture(4, mCubemapArray); + //GFX->setCubeArrayTexture(5, mIrradArray); - MaterialParameterHandle *probePositionSC = reflProbeMat->matInstance->getMaterialParameterHandle("$inProbePosArray"); - MaterialParameterHandle *probeWorldToObjSC = reflProbeMat->matInstance->getMaterialParameterHandle("$worldToObjArray"); - MaterialParameterHandle *probeBBMinSC = reflProbeMat->matInstance->getMaterialParameterHandle("$bbMinArray"); - MaterialParameterHandle *probeBBMaxSC = reflProbeMat->matInstance->getMaterialParameterHandle("$bbMaxArray"); - MaterialParameterHandle *probeUseSphereModeSC = reflProbeMat->matInstance->getMaterialParameterHandle("$useSphereMode"); - MaterialParameterHandle *probeRadiusSC = reflProbeMat->matInstance->getMaterialParameterHandle("$radius"); - MaterialParameterHandle *probeAttenuationSC = reflProbeMat->matInstance->getMaterialParameterHandle("$attenuation"); - - /*U32 effectiveProbeCount = 0; + ProbeRenderInst* curEntry = ProbeRenderInst::all[0]; - for (U32 i = 0; i < probeCount; i++) - { - if (effectiveProbeCount >= MAXPROBECOUNT) - break; + GFX->setCubeTexture(4, curEntry->mCubemap); + GFX->setCubeTexture(5, curEntry->mIrradianceCubemap); - ProbeRenderInst* curEntry = ProbeRenderInst::all[i]; - if (!curEntry->mIsEnabled) - continue; + //Final packing + AlignedArray _probePositions(probePositions.size(), sizeof(Point4F), (U8*)probePositions.address(), false); + AlignedArray _probeBBMin(probeBBMin.size(), sizeof(Point4F), (U8*)probeBBMin.address(), false); + AlignedArray _probeBBMax(probeBBMax.size(), sizeof(Point4F), (U8*)probeBBMax.address(), false); + AlignedArray _probeUseSphereMode(probeUseSphereMode.size(), sizeof(float), (U8*)probeUseSphereMode.address(), false); + AlignedArray _probeRadius(probeRadius.size(), sizeof(float), (U8*)probeRadius.address(), false); + AlignedArray _probeAttenuation(probeAttenuation.size(), sizeof(float), (U8*)probeAttenuation.address(), false); - if (curEntry->mCubemap.isNull() || curEntry->mIrradianceCubemap.isNull()) - continue; + matParams->set(probePositionSC, _probePositions); + matParams->set(probeWorldToObjSC, probeWorldToObj.address(), probeWorldToObj.size()); + matParams->set(probeBBMinSC, _probeBBMin); + matParams->set(probeBBMaxSC, _probeBBMax); + matParams->set(probeUseSphereModeSC, _probeUseSphereMode); + matParams->set(probeRadiusSC, _probeRadius); + matParams->set(probeAttenuationSC, _probeAttenuation); - if (!curEntry->mCubemap->isInitialised()) - continue; + // Set geometry + GFX->setVertexBuffer(mFarFrustumQuadVerts); + GFX->setPrimitiveBuffer(NULL); + while (reflProbeMat->matInstance->setupPass(state, sgData)) + { + // Set transforms + matrixSet.setWorld(*sgData.objTrans); + reflProbeMat->matInstance->setTransforms(matrixSet, state); + reflProbeMat->matInstance->setSceneInfo(state, sgData); - //Setup - const Point3F &probePos = curEntry->getPosition(); - probePositions[i] = probePos + curEntry->mProbePosOffset; - - MatrixF trans = curEntry->getTransform(); - trans.inverse(); - - probeWorldToObj[i] = trans; - - probeBBMin[i] = curEntry->mBounds.minExtents; - probeBBMax[i] = curEntry->mBounds.maxExtents; - - probeUseSphereMode[i] = curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0; - - probeRadius[i] = curEntry->mRadius; - probeAttenuation[i] = 1; - - cubeMaps.push_back(curEntry->mCubemap); - irradMaps.push_back(curEntry->mIrradianceCubemap); - - effectiveProbeCount++; - } - - if (effectiveProbeCount != 0) - {*/ - //matParams->setSafe(numProbesSC, (float)effectiveProbeCount); - - /*GFXCubemapArrayHandle mCubemapArray; - mCubemapArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); - - GFXCubemapArrayHandle mIrradArray; - mIrradArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); - - mCubemapArray->initStatic(cubeMaps.address(), cubeMaps.size()); - mIrradArray->initStatic(irradMaps.address(), irradMaps.size());*/ - - NamedTexTarget *deferredTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName); - if (deferredTarget) - GFX->setTexture(0, deferredTarget->getTexture()); - else - GFX->setTexture(0, NULL); - - NamedTexTarget *colorTarget = NamedTexTarget::find(RenderDeferredMgr::ColorBufferName); - if (colorTarget) - GFX->setTexture(1, colorTarget->getTexture()); - else - GFX->setTexture(1, NULL); - - NamedTexTarget *matinfoTarget = NamedTexTarget::find(RenderDeferredMgr::MatInfoBufferName); - if (matinfoTarget) - GFX->setTexture(2, matinfoTarget->getTexture()); - else - GFX->setTexture(2, NULL); - - if (mBrdfTexture) - { - GFX->setTexture(3, mBrdfTexture); - } - else - GFX->setTexture(3, NULL); - - - //GFX->setCubeArrayTexture(4, mCubemapArray); - //GFX->setCubeArrayTexture(5, mIrradArray); - - ProbeRenderInst* curEntry = ProbeRenderInst::all[0]; - - Point3F probePosition = curEntry->getPosition(); - - MatrixF probeWorldToObj = curEntry->getTransform(); - probeWorldToObj.inverse(); - - Point3F probeBBMin = curEntry->mBounds.minExtents; - Point3F probeBBMax = curEntry->mBounds.maxExtents; - float probeUseSphereMode = 0; - float probeRadius = curEntry->mRadius; - float probeAttenuation = 1; - - GFX->setCubeTexture(4, curEntry->mCubemap); - GFX->setCubeTexture(5, curEntry->mIrradianceCubemap); - - matParams->set(probePositionSC, probePosition); - matParams->set(probeWorldToObjSC, probeWorldToObj); - matParams->set(probeBBMinSC, probeBBMin); - matParams->set(probeBBMaxSC, probeBBMax); - matParams->set(probeUseSphereModeSC, probeUseSphereMode); - matParams->set(probeRadiusSC, probeRadius); - matParams->set(probeAttenuationSC, probeAttenuation); - - // Set geometry - GFX->setVertexBuffer(mFarFrustumQuadVerts); - GFX->setPrimitiveBuffer(NULL); - - while (reflProbeMat->matInstance->setupPass(state, sgData)) - { - // Set transforms - matrixSet.setWorld(*sgData.objTrans); - reflProbeMat->matInstance->setTransforms(matrixSet, state); - reflProbeMat->matInstance->setSceneInfo(state, sgData); - - GFX->drawPrimitive(GFXTriangleStrip, 0, 2); - } - //} + GFX->drawPrimitive(GFXTriangleStrip, 0, 2); } } // diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl index d6ea44aac..054a4e08e 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl @@ -16,18 +16,18 @@ uniform float3 eyePosWorld; //cubemap arrays require all the same size. so shared mips# value uniform float cubeMips; -#define MAX_PROBES 1 //50 +#define MAX_PROBES 50 uniform float numProbes; TORQUE_UNIFORM_SAMPLERCUBE(cubeMapAR, 4); TORQUE_UNIFORM_SAMPLERCUBE(irradianceCubemapAR, 5); -uniform float3 inProbePosArray; -uniform float4x4 worldToObjArray; -uniform float3 bbMinArray; -uniform float3 bbMaxArray; -uniform float useSphereMode; -uniform float radius; -uniform float2 attenuation; +uniform float4 inProbePosArray[MAX_PROBES]; +uniform float4x4 worldToObjArray[MAX_PROBES]; +uniform float4 bbMinArray[MAX_PROBES]; +uniform float4 bbMaxArray[MAX_PROBES]; +uniform float useSphereMode[MAX_PROBES]; +uniform float radius[MAX_PROBES]; +uniform float2 attenuation[MAX_PROBES]; // Box Projected IBL Lighting // Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/ @@ -46,14 +46,14 @@ float3 boxProject(float3 wsPosition, float3 reflectDir, float3 boxWSPos, float3 return posonbox - boxWSPos; } -float3 iblBoxDiffuse( Surface surface) +float3 iblBoxDiffuse( Surface surface, int id) { - float3 cubeN = boxProject(surface.P, surface.N, inProbePosArray, bbMinArray, bbMaxArray); + float3 cubeN = boxProject(surface.P, surface.N, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz); cubeN.z *=-1; return TORQUE_TEXCUBELOD(irradianceCubemapAR,float4(cubeN,0)).xyz; } -float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTexture)) +float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTexture), int id) { float ndotv = clamp(dot(surface.N, surfToEye), 0.0, 1.0); @@ -64,20 +64,20 @@ float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTe float lod = surface.roughness*cubeMips; float3 r = reflect(surfToEye, surface.N); float3 cubeR = normalize(r); - cubeR = boxProject(surface.P, surface.N, inProbePosArray, bbMinArray, bbMaxArray); + cubeR = boxProject(surface.P, surface.N, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz); float3 radiance = TORQUE_TEXCUBELOD(cubeMapAR,float4(cubeR,lod)).xyz * (brdf.x + brdf.y); return radiance; } -float defineBoxSpaceInfluence(Surface surface) +float defineBoxSpaceInfluence(Surface surface, int id) { float tempAttenVal = 3.5; //replace with per probe atten - float3 surfPosLS = mul( worldToObjArray, float4(surface.P,1.0)).xyz; + float3 surfPosLS = mul( worldToObjArray[id], float4(surface.P,1.0)).xyz; - float3 boxMinLS = inProbePosArray-(float3(1,1,1)*radius); - float3 boxMaxLS = inProbePosArray+(float3(1,1,1)*radius); + float3 boxMinLS = inProbePosArray[id].xyz-(float3(1,1,1)*radius[0]); + float3 boxMaxLS = inProbePosArray[id].xyz+(float3(1,1,1)*radius[0]); float boxOuterRange = length(boxMaxLS - boxMinLS); float boxInnerRange = boxOuterRange / tempAttenVal; @@ -102,62 +102,52 @@ float4 main( FarFrustumQuadConnectP IN ) : SV_TARGET { discard; } - float blendVal; + + float blendVal[MAX_PROBES]; float3 surfToEye = normalize(surface.P - eyePosWorld); - int i; - float blendSum = 0; - float invBlendSum = 0; + int i = 0; + float blendSum = 0; + float invBlendSum = 0; - /*for(i=0; i < numProbes; i++) + for(i=0; i < numProbes; i++) { - float3 probeWS = inProbePosArray[i]; + float3 probeWS = inProbePosArray[i].xyz; float3 L = probeWS - surface.P; - if(useSphereMode[i]) + /*if(useSphereMode[i]) { - float3 L = inProbePosArray[i] - surface.P; + float3 L = inProbePosArray[i].xyz - surface.P; blendVal[i] = 1.0-length(L)/radius[i]; blendVal[i] = max(0,blendVal[i]); } else - { + {*/ blendVal[i] = defineBoxSpaceInfluence(surface, i); blendVal[i] = max(0,blendVal[i]); - } + //} blendSum += blendVal[i]; invBlendSum +=(1.0f - blendVal[i]); - }*/ - - if(useSphereMode) - { - float3 L = inProbePosArray - surface.P; - blendVal = 1.0-length(L)/radius; - blendVal = max(0,blendVal); - } - else - { - blendVal = defineBoxSpaceInfluence(surface); - blendVal = max(0,blendVal); - } + } // Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary. // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1). // respect constraint B. // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary // and respect constraint A. - /*for(i=0; i < numProbes; i++) + for(i=0; i < numProbes; i++) { blendVal[i] = (1.0f - ( blendVal[i] / blendSum)) / (numProbes - 1); blendVal[i] *= ((1.0f - blendVal[i]) / invBlendSum); blendSum += blendVal[i]; - }*/ + } - //float asdasg = defineBoxSpaceInfluence(surface, 0); - //return float4(asdasg,asdasg,asdasg,1); + float finalSum = blendSum; + + //return float4(finalSum,finalSum,finalSum, 1); // Normalize blendVal - /*if (blendSum == 0.0f) // Possible with custom weight + if (blendSum == 0.0f) // Possible with custom weight { blendSum = 1.0f; } @@ -166,7 +156,7 @@ float4 main( FarFrustumQuadConnectP IN ) : SV_TARGET for (i = 0; i < numProbes; ++i) { blendVal[i] *= invBlendSumWeighted; - }*/ + } float3 irradiance = float3(0,0,0); float3 specular = float3(0,0,0); @@ -175,12 +165,12 @@ float4 main( FarFrustumQuadConnectP IN ) : SV_TARGET //energy conservation float3 kD = 1.0.xxx - F; kD *= 1.0 - surface.metalness; - //for (i = 0; i < numProbes; ++i) - //{ - irradiance = blendVal*iblBoxDiffuse(surface); + for (i = 0; i < numProbes; ++i) + { + irradiance += blendVal[i]*iblBoxDiffuse(surface,i); - specular = blendVal*F*iblBoxSpecular(surface, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture)); - //} + specular += blendVal[i]*F*iblBoxSpecular(surface, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture),i); + } //final diffuse color float3 diffuse = kD * irradiance * surface.baseColor.rgb; float4 finalColor = float4(diffuse + specular * surface.ao, 1); From a1b281cc5f11cdcd0c5b1561eb6bfd89a190cf2d Mon Sep 17 00:00:00 2001 From: Areloch Date: Mon, 11 Feb 2019 00:17:53 -0600 Subject: [PATCH 4/8] Ongoing PostFX org rework. --- Engine/source/postFx/postEffect.cpp | 11 +- Engine/source/postFx/postEffect.h | 4 + .../source/renderInstance/renderProbeMgr.cpp | 330 ++++++++++-------- Engine/source/renderInstance/renderProbeMgr.h | 38 +- .../client/lighting/advanced/shaders.cs | 8 +- .../advanced/reflectionProbeArrayP.hlsl | 8 +- 6 files changed, 221 insertions(+), 178 deletions(-) diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index 4054554f0..b123109e8 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -1434,6 +1434,11 @@ void PostEffect::_checkRequirements() // properly, we can find all the input textures, // and its formats are supported. + if (mShaderName == String("PFX_ReflectionProbeArray") || getName() == StringTable->insert("reflectionProbeArrayPostFX")) + { + bool derp = true; + } + mIsValid = false; mUpdateShader = false; mShader = NULL; @@ -1473,9 +1478,11 @@ void PostEffect::_checkRequirements() if ( texFilename.isNotEmpty() && texFilename[0] == '#' ) { NamedTexTarget *namedTarget = NamedTexTarget::find( texFilename.c_str() + 1 ); - if ( !namedTarget ) + if (!namedTarget) + { return; - + } + // Grab the macros for shader initialization. namedTarget->getShaderMacros( ¯os ); } diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index 53ee0b1d5..3f2001be0 100644 --- a/Engine/source/postFx/postEffect.h +++ b/Engine/source/postFx/postEffect.h @@ -353,6 +353,10 @@ public: bool isOneFrameOnly() { return mOneFrameOnly; } F32 getAspectRatio() const; + + GFXShaderRef getShader() { return mShader; } + Vector* getShaderMacros() { return &mShaderMacros; } + GFXShaderConstBufferRef getShaderConstBuffer() { return mShaderConsts; } enum PostEffectRequirements diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index b8ae72ee2..0a38686a7 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -243,7 +243,6 @@ bool ReflectProbeMatInstance::setupPass(SceneRenderState *state, const SceneData RenderProbeMgr::RenderProbeMgr() : RenderBinManager(RenderPassManager::RIT_Probes, 1.0f, 1.0f), mReflectProbeMaterial(nullptr), - mSceneManager(nullptr), mLastShader(nullptr), mLastConstants(nullptr) { @@ -276,6 +275,12 @@ RenderProbeMgr::RenderProbeMgr() irradMaps.setSize(MAXPROBECOUNT); irradMaps.fill(NULL); + + mEffectiveProbeCount = 0; + + mProbeArrayEffect = nullptr; + + numProbesSC = nullptr; } RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder) @@ -320,6 +325,21 @@ void RenderProbeMgr::registerProbe(U32 probeIdx) return; mRegisteredProbes.push_back_unique(probeIdx); + + //rebuild our probe data + //_setupStaticParameters(); +} + +void RenderProbeMgr::unregisterProbe(U32 probeIdx) +{ + //Mostly for consolidation, but also lets us sanity check or prep any other data we need for rendering this in one place at time of flagging for render + if (probeIdx >= ProbeRenderInst::all.size()) + return; + + mRegisteredProbes.remove(probeIdx); + + //rebuild our probe data + //_setupStaticParameters(); } // @@ -327,8 +347,12 @@ void RenderProbeMgr::registerProbe(U32 probeIdx) PostEffect* RenderProbeMgr::getProbeArrayEffect() { if (!mProbeArrayEffect) + { mProbeArrayEffect = dynamic_cast(Sim::findObject("reflectionProbeArrayPostFX")); + if (!mProbeArrayEffect) + return nullptr; + } return mProbeArrayEffect; } @@ -339,7 +363,115 @@ PostEffect* RenderProbeMgr::getProbeArrayEffect() void RenderProbeMgr::_setupStaticParameters() { + mLastShader = mProbeArrayEffect->getShader(); + if (mLastShader == nullptr) + return; + + mLastConstants = mLastShader->allocConstBuffer(); + + numProbesSC = mLastShader->getShaderConstHandle("$numProbes"); + + probePositionSC = mLastShader->getShaderConstHandle("$inProbePosArray"); + probeWorldToObjSC = mLastShader->getShaderConstHandle("$worldToObjArray"); + probeBBMinSC = mLastShader->getShaderConstHandle("$bbMinArray"); + probeBBMaxSC = mLastShader->getShaderConstHandle("$bbMaxArray"); + probeUseSphereModeSC = mLastShader->getShaderConstHandle("$useSphereMode"); + probeRadiusSC = mLastShader->getShaderConstHandle("$radius"); + probeAttenuationSC = mLastShader->getShaderConstHandle("$attenuation"); + + //Array rendering + U32 probeCount = ProbeRenderInst::all.size(); + + mEffectiveProbeCount = 0; + + for (U32 i = 0; i < probeCount; i++) + { + if (mEffectiveProbeCount >= MAXPROBECOUNT) + break; + + ProbeRenderInst* curEntry = ProbeRenderInst::all[i]; + if (!curEntry->mIsEnabled) + continue; + + if (curEntry->mCubemap.isNull() || curEntry->mIrradianceCubemap.isNull()) + continue; + + if (!curEntry->mCubemap->isInitialised()) + continue; + + if (curEntry->mIsSkylight) + continue; + + //Setup + const Point3F &probePos = curEntry->getPosition(); + probePositions[i] = probePos + curEntry->mProbePosOffset; + + MatrixF trans = curEntry->getTransform(); + trans.inverse(); + + probeWorldToObj[i] = trans; + + probeBBMin[i] = curEntry->mBounds.minExtents; + probeBBMax[i] = curEntry->mBounds.maxExtents; + + probeUseSphereMode[i] = curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0; + + probeRadius[i] = curEntry->mRadius; + probeAttenuation[i] = 1; + + cubeMaps[i] = curEntry->mCubemap; + irradMaps[i] = curEntry->mIrradianceCubemap; + + mEffectiveProbeCount++; + } + + if (mEffectiveProbeCount != 0) + { + mCubemapArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); + mIrradArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); + + mCubemapArray->initStatic(cubeMaps.address(), mEffectiveProbeCount); + mIrradArray->initStatic(irradMaps.address(), mEffectiveProbeCount); + + /*NamedTexTarget *deferredTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName); + if (deferredTarget) + GFX->setTexture(0, deferredTarget->getTexture()); + else + GFX->setTexture(0, NULL); + + NamedTexTarget *colorTarget = NamedTexTarget::find(RenderDeferredMgr::ColorBufferName); + if (colorTarget) + GFX->setTexture(1, colorTarget->getTexture()); + else + GFX->setTexture(1, NULL); + + NamedTexTarget *matinfoTarget = NamedTexTarget::find(RenderDeferredMgr::MatInfoBufferName); + if (matinfoTarget) + GFX->setTexture(2, matinfoTarget->getTexture()); + else + GFX->setTexture(2, NULL); + + if (mBrdfTexture) + { + GFX->setTexture(3, mBrdfTexture); + } + else + GFX->setTexture(3, NULL);*/ + + //GFX->setCubeArrayTexture(4, mCubemapArray); + //GFX->setCubeArrayTexture(5, mIrradArray); + + ProbeRenderInst* curEntry = ProbeRenderInst::all[0]; + //count = MAXPROBECOUNT; + //Final packing + mProbePositions = AlignedArray(mEffectiveProbeCount, sizeof(Point4F), (U8*)probePositions.address(), false); + mProbeBBMin = AlignedArray(mEffectiveProbeCount, sizeof(Point4F), (U8*)probeBBMin.address(), false); + mProbeBBMax = AlignedArray(mEffectiveProbeCount, sizeof(Point4F), (U8*)probeBBMax.address(), false); + mProbeUseSphereMode = AlignedArray(mEffectiveProbeCount, sizeof(float), (U8*)probeUseSphereMode.address(), false); + mProbeRadius = AlignedArray(mEffectiveProbeCount, sizeof(float), (U8*)probeRadius.address(), false); + mProbeAttenuation = AlignedArray(mEffectiveProbeCount, sizeof(float), (U8*)probeAttenuation.address(), false); + } } void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state) @@ -432,27 +564,27 @@ ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuff ProbeConstantMap::Iterator iter = mConstantLookup.find(shader); if (iter != mConstantLookup.end()) { - mLastConstants = iter->value; + mLastForwardConstants = iter->value; } else { ProbeShaderConstants* psc = new ProbeShaderConstants(); mConstantLookup[shader] = psc; - mLastConstants = psc; + mLastForwardConstants = psc; } // Set our new shader mLastShader = shader; } - mLastConstants = new ProbeShaderConstants(); + mLastForwardConstants = new ProbeShaderConstants(); // Make sure that our current lighting constants are initialized - if (!mLastConstants->mInit) - mLastConstants->init(shader); + if (!mLastForwardConstants->mInit) + mLastForwardConstants->init(shader); - return mLastConstants; + return mLastForwardConstants; } void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, @@ -629,7 +761,9 @@ void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat, //----------------------------------------------------------------------------- void RenderProbeMgr::render( SceneRenderState *state ) { - PROFILE_SCOPE(RenderProbeMgr_render); + //PROFILE_SCOPE(RenderProbeMgr_render); + if (getProbeArrayEffect() == nullptr) + return; // Early out if nothing to draw. if (!ProbeRenderInst::all.size()) @@ -638,129 +772,38 @@ void RenderProbeMgr::render( SceneRenderState *state ) if (!RenderProbeMgr::smRenderReflectionProbes) return; + if (mEffectiveProbeCount == 0) + _setupStaticParameters(); //return; + GFXTransformSaver saver; GFXDEBUGEVENT_SCOPE(RenderProbeMgr_render, ColorI::WHITE); - NamedTexTargetRef sceneColorTargetRef = NamedTexTarget::find("AL_FormatToken"); - if (sceneColorTargetRef.isNull()) - return; - - GFXTextureTargetRef probeLightingTargetRef = GFX->allocRenderToTextureTarget(); - - if (probeLightingTargetRef.isNull()) - return; - - //Do a quick pass to update our probes if they're dirty - //PROBEMGR->updateDirtyProbes(); - - probeLightingTargetRef->attachTexture(GFXTextureTarget::Color0, sceneColorTargetRef->getTexture(0)); - - GFX->pushActiveRenderTarget(); - GFX->setActiveRenderTarget(probeLightingTargetRef); - - GFX->setViewport(sceneColorTargetRef->getViewport()); - - // Restore transforms - MatrixSet &matrixSet = getRenderPass()->getMatrixSet(); - matrixSet.restoreSceneViewProjection(); - - const MatrixF &worldToCameraXfm = matrixSet.getWorldToCamera(); - - // Set up the SG Data - SceneData sgData; - sgData.init(state); - // Initialize and set the per-frame parameters after getting // the vector light material as we use lazy creation. - _setupPerFrameParameters(state); - - //Order the probes by size, biggest to smallest - //dQsort(ProbeRenderInst::all.address(), ProbeRenderInst::all.size(), sizeof(const ProbeRenderInst*), AscendingReflectProbeInfluence); + //_setupPerFrameParameters(state); //Specular - PROFILE_START(RenderProbeManager_ReflectProbeRender); + //PROFILE_START(RenderProbeManager_ReflectProbeRender); - ReflectProbeMaterialInfo* reflProbeMat = getReflectProbeMaterial(); - - if (reflProbeMat == nullptr || reflProbeMat->matInstance == nullptr) + // If this is a non-diffuse pass or we have no objects to + // render then tell the effect to skip rendering. + if (!state->isDiffusePass()/* || binSize == 0*/|| !numProbesSC || !numProbesSC->isValid()) + { + getProbeArrayEffect()->setSkip(true); return; - - MaterialParameters *matParams = reflProbeMat->matInstance->getMaterialParameters(); - - MaterialParameterHandle *numProbesSC = reflProbeMat->matInstance->getMaterialParameterHandle("$numProbes"); - - MaterialParameterHandle *probePositionSC = reflProbeMat->matInstance->getMaterialParameterHandle("$inProbePosArray"); - MaterialParameterHandle *probeWorldToObjSC = reflProbeMat->matInstance->getMaterialParameterHandle("$worldToObjArray"); - MaterialParameterHandle *probeBBMinSC = reflProbeMat->matInstance->getMaterialParameterHandle("$bbMinArray"); - MaterialParameterHandle *probeBBMaxSC = reflProbeMat->matInstance->getMaterialParameterHandle("$bbMaxArray"); - MaterialParameterHandle *probeUseSphereModeSC = reflProbeMat->matInstance->getMaterialParameterHandle("$useSphereMode"); - MaterialParameterHandle *probeRadiusSC = reflProbeMat->matInstance->getMaterialParameterHandle("$radius"); - MaterialParameterHandle *probeAttenuationSC = reflProbeMat->matInstance->getMaterialParameterHandle("$attenuation"); + } //Array rendering U32 probeCount = ProbeRenderInst::all.size(); if (probeCount == 0) return; - MatrixF trans = MatrixF::Identity; - sgData.objTrans = &trans; - - U32 effectiveProbeCount = 0; - for (U32 i = 0; i < probeCount; i++) + if (mEffectiveProbeCount != 0) { - if (effectiveProbeCount >= MAXPROBECOUNT) - break; - - ProbeRenderInst* curEntry = ProbeRenderInst::all[i]; - if (!curEntry->mIsEnabled) - continue; - - if (curEntry->mCubemap.isNull() || curEntry->mIrradianceCubemap.isNull()) - continue; - - if (!curEntry->mCubemap->isInitialised()) - continue; - - if (curEntry->mIsSkylight) - continue; - - //Setup - const Point3F &probePos = curEntry->getPosition(); - probePositions[i] = probePos + curEntry->mProbePosOffset; - - MatrixF trans = curEntry->getTransform(); - trans.inverse(); - - probeWorldToObj[i]=trans; - - probeBBMin[i] = curEntry->mBounds.minExtents; - probeBBMax[i] = curEntry->mBounds.maxExtents; - - probeUseSphereMode[i] = curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0; - - probeRadius[i] = curEntry->mRadius; - probeAttenuation[i] = 1; - - cubeMaps[i] = curEntry->mCubemap; - irradMaps[i] = curEntry->mIrradianceCubemap; - - effectiveProbeCount++; - } - - if (effectiveProbeCount != 0) - { - U32 count = effectiveProbeCount; - matParams->setSafe(numProbesSC, (float)effectiveProbeCount); - - mCubemapArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); - mIrradArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); - - mCubemapArray->initStatic(cubeMaps.address(), count); - mIrradArray->initStatic(irradMaps.address(), count); - - NamedTexTarget *deferredTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName); + //These will in theory be set by the postFX + /*NamedTexTarget *deferredTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName); if (deferredTarget) GFX->setTexture(0, deferredTarget->getTexture()); else @@ -776,7 +819,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) if (matinfoTarget) GFX->setTexture(2, matinfoTarget->getTexture()); else - GFX->setTexture(2, NULL); + GFX->setTexture(2, NULL);*/ if (mBrdfTexture) { @@ -785,54 +828,33 @@ void RenderProbeMgr::render( SceneRenderState *state ) else GFX->setTexture(3, NULL); - //GFX->setCubeArrayTexture(4, mCubemapArray); - //GFX->setCubeArrayTexture(5, mIrradArray); + GFX->setCubeArrayTexture(4, mCubemapArray); + GFX->setCubeArrayTexture(5, mIrradArray); - ProbeRenderInst* curEntry = ProbeRenderInst::all[0]; - count = MAXPROBECOUNT; - //Final packing - AlignedArray _probePositions(count, sizeof(Point4F), (U8*)probePositions.address(), false); - AlignedArray _probeBBMin(count, sizeof(Point4F), (U8*)probeBBMin.address(), false); - AlignedArray _probeBBMax(count, sizeof(Point4F), (U8*)probeBBMax.address(), false); - AlignedArray _probeUseSphereMode(count, sizeof(float), (U8*)probeUseSphereMode.address(), false); - AlignedArray _probeRadius(count, sizeof(float), (U8*)probeRadius.address(), false); - AlignedArray _probeAttenuation(count, sizeof(float), (U8*)probeAttenuation.address(), false); - - matParams->set(probePositionSC, _probePositions); - matParams->set(probeWorldToObjSC, probeWorldToObj.address(), count); - matParams->set(probeBBMinSC, _probeBBMin); - matParams->set(probeBBMaxSC, _probeBBMax); - matParams->set(probeUseSphereModeSC, _probeUseSphereMode); - matParams->set(probeRadiusSC, _probeRadius); - matParams->set(probeAttenuationSC, _probeAttenuation); - - // Set geometry - GFX->setVertexBuffer(mFarFrustumQuadVerts); - GFX->setPrimitiveBuffer(NULL); - - while (reflProbeMat->matInstance->setupPass(state, sgData)) + if (numProbesSC->isValid()) { - // Set transforms - matrixSet.setWorld(*sgData.objTrans); - reflProbeMat->matInstance->setTransforms(matrixSet, state); - reflProbeMat->matInstance->setSceneInfo(state, sgData); + mLastConstants->set(numProbesSC, (float)mEffectiveProbeCount); - GFX->drawPrimitive(GFXTriangleStrip, 0, 2); + mLastConstants->set(probePositionSC, mProbePositions); + + mLastConstants->set(probePositionSC, mProbePositions); + mLastConstants->set(probeWorldToObjSC, probeWorldToObj.address(), mEffectiveProbeCount); + mLastConstants->set(probeBBMinSC, mProbeBBMin); + mLastConstants->set(probeBBMaxSC, mProbeBBMax); + mLastConstants->set(probeUseSphereModeSC, mProbeUseSphereMode); + mLastConstants->set(probeRadiusSC, mProbeRadius); + mLastConstants->set(probeAttenuationSC, mProbeAttenuation); } } - GFX->popActiveRenderTarget(); + // Finish up. + //if (isRenderingToTarget) + // _onPostRender(); - //PROBEMGR->unregisterAllProbes(); - //PROBEMGR->mRegisteredProbes.clear(); + // Make sure the effect is gonna render. + getProbeArrayEffect()->setSkip(false); - PROFILE_END(); - - GFX->setVertexBuffer(NULL); - GFX->setPrimitiveBuffer(NULL); - - // Fire off a signal to let others know that light-bin rendering is ending now - //getRenderSignal().trigger(state, this); + //PROFILE_END(); } // diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index ea735e29a..2142fe04d 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -268,12 +268,22 @@ class RenderProbeMgr : public RenderBinManager ReflectProbeMaterialInfo* mReflectProbeMaterial; + GFXShaderConstHandle *numProbesSC; + GFXShaderConstHandle *probePositionSC; + GFXShaderConstHandle *probeWorldToObjSC; + GFXShaderConstHandle *probeBBMinSC; + GFXShaderConstHandle *probeBBMaxSC; + GFXShaderConstHandle *probeUseSphereModeSC; + GFXShaderConstHandle *probeRadiusSC; + GFXShaderConstHandle *probeAttenuationSC; + /// The scene graph the light manager is associated with. - SceneManager *mSceneManager; + //SceneManager *mSceneManager; ProbeConstantMap mConstantLookup; GFXShaderRef mLastShader; - ProbeShaderConstants* mLastConstants; + GFXShaderConstBufferRef mLastConstants; + ProbeShaderConstants* mLastForwardConstants; // // @@ -306,7 +316,7 @@ protected: GFXTextureObject * mBrdfTexture; //Array rendering - + U32 mEffectiveProbeCount; Vector probePositions; Vector probeWorldToObj; Vector probeBBMin; @@ -317,6 +327,13 @@ protected: Vector cubeMaps; Vector irradMaps; + AlignedArray mProbePositions; + AlignedArray mProbeBBMin; + AlignedArray mProbeBBMax; + AlignedArray mProbeUseSphereMode; + AlignedArray mProbeRadius; + AlignedArray mProbeAttenuation; + GFXCubemapArrayHandle mCubemapArray; GFXCubemapArrayHandle mIrradArray; public: @@ -348,10 +365,7 @@ public: void registerProbe(U32 probeIdx); - // Returns the scene manager passed at activation. - SceneManager* getSceneManager() { return mSceneManager; } - - void setSceneManager(SceneManager* sceneManager) { mSceneManager = sceneManager; } + void unregisterProbe(U32 probeIdx); /// Debug rendering static bool smRenderReflectionProbes; @@ -363,15 +377,7 @@ RenderProbeMgr* RenderProbeMgr::getProbeManager() { RenderProbeMgr* probeManager = new RenderProbeMgr(); - if (gClientSceneGraph != nullptr) - { - probeManager->setSceneManager(gClientSceneGraph); - smProbeManager = probeManager; - } - else - { - delete probeManager; - } + smProbeManager = probeManager; } return smProbeManager; diff --git a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs index c70ea54e3..f646c95a4 100644 --- a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs +++ b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs @@ -500,12 +500,12 @@ singleton PostEffect( reflectionProbeArrayPostFX ) //texture[0] = "#highlight"; //texture[1] = "$backBuffer"; - texture[0] = "$deferredBuffer"; - texture[1] = "$colorBuffer"; - texture[2] = "$matInfoBuffer"; + texture[0] = "#deferred"; + texture[1] = "#color"; + texture[2] = "#matinfo"; texture[3] = "$BRDFTexture"; texture[4] = "$cubeMap"; texture[5] = "$irradianceCubemap"; - target = "$backBuffer"; + target = "AL_FormatToken"; }; \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl index 9ae026ba0..d320a99ed 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl @@ -1,5 +1,6 @@ -#include "../postFx.hlsl" - +#include "../../postFx/postFx.hlsl" +#include "../../shaderModel.hlsl" +#include "../../shaderModelAutoGen.hlsl" #include "../../lighting.hlsl" TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0); @@ -146,6 +147,9 @@ float4 main( PFXVertToPix IN ) : SV_TARGET float finalSum = blendSum; + return TORQUE_TEX2D(colorBuffer, IN.uv0.xy); + //return float4(surface.N,1); + //return float4(1,1,1, 1); //return float4(finalSum,finalSum,finalSum, 1); // Normalize blendVal From 34abe1b835e5ac8d30e668c0f8ca19f27a3acae2 Mon Sep 17 00:00:00 2001 From: Areloch Date: Tue, 12 Feb 2019 01:10:30 -0600 Subject: [PATCH 5/8] Updated the PostFX ability to setShaderConsts and cubetextures for probes --- Engine/source/postFx/postEffect.cpp | 426 +++++++++++++++--- Engine/source/postFx/postEffect.h | 84 ++++ .../source/renderInstance/renderProbeMgr.cpp | 136 ++---- Engine/source/renderInstance/renderProbeMgr.h | 23 +- .../client/lighting/advanced/shaders.cs | 6 +- .../advanced/reflectionProbeArrayP.hlsl | 30 +- 6 files changed, 504 insertions(+), 201 deletions(-) diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index b123109e8..f93333d16 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -170,6 +170,57 @@ void PostEffect::EffectConst::set( const String &newVal ) mStringVal = newVal; mDirty = true; + mValueType = StringType; +} + +void PostEffect::EffectConst::set(const F32 &newVal) +{ + if (mFloatVal == newVal) + return; + + mFloatVal = newVal; + mDirty = true; + mValueType = FloatType; +} + +void PostEffect::EffectConst::set(const Point4F &newVal) +{ + if (mPointVal == newVal) + return; + + mPointVal = newVal; + mDirty = true; + mValueType = PointType; +} + +void PostEffect::EffectConst::set(const MatrixF &newVal) +{ + if (mMatrixVal == newVal) + return; + + mMatrixVal = newVal; + mDirty = true; + mValueType = MatrixType; +} + +void PostEffect::EffectConst::set(const Vector &newVal) +{ + //if (mPointArrayVal == newVal) + // return; + + mPointArrayVal = newVal; + mDirty = true; + mValueType = PointArrayType; +} + +void PostEffect::EffectConst::set(const Vector &newVal) +{ + //if (mMatrixArrayVal == newVal) + // return; + + mMatrixArrayVal = newVal; + mDirty = true; + mValueType = MatrixArrayType; } void PostEffect::EffectConst::setToBuffer( GFXShaderConstBufferRef buff ) @@ -194,71 +245,179 @@ void PostEffect::EffectConst::setToBuffer( GFXShaderConstBufferRef buff ) // Expand to other types as necessary. U32 arraySize = mHandle->getArraySize(); - const char *strVal = mStringVal.c_str(); + if (mValueType == StringType) + { + const char *strVal = mStringVal.c_str(); - if ( type == GFXSCT_Int ) - { - S32 val; - Con::setData( TypeS32, &val, 0, 1, &strVal ); - buff->set( mHandle, val ); - } - else if ( type == GFXSCT_Float ) - { - F32 val; - Con::setData( TypeF32, &val, 0, 1, &strVal ); - buff->set( mHandle, val ); - } - else if ( type == GFXSCT_Float2 ) - { - Point2F val; - Con::setData( TypePoint2F, &val, 0, 1, &strVal ); - buff->set( mHandle, val ); - } - else if ( type == GFXSCT_Float3 ) - { - Point3F val; - Con::setData( TypePoint3F, &val, 0, 1, &strVal ); - buff->set( mHandle, val ); - } - else if ( type == GFXSCT_Float4 ) - { - Point4F val; - - if ( arraySize > 1 ) + if (type == GFXSCT_Int) { - // Do array setup! - //U32 unitCount = StringUnit::getUnitCount( strVal, "\t" ); - //AssertFatal( unitCount == arraySize, "" ); + S32 val; + Con::setData(TypeS32, &val, 0, 1, &strVal); + buff->set(mHandle, val); + } + else if (type == GFXSCT_Float) + { + F32 val; + Con::setData(TypeF32, &val, 0, 1, &strVal); + buff->set(mHandle, val); + } + else if (type == GFXSCT_Float2) + { + Point2F val; + Con::setData(TypePoint2F, &val, 0, 1, &strVal); + buff->set(mHandle, val); + } + else if (type == GFXSCT_Float3) + { + Point3F val; + Con::setData(TypePoint3F, &val, 0, 1, &strVal); + buff->set(mHandle, val); + } + else if (type == GFXSCT_Float4) + { + Point4F val; - String tmpString; - Vector valArray; - - for ( U32 i = 0; i < arraySize; i++ ) + if (arraySize > 1) { - tmpString = StringUnit::getUnit( strVal, i, "\t" ); - valArray.increment(); - const char *tmpCStr = tmpString.c_str(); + // Do array setup! + //U32 unitCount = StringUnit::getUnitCount( strVal, "\t" ); + //AssertFatal( unitCount == arraySize, "" ); - Con::setData( TypePoint4F, &valArray.last(), 0, 1, &tmpCStr ); + String tmpString; + Vector valArray; + + for (U32 i = 0; i < arraySize; i++) + { + tmpString = StringUnit::getUnit(strVal, i, "\t"); + valArray.increment(); + const char *tmpCStr = tmpString.c_str(); + + Con::setData(TypePoint4F, &valArray.last(), 0, 1, &tmpCStr); + } + + AlignedArray rectData(valArray.size(), sizeof(Point4F), (U8*)valArray.address(), false); + buff->set(mHandle, rectData); + } + else + { + // Do regular setup. + Con::setData(TypePoint4F, &val, 0, 1, &strVal); + buff->set(mHandle, val); } - - AlignedArray rectData( valArray.size(), sizeof( Point4F ), (U8*)valArray.address(), false ); - buff->set( mHandle, rectData ); } else { - // Do regular setup. - Con::setData( TypePoint4F, &val, 0, 1, &strVal ); - buff->set( mHandle, val ); +#if TORQUE_DEBUG + const char* err = avar("PostEffect::EffectConst::setToBuffer $s type is not implemented", mName.c_str()); + Con::errorf(err); + GFXAssertFatal(0, err); +#endif } } - else + else if (mValueType == FloatType) { + if (type == GFXSCT_Float) + { + buff->set(mHandle, mFloatVal); + } + else + { #if TORQUE_DEBUG - const char* err = avar("PostEffect::EffectConst::setToBuffer $s type is not implemented", mName.c_str()); - Con::errorf(err); - GFXAssertFatal(0,err); + const char* err = avar("PostEffect::EffectConst::setToBuffer $s type is not implemented", mName.c_str()); + Con::errorf(err); + GFXAssertFatal(0, err); #endif + } + } + else if (mValueType == PointType) + { + if (type == GFXSCT_Float2) + { + buff->set(mHandle, Point2F(mPointVal.x, mPointVal.y)); + } + else if (type == GFXSCT_Float3) + { + buff->set(mHandle, Point3F(mPointVal.x, mPointVal.y, mPointVal.z)); + } + else if (type == GFXSCT_Float4) + { + buff->set(mHandle, mPointVal); + } + else + { +#if TORQUE_DEBUG + const char* err = avar("PostEffect::EffectConst::setToBuffer $s type is not implemented", mName.c_str()); + Con::errorf(err); + GFXAssertFatal(0, err); +#endif + } + } + else if (mValueType == MatrixType) + { + if (type == GFXSCT_Float4x4) + { + buff->set(mHandle, mMatrixVal); + } + else + { + #if TORQUE_DEBUG + const char* err = avar("PostEffect::EffectConst::setToBuffer $s type is not implemented", mName.c_str()); + Con::errorf(err); + GFXAssertFatal(0, err); + #endif + } + } + else if (mValueType == PointArrayType) + { + if (type == GFXSCT_Float4) + { + if (arraySize != mPointArrayVal.size()) + { + #if TORQUE_DEBUG + const char* err = avar("PostEffect::EffectConst::setToBuffer PointArrayType, attempted to feed an array that does not match the uniform array's size!"); + Con::errorf(err); + GFXAssertFatal(0, err); + #endif + return; + } + + AlignedArray alignedVal = AlignedArray(arraySize, sizeof(Point4F), (U8*)mPointArrayVal.address(), false); + + buff->set(mHandle, alignedVal); + } + else + { + #if TORQUE_DEBUG + const char* err = avar("PostEffect::EffectConst::setToBuffer $s type is not implemented", mName.c_str()); + Con::errorf(err); + GFXAssertFatal(0, err); + #endif + } + } + else if (mValueType == MatrixArrayType) + { + if (type == GFXSCT_Float4x4) + { + if (arraySize != mMatrixArrayVal.size()) + { + #if TORQUE_DEBUG + const char* err = avar("PostEffect::EffectConst::setToBuffer MatrixArrayType, attempted to feed an array that does not match the uniform array's size!"); + Con::errorf(err); + GFXAssertFatal(0, err); + #endif + return; + } + + buff->set(mHandle, mMatrixArrayVal.address(), arraySize); + } + else + { + #if TORQUE_DEBUG + const char* err = avar("PostEffect::EffectConst::setToBuffer $s type is not implemented", mName.c_str()); + Con::errorf(err); + GFXAssertFatal(0, err); + #endif + } } } @@ -413,6 +572,8 @@ bool PostEffect::onAdd() // Find additional textures for( S32 i = 0; i < NumTextures; i++ ) { + mTextureType[i] = NormalTextureType; + String texFilename = mTexFilename[i]; // Skip empty stages or ones with variable or target names. @@ -915,6 +1076,11 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) setShaderConsts_callback(); } + if (mShaderName == String("PFX_ReflectionProbeArray") || getName() == StringTable->insert("reflectionProbeArrayPostFX")) + { + bool derp = true; + } + EffectConstTable::Iterator iter = mEffectConsts.begin(); for ( ; iter != mEffectConsts.end(); iter++ ) iter->value->setToBuffer( mShaderConsts ); @@ -972,6 +1138,30 @@ void PostEffect::_setupTexture( U32 stage, GFXTexHandle &inputTex, const RectI * GFX->setTexture( stage, theTex ); } +void PostEffect::_setupCubemapTexture(U32 stage, GFXCubemapHandle &inputTex) +{ + RectI viewport = GFX->getViewport(); + + mActiveTextures[stage] = nullptr; + mActiveNamedTarget[stage] = nullptr; + mActiveTextureViewport[stage] = viewport; + + if (inputTex.isValid()) + GFX->setCubeTexture(stage, inputTex); +} + +void PostEffect::_setupCubemapArrayTexture(U32 stage, GFXCubemapArrayHandle &inputTex) +{ + RectI viewport = GFX->getViewport(); + + mActiveTextures[stage] = nullptr; + mActiveNamedTarget[stage] = nullptr; + mActiveTextureViewport[stage] = viewport; + + if (inputTex.isValid()) + GFX->setCubeArrayTexture(stage, inputTex); +} + void PostEffect::_setupTransforms() { // Set everything to identity. @@ -1188,8 +1378,15 @@ void PostEffect::process( const SceneRenderState *state, GFXTransformSaver saver; // Set the textures. - for ( U32 i = 0; i < NumTextures; i++ ) - _setupTexture( i, inOutTex, inTexViewport ); + for (U32 i = 0; i < NumTextures; i++) + { + if (mTextureType[i] == NormalTextureType) + _setupTexture(i, inOutTex, inTexViewport); + else if (mTextureType[i] == CubemapType) + _setupCubemapTexture(i, mCubemapTextures[i]); + else if (mTextureType[i] == CubemapArrayType) + _setupCubemapArrayTexture(i, mCubemapArrayTextures[i]); + } _setupStateBlock( state ) ; _setupTransforms(); @@ -1406,6 +1603,38 @@ void PostEffect::setTexture( U32 index, const String &texFilePath ) // Try to load the texture. mTextures[index].set( texFilePath, &PostFxTextureProfile, avar( "%s() - (line %d)", __FUNCTION__, __LINE__ ) ); + + mTextureType[index] = NormalTextureType; +} + +void PostEffect::setCubemapTexture(U32 index, const GFXCubemapHandle &cubemapHandle) +{ + // Set the new texture name. + mCubemapTextures[index].free(); + + // Skip empty stages or ones with variable or target names. + if (cubemapHandle.isNull()) + return; + + // Try to load the texture. + mCubemapTextures[index] = cubemapHandle; + + mTextureType[index] = CubemapType; +} + +void PostEffect::setCubemapArrayTexture(U32 index, const GFXCubemapArrayHandle &cubemapArrayHandle) +{ + // Set the new texture name. + mCubemapArrayTextures[index].free(); + + // Skip empty stages or ones with variable or target names. + if (cubemapArrayHandle.isNull()) + return; + + // Try to load the texture. + mCubemapArrayTextures[index] = cubemapArrayHandle; + + mTextureType[index] = CubemapArrayType; } void PostEffect::setShaderConst( const String &name, const String &val ) @@ -1422,6 +1651,76 @@ void PostEffect::setShaderConst( const String &name, const String &val ) iter->value->set( val ); } +void PostEffect::setShaderConst(const String &name, const F32 &val) +{ + PROFILE_SCOPE(PostEffect_SetShaderConst_Float); + + EffectConstTable::Iterator iter = mEffectConsts.find(name); + if (iter == mEffectConsts.end()) + { + EffectConst *newConst = new EffectConst(name, val); + iter = mEffectConsts.insertUnique(name, newConst); + } + + iter->value->set(val); +} + +void PostEffect::setShaderConst(const String &name, const Point4F &val) +{ + PROFILE_SCOPE(PostEffect_SetShaderConst_Point); + + EffectConstTable::Iterator iter = mEffectConsts.find(name); + if (iter == mEffectConsts.end()) + { + EffectConst *newConst = new EffectConst(name, val); + iter = mEffectConsts.insertUnique(name, newConst); + } + + iter->value->set(val); +} + +void PostEffect::setShaderConst(const String &name, const MatrixF &val) +{ + PROFILE_SCOPE(PostEffect_SetShaderConst_Matrix); + + EffectConstTable::Iterator iter = mEffectConsts.find(name); + if (iter == mEffectConsts.end()) + { + EffectConst *newConst = new EffectConst(name, val); + iter = mEffectConsts.insertUnique(name, newConst); + } + + iter->value->set(val); +} + +void PostEffect::setShaderConst(const String &name, const Vector &val) +{ + PROFILE_SCOPE(PostEffect_SetShaderConst_PointArray); + + EffectConstTable::Iterator iter = mEffectConsts.find(name); + if (iter == mEffectConsts.end()) + { + EffectConst *newConst = new EffectConst(name, val); + iter = mEffectConsts.insertUnique(name, newConst); + } + + iter->value->set(val); +} + +void PostEffect::setShaderConst(const String &name, const Vector &val) +{ + PROFILE_SCOPE(PostEffect_SetShaderConst_MatrixArray); + + EffectConstTable::Iterator iter = mEffectConsts.find(name); + if (iter == mEffectConsts.end()) + { + EffectConst *newConst = new EffectConst(name, val); + iter = mEffectConsts.insertUnique(name, newConst); + } + + iter->value->set(val); +} + F32 PostEffect::getAspectRatio() const { const Point2I &rtSize = GFX->getActiveRenderTarget()->getSize(); @@ -1473,18 +1772,21 @@ void PostEffect::_checkRequirements() // they exist... else we're invalid. for ( U32 i=0; i < NumTextures; i++ ) { - const String &texFilename = mTexFilename[i]; - - if ( texFilename.isNotEmpty() && texFilename[0] == '#' ) + if (mTextureType[i] == NormalTextureType) { - NamedTexTarget *namedTarget = NamedTexTarget::find( texFilename.c_str() + 1 ); - if (!namedTarget) + const String &texFilename = mTexFilename[i]; + + if (texFilename.isNotEmpty() && texFilename[0] == '#') { - return; + NamedTexTarget *namedTarget = NamedTexTarget::find(texFilename.c_str() + 1); + if (!namedTarget) + { + return; + } + + // Grab the macros for shader initialization. + namedTarget->getShaderMacros(¯os); } - - // Grab the macros for shader initialization. - namedTarget->getShaderMacros( ¯os ); } } diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index 3f2001be0..377336a9e 100644 --- a/Engine/source/postFx/postEffect.h +++ b/Engine/source/postFx/postEffect.h @@ -41,6 +41,9 @@ #ifndef _GFXTEXTUREHANDLE_H_ #include "gfx/gfxTextureHandle.h" #endif +#ifndef _GFXCUBEMAP_H_ +#include "gfx/gfxCubemap.h" +#endif #ifndef _GFXTARGET_H_ #include "gfx/gfxTarget.h" #endif @@ -88,7 +91,16 @@ protected: FileName mTexFilename[NumTextures]; bool mTexSRGB[NumTextures]; + enum + { + NormalTextureType = 0, + CubemapType, + CubemapArrayType, + } mTextureType[NumTextures]; + GFXTexHandle mTextures[NumTextures]; + GFXCubemapHandle mCubemapTextures[NumTextures]; + GFXCubemapArrayHandle mCubemapArrayTextures[NumTextures]; NamedTexTarget mNamedTarget; NamedTexTarget mNamedTargetDepthStencil; @@ -210,7 +222,52 @@ protected: set( val ); } + EffectConst(const String &name, const F32 &val) + : mName(name), + mHandle(NULL), + mDirty(true) + { + set(val); + } + + EffectConst(const String &name, const Point4F &val) + : mName(name), + mHandle(NULL), + mDirty(true) + { + set(val); + } + + EffectConst(const String &name, const MatrixF &val) + : mName(name), + mHandle(NULL), + mDirty(true) + { + set(val); + } + + EffectConst(const String &name, const Vector &val) + : mName(name), + mHandle(NULL), + mDirty(true) + { + set(val); + } + + EffectConst(const String &name, const Vector &val) + : mName(name), + mHandle(NULL), + mDirty(true) + { + set(val); + } + void set( const String &newVal ); + void set(const F32 &newVal); + void set(const Point4F &newVal); + void set(const MatrixF &newVal); + void set(const Vector &newVal); + void set(const Vector &newVal); void setToBuffer( GFXShaderConstBufferRef buff ); @@ -220,6 +277,23 @@ protected: String mStringVal; + F32 mFloatVal; + Point4F mPointVal; + MatrixF mMatrixVal; + + Vector mPointArrayVal; + Vector mMatrixArrayVal; + + enum + { + StringType, + FloatType, + PointType, + MatrixType, + PointArrayType, + MatrixArrayType + } mValueType; + bool mDirty; }; @@ -245,6 +319,9 @@ protected: /// virtual void _setupTexture( U32 slot, GFXTexHandle &inputTex, const RectI *inTexViewport ); + virtual void _setupCubemapTexture(U32 stage, GFXCubemapHandle &inputTex); + virtual void _setupCubemapArrayTexture(U32 slot, GFXCubemapArrayHandle &inputTex); + /// Protected set method for toggling the enabled state. static bool _setIsEnabled( void *object, const char *index, const char *data ); @@ -339,6 +416,8 @@ public: F32 getPriority() const { return mRenderPriority; } void setTexture( U32 index, const String &filePath ); + void setCubemapTexture(U32 index, const GFXCubemapHandle &cubemapHandle); + void setCubemapArrayTexture(U32 index, const GFXCubemapArrayHandle &cubemapArrayHandle); void setShaderMacro( const String &name, const String &value = String::EmptyString ); bool removeShaderMacro( const String &name ); @@ -346,6 +425,11 @@ public: /// void setShaderConst( const String &name, const String &val ); + void setShaderConst(const String &name, const F32 &val); + void setShaderConst(const String &name, const Point4F &val); + void setShaderConst(const String &name, const MatrixF &val); + void setShaderConst(const String &name, const Vector &val); + void setShaderConst(const String &name, const Vector &val); void setOnThisFrame( bool enabled ) { mOnThisFrame = enabled; } bool isOnThisFrame() { return mOnThisFrame; } diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 0a38686a7..2b76325ff 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -249,33 +249,6 @@ RenderProbeMgr::RenderProbeMgr() String brdfPath = Con::getVariable("$Core::BRDFTexture", "core/art/pbr/brdfTexture.dds"); mBrdfTexture = TEXMGR->createTexture(brdfPath, &GFXTexturePersistentProfile); - probePositions.setSize(MAXPROBECOUNT); - probePositions.fill(Point3F::Zero); - - probeWorldToObj.setSize(MAXPROBECOUNT); - probeWorldToObj.fill(MatrixF::Identity); - - probeBBMin.setSize(MAXPROBECOUNT); - probeBBMin.fill(Point3F::Zero); - - probeBBMax.setSize(MAXPROBECOUNT); - probeBBMax.fill(Point3F::Zero); - - probeUseSphereMode.setSize(MAXPROBECOUNT); - probeUseSphereMode.fill(0.0f); - - probeRadius.setSize(MAXPROBECOUNT); - probeRadius.fill(0.0f); - - probeAttenuation.setSize(MAXPROBECOUNT); - probeAttenuation.fill(0.0f); - - cubeMaps.setSize(MAXPROBECOUNT); - cubeMaps.fill(NULL); - - irradMaps.setSize(MAXPROBECOUNT); - irradMaps.fill(NULL); - mEffectiveProbeCount = 0; mProbeArrayEffect = nullptr; @@ -363,28 +336,22 @@ PostEffect* RenderProbeMgr::getProbeArrayEffect() void RenderProbeMgr::_setupStaticParameters() { - mLastShader = mProbeArrayEffect->getShader(); - - if (mLastShader == nullptr) - return; - - mLastConstants = mLastShader->allocConstBuffer(); - - numProbesSC = mLastShader->getShaderConstHandle("$numProbes"); - - probePositionSC = mLastShader->getShaderConstHandle("$inProbePosArray"); - probeWorldToObjSC = mLastShader->getShaderConstHandle("$worldToObjArray"); - probeBBMinSC = mLastShader->getShaderConstHandle("$bbMinArray"); - probeBBMaxSC = mLastShader->getShaderConstHandle("$bbMaxArray"); - probeUseSphereModeSC = mLastShader->getShaderConstHandle("$useSphereMode"); - probeRadiusSC = mLastShader->getShaderConstHandle("$radius"); - probeAttenuationSC = mLastShader->getShaderConstHandle("$attenuation"); - //Array rendering U32 probeCount = ProbeRenderInst::all.size(); mEffectiveProbeCount = 0; + probePositions.setSize(MAXPROBECOUNT); + probeWorldToObj.setSize(MAXPROBECOUNT); + probeBBMin.setSize(MAXPROBECOUNT); + probeBBMax.setSize(MAXPROBECOUNT); + probeUseSphereMode.setSize(MAXPROBECOUNT); + probeRadius.setSize(MAXPROBECOUNT); + probeAttenuation.setSize(MAXPROBECOUNT); + + cubeMaps.setSize(MAXPROBECOUNT); + irradMaps.setSize(MAXPROBECOUNT); + for (U32 i = 0; i < probeCount; i++) { if (mEffectiveProbeCount >= MAXPROBECOUNT) @@ -415,10 +382,10 @@ void RenderProbeMgr::_setupStaticParameters() probeBBMin[i] = curEntry->mBounds.minExtents; probeBBMax[i] = curEntry->mBounds.maxExtents; - probeUseSphereMode[i] = curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0; + probeUseSphereMode[i] = Point4F(curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 0,0,0); - probeRadius[i] = curEntry->mRadius; - probeAttenuation[i] = 1; + probeRadius[i] = Point4F(curEntry->mRadius,0,0,0); + probeAttenuation[i] = Point4F(1, 0, 0, 0); cubeMaps[i] = curEntry->mCubemap; irradMaps[i] = curEntry->mIrradianceCubemap; @@ -433,44 +400,6 @@ void RenderProbeMgr::_setupStaticParameters() mCubemapArray->initStatic(cubeMaps.address(), mEffectiveProbeCount); mIrradArray->initStatic(irradMaps.address(), mEffectiveProbeCount); - - /*NamedTexTarget *deferredTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName); - if (deferredTarget) - GFX->setTexture(0, deferredTarget->getTexture()); - else - GFX->setTexture(0, NULL); - - NamedTexTarget *colorTarget = NamedTexTarget::find(RenderDeferredMgr::ColorBufferName); - if (colorTarget) - GFX->setTexture(1, colorTarget->getTexture()); - else - GFX->setTexture(1, NULL); - - NamedTexTarget *matinfoTarget = NamedTexTarget::find(RenderDeferredMgr::MatInfoBufferName); - if (matinfoTarget) - GFX->setTexture(2, matinfoTarget->getTexture()); - else - GFX->setTexture(2, NULL); - - if (mBrdfTexture) - { - GFX->setTexture(3, mBrdfTexture); - } - else - GFX->setTexture(3, NULL);*/ - - //GFX->setCubeArrayTexture(4, mCubemapArray); - //GFX->setCubeArrayTexture(5, mIrradArray); - - ProbeRenderInst* curEntry = ProbeRenderInst::all[0]; - //count = MAXPROBECOUNT; - //Final packing - mProbePositions = AlignedArray(mEffectiveProbeCount, sizeof(Point4F), (U8*)probePositions.address(), false); - mProbeBBMin = AlignedArray(mEffectiveProbeCount, sizeof(Point4F), (U8*)probeBBMin.address(), false); - mProbeBBMax = AlignedArray(mEffectiveProbeCount, sizeof(Point4F), (U8*)probeBBMax.address(), false); - mProbeUseSphereMode = AlignedArray(mEffectiveProbeCount, sizeof(float), (U8*)probeUseSphereMode.address(), false); - mProbeRadius = AlignedArray(mEffectiveProbeCount, sizeof(float), (U8*)probeRadius.address(), false); - mProbeAttenuation = AlignedArray(mEffectiveProbeCount, sizeof(float), (U8*)probeAttenuation.address(), false); } } @@ -788,7 +717,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) // If this is a non-diffuse pass or we have no objects to // render then tell the effect to skip rendering. - if (!state->isDiffusePass()/* || binSize == 0*/|| !numProbesSC || !numProbesSC->isValid()) + if (!state->isDiffusePass()/* || binSize == 0*/) { getProbeArrayEffect()->setSkip(true); return; @@ -821,30 +750,29 @@ void RenderProbeMgr::render( SceneRenderState *state ) else GFX->setTexture(2, NULL);*/ - if (mBrdfTexture) + /*if (mBrdfTexture) { GFX->setTexture(3, mBrdfTexture); } else - GFX->setTexture(3, NULL); + GFX->setTexture(3, NULL);*/ - GFX->setCubeArrayTexture(4, mCubemapArray); - GFX->setCubeArrayTexture(5, mIrradArray); + //GFX->setCubeArrayTexture(4, mCubemapArray); + //GFX->setCubeArrayTexture(5, mIrradArray); + mProbeArrayEffect->setCubemapArrayTexture(4, mCubemapArray); + mProbeArrayEffect->setCubemapArrayTexture(5, mIrradArray); - if (numProbesSC->isValid()) - { - mLastConstants->set(numProbesSC, (float)mEffectiveProbeCount); - - mLastConstants->set(probePositionSC, mProbePositions); - - mLastConstants->set(probePositionSC, mProbePositions); - mLastConstants->set(probeWorldToObjSC, probeWorldToObj.address(), mEffectiveProbeCount); - mLastConstants->set(probeBBMinSC, mProbeBBMin); - mLastConstants->set(probeBBMaxSC, mProbeBBMax); - mLastConstants->set(probeUseSphereModeSC, mProbeUseSphereMode); - mLastConstants->set(probeRadiusSC, mProbeRadius); - mLastConstants->set(probeAttenuationSC, mProbeAttenuation); - } + U32 mips = ProbeRenderInst::all[0]->mCubemap.getPointer()->getMipMapLevels(); + mProbeArrayEffect->setShaderConst("$cubeMips", (float)mips); + + mProbeArrayEffect->setShaderConst("$numProbes", (float)mEffectiveProbeCount); + mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositions); + mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObj); + mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMin); + mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMax); + mProbeArrayEffect->setShaderConst("$useSphereMode", probeUseSphereMode); + mProbeArrayEffect->setShaderConst("$radius", probeRadius); + mProbeArrayEffect->setShaderConst("$attenuation", probeAttenuation); } // Finish up. diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index 2142fe04d..d07e3da33 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -233,17 +233,6 @@ class RenderProbeMgr : public RenderBinManager MaterialParameterHandle *probeCount; - // - MaterialParameterHandle *numProbesSC; - - MaterialParameterHandle *probePositionSC; - MaterialParameterHandle *probeWorldToObjSC; - MaterialParameterHandle *probeBBMinSC; - MaterialParameterHandle *probeBBMaxSC; - MaterialParameterHandle *probeUseSphereModeSC; - MaterialParameterHandle *probeRadiusSC; - MaterialParameterHandle *probeAttenuationSC; - ReflectProbeMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat); virtual ~ReflectProbeMaterialInfo(); @@ -317,13 +306,13 @@ protected: //Array rendering U32 mEffectiveProbeCount; - Vector probePositions; + Vector probePositions; Vector probeWorldToObj; - Vector probeBBMin; - Vector probeBBMax; - Vector probeUseSphereMode; - Vector probeRadius; - Vector probeAttenuation; + Vector probeBBMin; + Vector probeBBMax; + Vector probeUseSphereMode; + Vector probeRadius; + Vector probeAttenuation; Vector cubeMaps; Vector irradMaps; diff --git a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs index f646c95a4..a834b2ea4 100644 --- a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs +++ b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs @@ -503,9 +503,9 @@ singleton PostEffect( reflectionProbeArrayPostFX ) texture[0] = "#deferred"; texture[1] = "#color"; texture[2] = "#matinfo"; - texture[3] = "$BRDFTexture"; - texture[4] = "$cubeMap"; - texture[5] = "$irradianceCubemap"; + texture[3] = "core/art/pbr/brdfTexture.dds"; + //texture[4] = "$cubeMap"; + //texture[5] = "$irradianceCubemap"; target = "AL_FormatToken"; }; \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl index d320a99ed..e20cd710c 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl @@ -18,17 +18,17 @@ uniform float cubeMips; #define MAX_PROBES 50 uniform float numProbes; -//TORQUE_UNIFORM_SAMPLERCUBEARRAY(cubeMapAR, 4); -//TORQUE_UNIFORM_SAMPLERCUBEARRAY(irradianceCubemapAR, 5); -TORQUE_UNIFORM_SAMPLERCUBE(cubeMapAR, 4); -TORQUE_UNIFORM_SAMPLERCUBE(irradianceCubemapAR, 5); +TORQUE_UNIFORM_SAMPLERCUBEARRAY(cubeMapAR, 4); +TORQUE_UNIFORM_SAMPLERCUBEARRAY(irradianceCubemapAR, 5); +//TORQUE_UNIFORM_SAMPLERCUBE(cubeMapAR, 4); +//TORQUE_UNIFORM_SAMPLERCUBE(irradianceCubemapAR, 5); uniform float4 inProbePosArray[MAX_PROBES]; uniform float4x4 worldToObjArray[MAX_PROBES]; uniform float4 bbMinArray[MAX_PROBES]; uniform float4 bbMaxArray[MAX_PROBES]; -uniform float useSphereMode[MAX_PROBES]; -uniform float radius[MAX_PROBES]; -uniform float2 attenuation[MAX_PROBES]; +uniform float4 useSphereMode[MAX_PROBES]; +uniform float4 radius[MAX_PROBES]; +uniform float4 attenuation[MAX_PROBES]; // Box Projected IBL Lighting // Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/ @@ -51,8 +51,8 @@ float3 iblBoxDiffuse( Surface surface, int id) { float3 cubeN = boxProject(surface.P, surface.N, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz); cubeN.z *=-1; - //return TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR,cubeN,id,0).xyz; - return TORQUE_TEXCUBELOD(irradianceCubemapAR,float4(cubeN,0)).xyz; + return TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR,cubeN,id,0).xyz; + //return TORQUE_TEXCUBELOD(irradianceCubemapAR,float4(cubeN,0)).xyz; } float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTexture), int id) @@ -68,8 +68,8 @@ float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTe float3 cubeR = normalize(r); cubeR = boxProject(surface.P, surface.N, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz); - //float3 radiance = TORQUE_TEXCUBEARRAYLOD(cubeMapAR,cubeR,id,lod).xyz * (brdf.x + brdf.y); - float3 radiance = TORQUE_TEXCUBELOD(cubeMapAR,float4(cubeR,lod)).xyz * (brdf.x + brdf.y); + float3 radiance = TORQUE_TEXCUBEARRAYLOD(cubeMapAR,cubeR,id,lod).xyz * (brdf.x + brdf.y); + //float3 radiance = TORQUE_TEXCUBELOD(cubeMapAR,float4(cubeR,lod)).xyz * (brdf.x + brdf.y); return radiance; } @@ -79,8 +79,8 @@ float defineBoxSpaceInfluence(Surface surface, int id) float tempAttenVal = 3.5; //replace with per probe atten float3 surfPosLS = mul( worldToObjArray[id], float4(surface.P,1.0)).xyz; - float3 boxMinLS = inProbePosArray[id].xyz-(float3(1,1,1)*radius[0]); - float3 boxMaxLS = inProbePosArray[id].xyz+(float3(1,1,1)*radius[0]); + float3 boxMinLS = inProbePosArray[id].xyz-(float3(1,1,1)*radius[0].x); + float3 boxMaxLS = inProbePosArray[id].xyz+(float3(1,1,1)*radius[0].x); float boxOuterRange = length(boxMaxLS - boxMinLS); float boxInnerRange = boxOuterRange / tempAttenVal; @@ -147,7 +147,7 @@ float4 main( PFXVertToPix IN ) : SV_TARGET float finalSum = blendSum; - return TORQUE_TEX2D(colorBuffer, IN.uv0.xy); + //return TORQUE_TEX2D(colorBuffer, IN.uv0.xy); //return float4(surface.N,1); //return float4(1,1,1, 1); //return float4(finalSum,finalSum,finalSum, 1); @@ -155,7 +155,7 @@ float4 main( PFXVertToPix IN ) : SV_TARGET // Normalize blendVal if (blendSum == 0.0f) // Possible with custom weight { - blendSum = 1.0f; + //blendSum = 1.0f; } float invBlendSumWeighted = 1.0f / blendSum; From b0c89dddff5d63ec77ac62faa8f9c7eba9bb3448 Mon Sep 17 00:00:00 2001 From: Areloch Date: Wed, 13 Feb 2019 00:37:50 -0600 Subject: [PATCH 6/8] WIP of adjusting the reflection probe's bake to utilize the ReflectionManager and CubeReflector instead of duplicating the capture code. --- .../source/T3D/lighting/reflectionProbe.cpp | 121 ++++-------------- Engine/source/renderInstance/renderProbeMgr.h | 3 +- 2 files changed, 29 insertions(+), 95 deletions(-) diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index 218b26c81..92175094b 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -51,6 +51,8 @@ #include "gfx/gfxTextureManager.h" #include "T3D/lighting/IBLUtilities.h" +#include "scene/reflector.h" + extern bool gEditingMission; extern ColorI gCanvasClearColor; bool ReflectionProbe::smRenderPreviewProbes = true; @@ -584,6 +586,8 @@ void ReflectionProbe::updateMaterial() if (mReflectionModeType != DynamicCubemap) { + mProbeInfo->mCubeReflector.unregisterReflector(); + if ((mReflectionModeType == BakedCubemap) && !mProbeUniqueID.isEmpty()) { if (mPrefilterMap != nullptr && mPrefilterMap->mCubemap.isValid()) @@ -609,6 +613,8 @@ void ReflectionProbe::updateMaterial() if (mReflectionModeType == DynamicCubemap && !mDynamicCubemap.isNull()) { mProbeInfo->mCubemap = mDynamicCubemap; + + mProbeInfo->mCubeReflector.registerReflector(this, reflectorDesc); //need to decide how we wanna do the reflectorDesc. static name or a field } else { @@ -904,17 +910,6 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro U32 startMSTime = Platform::getRealMilliseconds(); - /*PostEffect *preCapture = dynamic_cast(Sim::findObject("AL_PreCapture")); - PostEffect *deferredShading = dynamic_cast(Sim::findObject("AL_DeferredShading")); - if (preCapture) - { - preCapture->setShaderConst("$radius",String::ToString(mRadius)); - preCapture->setShaderConst("$captureRez", String::ToString(F32(resolution))); - preCapture->enable(); - } - if (deferredShading) - deferredShading->disable();*/ - GFXCubemapHandle sceneCaptureCubemap; if (mReflectionModeType == DynamicCubemap && mDynamicCubemap.isNull()) @@ -968,91 +963,34 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro if (!renderWithProbes) RenderProbeMgr::smRenderReflectionProbes = false; - for (U32 i = 0; i < 6; ++i) - { - GFXTexHandle blendTex; - blendTex.set(resolution, resolution, GFXFormatR16G16B16A16F, &GFXRenderTargetProfile, ""); + CubeReflector cubeRefl; + ReflectParams reflParams; - GFXTextureTargetRef baseTarget = GFX->allocRenderToTextureTarget(); + //need to get the query somehow. Likely do some sort of get function to fetch from the guiTSControl that's active + CameraQuery query; //need to get the last cameraQuery - GFX->clearTextureStateImmediate(0); - - baseTarget->attachTexture(GFXTextureTarget::Color0, sceneCaptureCubemap, i); + Frustum culler; + culler.set(false, + query.fov, + (F32)resolution / (F32)resolution, + query.nearPlane, + query.farPlane, + query.cameraMatrix); - // Standard view that will be overridden below. - VectorF vLookatPt(0.0f, 0.0f, 0.0f), vUpVec(0.0f, 0.0f, 0.0f), vRight(0.0f, 0.0f, 0.0f); + S32 stereoTarget = GFX->getCurrentStereoTarget(); - switch (i) - { - case 0: // D3DCUBEMAP_FACE_POSITIVE_X: - vLookatPt = VectorF(1.0f, 0.0f, 0.0f); - vUpVec = VectorF(0.0f, 1.0f, 0.0f); - break; - case 1: // D3DCUBEMAP_FACE_NEGATIVE_X: - vLookatPt = VectorF(-1.0f, 0.0f, 0.0f); - vUpVec = VectorF(0.0f, 1.0f, 0.0f); - break; - case 2: // D3DCUBEMAP_FACE_POSITIVE_Y: - vLookatPt = VectorF(0.0f, 1.0f, 0.0f); - vUpVec = VectorF(0.0f, 0.0f, -1.0f); - break; - case 3: // D3DCUBEMAP_FACE_NEGATIVE_Y: - vLookatPt = VectorF(0.0f, -1.0f, 0.0f); - vUpVec = VectorF(0.0f, 0.0f, 1.0f); - break; - case 4: // D3DCUBEMAP_FACE_POSITIVE_Z: - vLookatPt = VectorF(0.0f, 0.0f, 1.0f); - vUpVec = VectorF(0.0f, 1.0f, 0.0f); - break; - case 5: // D3DCUBEMAP_FACE_NEGATIVE_Z: - vLookatPt = VectorF(0.0f, 0.0f, -1.0f); - vUpVec = VectorF(0.0f, 1.0f, 0.0f); - break; - } + reflParams.culler = culler; + reflParams.eyeId = stereoTarget; + reflParams.query = &query; + reflParams.startOfUpdateMs = startMSTime; + reflParams.viewportExtent = Point2I(resolution, resolution); - // create camera matrix - VectorF cross = mCross(vUpVec, vLookatPt); - cross.normalizeSafe(); - - MatrixF matView(true); - matView.setColumn(0, cross); - matView.setColumn(1, vLookatPt); - matView.setColumn(2, vUpVec); - matView.setPosition(getPosition()+mProbePosOffset); - matView.inverse(); - - // set projection to 90 degrees vertical and horizontal - F32 left, right, top, bottom; - F32 nearPlane = 0.01f; - F32 farDist = 1000.f; - - MathUtils::makeFrustum(&left, &right, &top, &bottom, M_HALFPI_F, 1.0f, nearPlane); - Frustum frustum(false, left, right, top, bottom, nearPlane, farDist); - - F32 detailAdjustBackup = TSShapeInstance::smDetailAdjust; - TSShapeInstance::smDetailAdjust *= getNextPow2(resolution); - renderFrame(&baseTarget, matView, frustum, mCaptureMask & EDITOR_RENDER_TYPEMASK, gCanvasClearColor); - TSShapeInstance::smDetailAdjust = detailAdjustBackup; - - baseTarget->resolve(); - } - - if (sceneCaptureCubemap.isValid()) - { - validCubemap = true; - mDirty = false; - } - else - { - validCubemap = false; - } + cubeRefl.updateReflection(reflParams); //Now, save out the maps //create irridiance cubemap - if (validCubemap) + if (cubeRefl.getCubemap()) { - bool se = isServerObject(); - //Just to ensure we're prepped for the generation createClientResources(); @@ -1073,8 +1011,8 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false); - IBLUtilities::GenerateIrradianceMap(renderTarget, sceneCaptureCubemap, mIrridianceMap->mCubemap); - IBLUtilities::GeneratePrefilterMap(renderTarget, sceneCaptureCubemap, mPrefilterMipLevels, mPrefilterMap->mCubemap); + IBLUtilities::GenerateIrradianceMap(renderTarget, cubeRefl.getCubemap(), mIrridianceMap->mCubemap); + IBLUtilities::GeneratePrefilterMap(renderTarget, cubeRefl.getCubemap(), mPrefilterMipLevels, mPrefilterMap->mCubemap); IBLUtilities::SaveCubeMap(getIrradianceMapPath(), mIrridianceMap->mCubemap); IBLUtilities::SaveCubeMap(getPrefilterMapPath(), mPrefilterMap->mCubemap); @@ -1089,11 +1027,6 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro setMaskBits(-1); - /*if (preCapture) - preCapture->disable(); - if (deferredShading) - deferredShading->enable();*/ - U32 endMSTime = Platform::getRealMilliseconds(); F32 diffTime = F32(endMSTime - startMSTime); diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index d07e3da33..3a21a2a4b 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -67,9 +67,10 @@ struct ProbeRenderInst : public SystemInterface Point3F mProbePosOffset; GFXCubemapHandle mCubemap; - GFXCubemapHandle mIrradianceCubemap; + CubeReflector mCubeReflector; + GFXTexHandle *mBRDFTexture; /// The priority of this light used for From 9ec7eb999d7493537d606aa1814d5c80e7617b8c Mon Sep 17 00:00:00 2001 From: Areloch Date: Wed, 13 Feb 2019 16:56:28 -0600 Subject: [PATCH 7/8] Further cleanup, proper hook-in of CubeReflector for bake capture. Shifted update of probe data to be triggered by probe changes. Pack probes into the data arrays forward-first instead of keeping strict indicies. todo: move bake to probeManager, clean up old/commented code, remove old probeMaterial stuff --- .../source/T3D/lighting/reflectionProbe.cpp | 44 +++++++----- Engine/source/T3D/lighting/reflectionProbe.h | 5 +- .../source/renderInstance/renderProbeMgr.cpp | 67 ++++++++++--------- Engine/source/renderInstance/renderProbeMgr.h | 62 ++++++++++------- .../client/lighting/advanced/shaders.cs | 10 +-- Templates/Full/game/levels/AProbeTest.mis | 24 +++---- .../advanced/reflectionProbeArrayP.hlsl | 4 +- 7 files changed, 120 insertions(+), 96 deletions(-) diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index 92175094b..349649e9a 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -53,6 +53,8 @@ #include "scene/reflector.h" +#include "T3D/gameTSCtrl.h" + extern bool gEditingMission; extern ColorI gCanvasClearColor; bool ReflectionProbe::smRenderPreviewProbes = true; @@ -463,6 +465,8 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) { updateMaterial(); } + + PROBEMGR->updateProbes(); } void ReflectionProbe::createGeometry() @@ -914,7 +918,7 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro if (mReflectionModeType == DynamicCubemap && mDynamicCubemap.isNull()) { - //mCubemap->createMap(); + //this is wholely reundant when we actually use the proper dynamic cube reflector mDynamicCubemap = GFX->createCubemap(); if(mUseHDRCaptures) @@ -938,13 +942,6 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro Con::errorf("ReflectionProbe::bake() - Unable to bake our captures because probe doesn't have a unique ID set"); return; } - - sceneCaptureCubemap = GFX->createCubemap(); - - if (mUseHDRCaptures) - sceneCaptureCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F); - else - sceneCaptureCubemap->initDynamic(resolution, GFXFormatR8G8B8A8); } bool validCubemap = true; @@ -953,21 +950,31 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro // it for child control rendering below. GFXTransformSaver saver; - //bool saveEditingMission = gEditingMission; - //gEditingMission = false; - - //Set this to true to use the prior method where it goes through the SPT_Reflect path for the bake - bool probeRenderState = RenderProbeMgr::smRenderReflectionProbes; if (!renderWithProbes) RenderProbeMgr::smRenderReflectionProbes = false; + F32 farPlane = 1000.0f; + + ReflectorDesc reflDesc; + reflDesc.texSize = resolution; + reflDesc.farDist = farPlane; + reflDesc.detailAdjust = 1; + reflDesc.objectTypeMask = -1; + CubeReflector cubeRefl; + cubeRefl.registerReflector(this, &reflDesc); + ReflectParams reflParams; //need to get the query somehow. Likely do some sort of get function to fetch from the guiTSControl that's active CameraQuery query; //need to get the last cameraQuery + query.fov = 90; //90 degree slices for each of the 6 sides + query.nearPlane = 0.1f; + query.farPlane = farPlane; + query.headMatrix = MatrixF(); + query.cameraMatrix = getTransform(); Frustum culler; culler.set(false, @@ -979,11 +986,13 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro S32 stereoTarget = GFX->getCurrentStereoTarget(); + Point2I maxRes(2048, 2048); //basically a boundary so we don't go over this and break stuff + reflParams.culler = culler; reflParams.eyeId = stereoTarget; reflParams.query = &query; reflParams.startOfUpdateMs = startMSTime; - reflParams.viewportExtent = Point2I(resolution, resolution); + reflParams.viewportExtent = maxRes; cubeRefl.updateReflection(reflParams); @@ -1006,9 +1015,6 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro mPrefilterMap->mCubemap->initDynamic(resolution, GFXFormatR8G8B8A8); } - //IBLUtilities::GenerateAndSaveIrradianceMap(getIrradianceMapPath(), resolution, sceneCaptureCubemap, mIrridianceMap->mCubemap); - //IBLUtilities::GenerateAndSavePrefilterMap(getPrefilterMapPath(), resolution, sceneCaptureCubemap, mPrefilterMipLevels, mPrefilterMap->mCubemap); - GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false); IBLUtilities::GenerateIrradianceMap(renderTarget, cubeRefl.getCubemap(), mIrridianceMap->mCubemap); @@ -1025,7 +1031,9 @@ void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithPro if(!renderWithProbes) RenderProbeMgr::smRenderReflectionProbes = probeRenderState; - setMaskBits(-1); + setMaskBits(CubemapMask); + + cubeRefl.unregisterReflector(); U32 endMSTime = Platform::getRealMilliseconds(); F32 diffTime = F32(endMSTime - startMSTime); diff --git a/Engine/source/T3D/lighting/reflectionProbe.h b/Engine/source/T3D/lighting/reflectionProbe.h index db4bf4d7a..df7a2e994 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.h +++ b/Engine/source/T3D/lighting/reflectionProbe.h @@ -47,7 +47,6 @@ class BaseMatInstance; - //----------------------------------------------------------------------------- // This class implements a basic SceneObject that can exist in the world at a // 3D position and render itself. There are several valid ways to render an @@ -129,6 +128,10 @@ protected: GFXCubemapHandle mDynamicCubemap; bool mUseCubemap; + String cubeDescName; + U32 cubeDescId; + ReflectorDesc *reflectorDesc; + ///Prevents us from saving out the cubemaps(for now) but allows us the full HDR range on the in-memory cubemap captures bool mUseHDRCaptures; diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 2b76325ff..289c9a4f4 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -250,10 +250,13 @@ RenderProbeMgr::RenderProbeMgr() mBrdfTexture = TEXMGR->createTexture(brdfPath, &GFXTexturePersistentProfile); mEffectiveProbeCount = 0; + mMipCount = 0; mProbeArrayEffect = nullptr; numProbesSC = nullptr; + + smProbeManager = this; } RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder) @@ -334,12 +337,18 @@ PostEffect* RenderProbeMgr::getProbeArrayEffect() //Con::setIntVariable("lightMetrics::culledReflectProbes", 0/*mNumLightsCulled*/); // +void RenderProbeMgr::updateProbes() +{ + _setupStaticParameters(); +} + void RenderProbeMgr::_setupStaticParameters() { //Array rendering U32 probeCount = ProbeRenderInst::all.size(); mEffectiveProbeCount = 0; + mMipCount = 0; probePositions.setSize(MAXPROBECOUNT); probeWorldToObj.setSize(MAXPROBECOUNT); @@ -349,8 +358,8 @@ void RenderProbeMgr::_setupStaticParameters() probeRadius.setSize(MAXPROBECOUNT); probeAttenuation.setSize(MAXPROBECOUNT); - cubeMaps.setSize(MAXPROBECOUNT); - irradMaps.setSize(MAXPROBECOUNT); + cubeMaps.clear(); + irradMaps.clear(); for (U32 i = 0; i < probeCount; i++) { @@ -367,28 +376,33 @@ void RenderProbeMgr::_setupStaticParameters() if (!curEntry->mCubemap->isInitialised()) continue; + if (!curEntry->mIrradianceCubemap->isInitialised()) + continue; + if (curEntry->mIsSkylight) continue; + mMipCount = curEntry->mCubemap.getPointer()->getMipMapLevels(); + //Setup const Point3F &probePos = curEntry->getPosition(); - probePositions[i] = probePos + curEntry->mProbePosOffset; + probePositions[mEffectiveProbeCount] = probePos + curEntry->mProbePosOffset; MatrixF trans = curEntry->getTransform(); trans.inverse(); - probeWorldToObj[i] = trans; + probeWorldToObj[mEffectiveProbeCount] = trans; - probeBBMin[i] = curEntry->mBounds.minExtents; - probeBBMax[i] = curEntry->mBounds.maxExtents; + probeBBMin[mEffectiveProbeCount] = curEntry->mBounds.minExtents; + probeBBMax[mEffectiveProbeCount] = curEntry->mBounds.maxExtents; - probeUseSphereMode[i] = Point4F(curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 0,0,0); + probeUseSphereMode[mEffectiveProbeCount] = Point4F(curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 0,0,0); - probeRadius[i] = Point4F(curEntry->mRadius,0,0,0); - probeAttenuation[i] = Point4F(1, 0, 0, 0); + probeRadius[mEffectiveProbeCount] = Point4F(curEntry->mRadius,0,0,0); + probeAttenuation[mEffectiveProbeCount] = Point4F(1, 0, 0, 0); - cubeMaps[i] = curEntry->mCubemap; - irradMaps[i] = curEntry->mIrradianceCubemap; + cubeMaps.push_back(curEntry->mCubemap); + irradMaps.push_back(curEntry->mIrradianceCubemap); mEffectiveProbeCount++; } @@ -398,8 +412,8 @@ void RenderProbeMgr::_setupStaticParameters() mCubemapArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); mIrradArray = GFXCubemapArrayHandle(GFX->createCubemapArray()); - mCubemapArray->initStatic(cubeMaps.address(), mEffectiveProbeCount); - mIrradArray->initStatic(irradMaps.address(), mEffectiveProbeCount); + mCubemapArray->initStatic(cubeMaps.address(), cubeMaps.size()); + mIrradArray->initStatic(irradMaps.address(), irradMaps.size()); } } @@ -695,14 +709,12 @@ void RenderProbeMgr::render( SceneRenderState *state ) return; // Early out if nothing to draw. - if (!ProbeRenderInst::all.size()) - return; - - if (!RenderProbeMgr::smRenderReflectionProbes) - return; - - if (mEffectiveProbeCount == 0) - _setupStaticParameters(); //return; + if (!ProbeRenderInst::all.size() || !RenderProbeMgr::smRenderReflectionProbes || mEffectiveProbeCount == 0 + || !state->isDiffusePass() || cubeMaps.empty() || irradMaps.empty()) + { + getProbeArrayEffect()->setSkip(true); + return; + } GFXTransformSaver saver; @@ -717,18 +729,10 @@ void RenderProbeMgr::render( SceneRenderState *state ) // If this is a non-diffuse pass or we have no objects to // render then tell the effect to skip rendering. - if (!state->isDiffusePass()/* || binSize == 0*/) - { - getProbeArrayEffect()->setSkip(true); - return; - } - + //Array rendering U32 probeCount = ProbeRenderInst::all.size(); - if (probeCount == 0) - return; - if (mEffectiveProbeCount != 0) { //These will in theory be set by the postFX @@ -762,8 +766,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) mProbeArrayEffect->setCubemapArrayTexture(4, mCubemapArray); mProbeArrayEffect->setCubemapArrayTexture(5, mIrradArray); - U32 mips = ProbeRenderInst::all[0]->mCubemap.getPointer()->getMipMapLevels(); - mProbeArrayEffect->setShaderConst("$cubeMips", (float)mips); + mProbeArrayEffect->setShaderConst("$cubeMips", (float)mMipCount); mProbeArrayEffect->setShaderConst("$numProbes", (float)mEffectiveProbeCount); mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositions); diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index 3a21a2a4b..fd9147b27 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -48,6 +48,10 @@ #include "postFx/postEffectCommon.h" #endif +#ifndef _REFLECTOR_H_ +#include "scene/reflector.h" +#endif + static U32 MAXPROBECOUNT = 50; class PostEffect; @@ -303,47 +307,46 @@ protected: GFXShaderConstHandle *probeLocalPosSC, GFXShaderConstBuffer *shaderConsts); - GFXTextureObject * mBrdfTexture; + GFXTextureObject * mBrdfTexture; - //Array rendering - U32 mEffectiveProbeCount; - Vector probePositions; - Vector probeWorldToObj; - Vector probeBBMin; - Vector probeBBMax; - Vector probeUseSphereMode; - Vector probeRadius; - Vector probeAttenuation; - Vector cubeMaps; - Vector irradMaps; + //Array rendering + U32 mEffectiveProbeCount; + S32 mMipCount; + Vector probePositions; + Vector probeWorldToObj; + Vector probeBBMin; + Vector probeBBMax; + Vector probeUseSphereMode; + Vector probeRadius; + Vector probeAttenuation; + Vector cubeMaps; + Vector irradMaps; - AlignedArray mProbePositions; - AlignedArray mProbeBBMin; - AlignedArray mProbeBBMax; - AlignedArray mProbeUseSphereMode; - AlignedArray mProbeRadius; - AlignedArray mProbeAttenuation; + AlignedArray mProbePositions; + AlignedArray mProbeBBMin; + AlignedArray mProbeBBMax; + AlignedArray mProbeUseSphereMode; + AlignedArray mProbeRadius; + AlignedArray mProbeAttenuation; - GFXCubemapArrayHandle mCubemapArray; - GFXCubemapArrayHandle mIrradArray; + GFXCubemapArrayHandle mCubemapArray; + GFXCubemapArrayHandle mIrradArray; public: RenderProbeMgr(); RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder); // RenderBinMgr + void updateProbes(); + +protected: void _setupStaticParameters(); void _setupPerFrameParameters(const SceneRenderState *state); virtual void addElement(RenderInst *inst); virtual void render(SceneRenderState * state); - virtual void setProbeInfo(ProcessedMaterial *pmat, - const Material *mat, - const SceneData &sgData, - const SceneRenderState *state, - U32 pass, - GFXShaderConstBuffer *shaderConsts); ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer); +public: // ConsoleObject static void initPersistFields(); DECLARE_CONOBJECT(RenderProbeMgr); @@ -357,6 +360,13 @@ public: void unregisterProbe(U32 probeIdx); + virtual void setProbeInfo(ProcessedMaterial *pmat, + const Material *mat, + const SceneData &sgData, + const SceneRenderState *state, + U32 pass, + GFXShaderConstBuffer *shaderConsts); + /// Debug rendering static bool smRenderReflectionProbes; }; diff --git a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs index a834b2ea4..4a40b8075 100644 --- a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs +++ b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs @@ -476,9 +476,9 @@ singleton ShaderData( PFX_ReflectionProbeArray ) singleton GFXStateBlockData( PFX_ReflectionProbeArrayStateBlock ) { - zDefined = true; - zEnable = false; - zWriteEnable = false; + //zDefined = true; + //zEnable = false; + //zWriteEnable = false; samplersDefined = true; samplerStates[0] = SamplerClampLinear; @@ -490,9 +490,9 @@ singleton PostEffect( reflectionProbeArrayPostFX ) // passes by default so we don't do the extra drawing. //allowReflectPass = false; - renderTime = "PFXAfterDiffuse"; + renderTime = "PFXAfterBin"; renderBin = "ProbeBin"; - renderPriority = 1; + renderPriority = 9999; isEnabled = true; shader = PFX_ReflectionProbeArray; diff --git a/Templates/Full/game/levels/AProbeTest.mis b/Templates/Full/game/levels/AProbeTest.mis index e3969a879..5e7a97e48 100644 --- a/Templates/Full/game/levels/AProbeTest.mis +++ b/Templates/Full/game/levels/AProbeTest.mis @@ -134,7 +134,7 @@ new SimGroup(MissionGroup) { ReflectionMode = "Baked Cubemap"; reflectionPath = "levels/probeTest/probes/"; Bake = "0"; - position = "0 0.0825528 2.18272"; + position = "0 0.280415 4.80432"; rotation = "1 0 0 0"; scale = "5 5 5"; canSave = "1"; @@ -156,7 +156,7 @@ new SimGroup(MissionGroup) { surface = "0 0 0 1 0 0 0.5"; surface = "0 1 0 0 0 0 -0.5"; - surface = "0.707107 0 0 0.707106 0 0.5 0"; + surface = "0.707107 0 0 0.707107 0 0.5 0"; surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14"; surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08"; surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08"; @@ -171,7 +171,7 @@ new SimGroup(MissionGroup) { surface = "0 0 0 1 0 0 0.5"; surface = "0 1 0 0 0 0 -0.5"; - surface = "0.707107 0 0 0.707106 0 0.5 0"; + surface = "0.707107 0 0 0.707107 0 0.5 0"; surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14"; surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08"; surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08"; @@ -186,7 +186,7 @@ new SimGroup(MissionGroup) { surface = "0 0 0 1 0 0 0.5"; surface = "0 1 0 0 0 0 -0.5"; - surface = "0.707107 0 0 0.707107 0 0.5 0"; + surface = "0.707107 0 0 0.707106 0 0.5 0"; surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14"; surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08"; surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08"; @@ -201,7 +201,7 @@ new SimGroup(MissionGroup) { surface = "0 0 0 1 0 0 0.5"; surface = "0 1 0 0 0 0 -0.5"; - surface = "0.707107 0 0 0.707107 0 0.5 0"; + surface = "0.707107 0 0 0.707106 0 0.5 0"; surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14"; surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08"; surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08"; @@ -216,7 +216,7 @@ new SimGroup(MissionGroup) { surface = "0 0 0 1 0 0 0.5"; surface = "0 1 0 0 0 0 -0.5"; - surface = "0.707107 0 0 0.707107 0 0.5 0"; + surface = "0.707107 0 0 0.707106 0 0.5 0"; surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14"; surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08"; surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08"; @@ -231,7 +231,7 @@ new SimGroup(MissionGroup) { surface = "0 0 0 1 0 0 0.5"; surface = "0 1 0 0 0 0 -0.5"; - surface = "0.707107 0 0 0.707106 0 0.5 0"; + surface = "0.707107 0 0 0.707107 0 0.5 0"; surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14"; surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08"; surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08"; @@ -246,7 +246,7 @@ new SimGroup(MissionGroup) { surface = "0 0 0 1 0 0 0.5"; surface = "0 1 0 0 0 0 -0.5"; - surface = "0.707107 0 0 0.707107 0 0.5 0"; + surface = "0.707107 0 0 0.707106 0 0.5 0"; surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14"; surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08"; surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08"; @@ -321,7 +321,7 @@ new SimGroup(MissionGroup) { ReflectionMode = "Baked Cubemap"; reflectionPath = "levels/probeTest/probes/"; Bake = "0"; - position = "-8.24487 0.0825528 2.5031"; + position = "-9.34007 0.48281 2.5031"; rotation = "1 0 0 0"; scale = "5 5 5"; canSave = "1"; @@ -341,7 +341,7 @@ new SimGroup(MissionGroup) { ReflectionMode = "Baked Cubemap"; reflectionPath = "levels/probeTest/probes/"; Bake = "0"; - position = "-8.24487 3.18253 2.18272"; + position = "-10.1924 8.78742 2.18272"; rotation = "1 0 0 0"; scale = "5 5 5"; canSave = "1"; @@ -354,14 +354,14 @@ new SimGroup(MissionGroup) { SkyColor = "0.5 0.5 1 1"; }; new ReflectionProbe() { - enabled = "1"; + enabled = "0"; ProbeShape = "Box"; radius = "5"; posOffset = "0 0 0"; ReflectionMode = "Baked Cubemap"; reflectionPath = "levels/probeTest/probes/"; Bake = "0"; - position = "-8.24487 -3.37372 2.18272"; + position = "8.24487 -3.37372 2.18272"; rotation = "1 0 0 0"; scale = "5 5 5"; canSave = "1"; diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl index e20cd710c..ad6dc7158 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl @@ -155,7 +155,7 @@ float4 main( PFXVertToPix IN ) : SV_TARGET // Normalize blendVal if (blendSum == 0.0f) // Possible with custom weight { - //blendSum = 1.0f; + blendSum = 1.0f; } float invBlendSumWeighted = 1.0f / blendSum; @@ -173,7 +173,7 @@ float4 main( PFXVertToPix IN ) : SV_TARGET kD *= 1.0 - surface.metalness; for (i = 0; i < numProbes; ++i) { - irradiance += blendVal[i]*iblBoxDiffuse(surface,i); + irradiance += float3(blendVal[i],blendVal[i],blendVal[i])/*blendVal[i]*iblBoxDiffuse(surface,i)*/; specular += blendVal[i]*F*iblBoxSpecular(surface, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture),i); } From b52799bbcecf3f2ac96580f076697597e9a508cd Mon Sep 17 00:00:00 2001 From: Areloch Date: Thu, 14 Feb 2019 00:35:22 -0600 Subject: [PATCH 8/8] Finished current cleanup/reorg. Temporarily disabled logic for forward render of probes to avoid data mangle. TODO: fix up forward once deferred math is locked in Split probe modes out into distinct environmental probe objects Removed the probes from tracking their own baked cubemap file paths and instead have a pref store it Removed old probe shaders and materials that aren't used now. Fixed mLastConst memory leak by removing nono line. --- .../T3D/lighting/boxEnvironmentProbe.cpp | 232 +++++++ .../source/T3D/lighting/boxEnvironmentProbe.h | 116 ++++ .../source/T3D/lighting/reflectionProbe.cpp | 208 +------ Engine/source/T3D/lighting/reflectionProbe.h | 20 +- Engine/source/T3D/lighting/skylight.cpp | 2 - .../T3D/lighting/sphereEnvironmentProbe.cpp | 232 +++++++ .../T3D/lighting/sphereEnvironmentProbe.h | 111 ++++ .../source/renderInstance/renderProbeMgr.cpp | 566 ++++++------------ Engine/source/renderInstance/renderProbeMgr.h | 211 ++----- .../client/lighting/advanced/shaders.cs | 161 +---- .../core/scripts/client/missionDownload.cs | 1 + Templates/Full/game/levels/AProbeTest.mis | 129 ++-- .../advanced/reflectionProbeArrayV.hlsl | 52 -- .../lighting/advanced/reflectionProbeP.hlsl | 171 ------ .../common/lighting/advanced/skylightP.hlsl | 62 -- .../worldEditor/scripts/editors/creator.ed.cs | 3 +- .../tools/worldEditor/scripts/lighting.ed.cs | 15 +- .../tools/worldEditor/scripts/probeBake.ed.cs | 14 +- 18 files changed, 1024 insertions(+), 1282 deletions(-) create mode 100644 Engine/source/T3D/lighting/boxEnvironmentProbe.cpp create mode 100644 Engine/source/T3D/lighting/boxEnvironmentProbe.h create mode 100644 Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp create mode 100644 Engine/source/T3D/lighting/sphereEnvironmentProbe.h delete mode 100644 Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayV.hlsl delete mode 100644 Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl delete mode 100644 Templates/Full/game/shaders/common/lighting/advanced/skylightP.hlsl diff --git a/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp b/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp new file mode 100644 index 000000000..23d58d1e7 --- /dev/null +++ b/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp @@ -0,0 +1,232 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "T3D/lighting/boxEnvironmentProbe.h" +#include "math/mathIO.h" +#include "scene/sceneRenderState.h" +#include "console/consoleTypes.h" +#include "core/stream/bitStream.h" +#include "materials/baseMatInstance.h" +#include "console/engineAPI.h" +#include "gfx/gfxDrawUtil.h" +#include "gfx/gfxDebugEvent.h" +#include "gfx/gfxTransformSaver.h" +#include "math/mathUtils.h" +#include "gfx/bitmap/gBitmap.h" +#include "core/stream/fileStream.h" +#include "core/fileObject.h" +#include "core/resourceManager.h" +#include "console/simPersistId.h" +#include "T3D/gameFunctions.h" +#include "postFx/postEffect.h" +#include "renderInstance/renderProbeMgr.h" +#include "renderInstance/renderProbeMgr.h" + +#include "math/util/sphereMesh.h" +#include "materials/materialManager.h" +#include "math/util/matrixSet.h" +#include "gfx/bitmap/cubemapSaver.h" + +#include "materials/materialFeatureTypes.h" + +#include "materials/shaderData.h" +#include "gfx/gfxTextureManager.h" + +#include "gfx/bitmap/imageUtils.h" + +#include "T3D/lighting/IBLUtilities.h" + +extern bool gEditingMission; +extern ColorI gCanvasClearColor; + +IMPLEMENT_CO_NETOBJECT_V1(BoxEnvironmentProbe); + +ConsoleDocClass(BoxEnvironmentProbe, + "@brief An example scene object which renders a mesh.\n\n" + "This class implements a basic SceneObject that can exist in the world at a " + "3D position and render itself. There are several valid ways to render an " + "object in Torque. This class implements the preferred rendering method which " + "is to submit a MeshRenderInst along with a Material, vertex buffer, " + "primitive buffer, and transform and allow the RenderMeshMgr handle the " + "actual setup and rendering for you.\n\n" + "See the C++ code for implementation details.\n\n" + "@ingroup Examples\n"); + +//----------------------------------------------------------------------------- +// Object setup and teardown +//----------------------------------------------------------------------------- +BoxEnvironmentProbe::BoxEnvironmentProbe() : ReflectionProbe() +{ + mCaptureMask = REFLECTION_PROBE_CAPTURE_TYPEMASK; +} + +BoxEnvironmentProbe::~BoxEnvironmentProbe() +{ +} + +//----------------------------------------------------------------------------- +// Object Editing +//----------------------------------------------------------------------------- +void BoxEnvironmentProbe::initPersistFields() +{ + // SceneObject already handles exposing the transform + Parent::initPersistFields(); +} + +void BoxEnvironmentProbe::inspectPostApply() +{ + Parent::inspectPostApply(); + + mDirty = true; + + // Flag the network mask to send the updates + // to the client object + setMaskBits(-1); +} + +bool BoxEnvironmentProbe::onAdd() +{ + if (!Parent::onAdd()) + return false; + + return true; +} + +void BoxEnvironmentProbe::onRemove() +{ + Parent::onRemove(); +} + +void BoxEnvironmentProbe::setTransform(const MatrixF & mat) +{ + // Let SceneObject handle all of the matrix manipulation + Parent::setTransform(mat); + + mDirty = true; + + // Dirty our network mask so that the new transform gets + // transmitted to the client object + setMaskBits(TransformMask); +} + +U32 BoxEnvironmentProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream) +{ + // Allow the Parent to get a crack at writing its info + U32 retMask = Parent::packUpdate(conn, mask, stream); + + return retMask; +} + +void BoxEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream) +{ + // Let the Parent read any info it sent + Parent::unpackUpdate(conn, stream); +} + +//----------------------------------------------------------------------------- +// Object Rendering +//----------------------------------------------------------------------------- + +void BoxEnvironmentProbe::updateProbeParams() +{ + Parent::updateProbeParams(); + + mProbeInfo->mProbeShapeType = ProbeRenderInst::Box; +} + +void BoxEnvironmentProbe::prepRenderImage(SceneRenderState *state) +{ + if (!mEnabled || !ReflectionProbe::smRenderPreviewProbes) + return; + + //special hook-in for BoxEnvironmentProbes + Point3F camPos = state->getCameraPosition(); + mProbeInfo->mBounds.setCenter(camPos); + + mProbeInfo->setPosition(camPos); + + if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr) + { + GFXTransformSaver saver; + + // Calculate the distance of this object from the camera + Point3F cameraOffset; + getRenderTransform().getColumn(3, &cameraOffset); + cameraOffset -= state->getDiffuseCameraPosition(); + F32 dist = cameraOffset.len(); + if (dist < 0.01f) + dist = 0.01f; + + // Set up the LOD for the shape + F32 invScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z)); + + mEditorShapeInst->setDetailFromDistance(state, dist * invScale); + + // Make sure we have a valid level of detail + if (mEditorShapeInst->getCurrentDetail() < 0) + return; + + BaseMatInstance* probePrevMat = mEditorShapeInst->getMaterialList()->getMaterialInst(0); + + setPreviewMatParameters(state, probePrevMat); + + // GFXTransformSaver is a handy helper class that restores + // the current GFX matrices to their original values when + // it goes out of scope at the end of the function + + // Set up our TS render state + TSRenderState rdata; + rdata.setSceneState(state); + rdata.setFadeOverride(1.0f); + + // We might have some forward lit materials + // so pass down a query to gather lights. + LightQuery query; + query.init(getWorldSphere()); + rdata.setLightQuery(&query); + + // Set the world matrix to the objects render transform + MatrixF mat = getRenderTransform(); + mat.scale(Point3F(1, 1, 1)); + GFX->setWorldMatrix(mat); + + // Animate the the shape + mEditorShapeInst->animate(); + + // Allow the shape to submit the RenderInst(s) for itself + mEditorShapeInst->render(rdata); + + saver.restore(); + } + + // If the light is selected or light visualization + // is enabled then register the callback. + const bool isSelectedInEditor = (gEditingMission && isSelected()); + if (isSelectedInEditor) + { + } +} + +void BoxEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat) +{ + Parent::setPreviewMatParameters(renderState, mat); +} \ No newline at end of file diff --git a/Engine/source/T3D/lighting/boxEnvironmentProbe.h b/Engine/source/T3D/lighting/boxEnvironmentProbe.h new file mode 100644 index 000000000..742472f97 --- /dev/null +++ b/Engine/source/T3D/lighting/boxEnvironmentProbe.h @@ -0,0 +1,116 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef BOX_ENVIRONMENT_PROBE_H +#define BOX_ENVIRONMENT_PROBE_H + +#ifndef REFLECTIONPROBE_H +#include "T3D/lighting/reflectionProbe.h" +#endif +#ifndef _GFXVERTEXBUFFER_H_ +#include "gfx/gfxVertexBuffer.h" +#endif +#ifndef _GFXPRIMITIVEBUFFER_H_ +#include "gfx/gfxPrimitiveBuffer.h" +#endif +#ifndef _TSSHAPEINSTANCE_H_ +#include "ts/tsShapeInstance.h" +#endif +#include "lighting/lightInfo.h" + +#ifndef _RENDERPASSMANAGER_H_ +#include "renderInstance/renderPassManager.h" +#endif + +class BaseMatInstance; + + +//----------------------------------------------------------------------------- +// This class implements a basic SceneObject that can exist in the world at a +// 3D position and render itself. There are several valid ways to render an +// object in Torque. This class implements the preferred rendering method which +// is to submit a MeshRenderInst along with a Material, vertex buffer, +// primitive buffer, and transform and allow the RenderMeshMgr handle the +// actual setup and rendering for you. +//----------------------------------------------------------------------------- + +class BoxEnvironmentProbe : public ReflectionProbe +{ + typedef ReflectionProbe Parent; + +private: + + //Debug rendering + static bool smRenderPreviewProbes; + +public: + BoxEnvironmentProbe(); + virtual ~BoxEnvironmentProbe(); + + // Declare this object as a ConsoleObject so that we can + // instantiate it into the world and network it + DECLARE_CONOBJECT(BoxEnvironmentProbe); + + //-------------------------------------------------------------------------- + // Object Editing + // Since there is always a server and a client object in Torque and we + // actually edit the server object we need to implement some basic + // networking functions + //-------------------------------------------------------------------------- + // Set up any fields that we want to be editable (like position) + static void initPersistFields(); + + // Allows the object to update its editable settings + // from the server object to the client + virtual void inspectPostApply(); + + // Handle when we are added to the scene and removed from the scene + bool onAdd(); + void onRemove(); + + // Override this so that we can dirty the network flag when it is called + void setTransform(const MatrixF &mat); + + // This function handles sending the relevant data from the server + // object to the client object + U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream); + // This function handles receiving relevant data from the server + // object and applying it to the client object + void unpackUpdate(NetConnection *conn, BitStream *stream); + + //-------------------------------------------------------------------------- + // Object Rendering + // Torque utilizes a "batch" rendering system. This means that it builds a + // list of objects that need to render (via RenderInst's) and then renders + // them all in one batch. This allows it to optimized on things like + // minimizing texture, state, and shader switching by grouping objects that + // use the same Materials. + //-------------------------------------------------------------------------- + virtual void updateProbeParams(); + + // This is the function that allows this object to submit itself for rendering + void prepRenderImage(SceneRenderState *state); + + void setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat); +}; + +#endif // BOX_ENVIRONMENT_PROBE_H \ No newline at end of file diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index 349649e9a..10bc07abc 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -53,8 +53,6 @@ #include "scene/reflector.h" -#include "T3D/gameTSCtrl.h" - extern bool gEditingMission; extern ColorI gCanvasClearColor; bool ReflectionProbe::smRenderPreviewProbes = true; @@ -79,14 +77,6 @@ ImplementEnumType(ReflectProbeType, { ProbeRenderInst::Box, "Box", "Box shape" } EndImplementEnumType; -ImplementEnumType(IndrectLightingModeEnum, - "Type of mesh data available in a shape.\n" - "@ingroup gameObjects") -{ ReflectionProbe::NoIndirect, "No Lighting", "This probe does not provide any local indirect lighting data" }, -{ ReflectionProbe::AmbientColor, "Ambient Color", "Adds a flat color to act as the local indirect lighting" }, -{ ReflectionProbe::SphericalHarmonics, "Spherical Harmonics", "Creates spherical harmonics data based off the reflection data" }, - EndImplementEnumType; - ImplementEnumType(ReflectionModeEnum, "Type of mesh data available in a shape.\n" "@ingroup gameObjects") @@ -109,8 +99,6 @@ ReflectionProbe::ReflectionProbe() mProbeShapeType = ProbeRenderInst::Box; - mIndrectLightingModeType = NoIndirect; - mReflectionModeType = BakedCubemap; mEnabled = true; @@ -123,7 +111,6 @@ ReflectionProbe::ReflectionProbe() mUseHDRCaptures = true; mStaticCubemap = NULL; - mReflectionPath = ""; mProbeUniqueID = ""; mEditorShapeInst = NULL; @@ -172,9 +159,7 @@ void ReflectionProbe::initPersistFields() addProtectedField("enabled", TypeBool, Offset(mEnabled, ReflectionProbe), &_setEnabled, &defaultProtectedGetFn, "Regenerate Voxel Grid"); - addField("ProbeShape", TypeReflectProbeType, Offset(mProbeShapeType, ReflectionProbe), - "The type of mesh data to use for collision queries."); - addField("radius", TypeF32, Offset(mRadius, ReflectionProbe), "The name of the material used to render the mesh."); + addField("radius", TypeF32, Offset(mRadius, ReflectionProbe), "The name of the material used to render the mesh."); addField("posOffset", TypePoint3F, Offset(mProbePosOffset, ReflectionProbe), ""); //addProtectedField("EditPosOffset", TypeBool, Offset(mEditPosOffset, ReflectionProbe), @@ -185,9 +170,6 @@ void ReflectionProbe::initPersistFields() addField("ReflectionMode", TypeReflectionModeEnum, Offset(mReflectionModeType, ReflectionProbe), "The type of mesh data to use for collision queries."); - addField("reflectionPath", TypeImageFilename, Offset(mReflectionPath, ReflectionProbe), - "The type of mesh data to use for collision queries."); - addField("StaticCubemap", TypeCubemapName, Offset(mCubemapName, ReflectionProbe), "Cubemap used instead of reflection texture if fullReflect is off."); addProtectedField("Bake", TypeBool, Offset(mBake, ReflectionProbe), @@ -240,7 +222,7 @@ bool ReflectionProbe::_doBake(void *object, const char *index, const char *data) if (clientProbe) { - clientProbe->bake(clientProbe->mReflectionPath, 64); + clientProbe->bake(); } return false; @@ -365,7 +347,6 @@ U32 ReflectionProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream if (stream->writeFlag(mask & BakeInfoMask)) { - stream->write(mReflectionPath); stream->write(mProbeUniqueID); } @@ -376,7 +357,6 @@ U32 ReflectionProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream if (stream->writeFlag(mask & ModeMask)) { - stream->write((U32)mIndrectLightingModeType); stream->write((U32)mReflectionModeType); } @@ -420,7 +400,6 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) if (stream->readFlag()) // BakeInfoMask { - stream->read(&mReflectionPath); stream->read(&mProbeUniqueID); } @@ -433,10 +412,6 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) if (stream->readFlag()) // ModeMask { - U32 indirectModeType = AmbientColor; - stream->read(&indirectModeType); - mIndrectLightingModeType = (IndrectLightingModeType)indirectModeType; - U32 reflectModeType = BakedCubemap; stream->read(&reflectModeType); mReflectionModeType = (ReflectionModeType)reflectModeType; @@ -466,7 +441,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) updateMaterial(); } - PROBEMGR->updateProbes(); + //PROBEMGR->updateProbes(); } void ReflectionProbe::createGeometry() @@ -490,7 +465,6 @@ void ReflectionProbe::createGeometry() //----------------------------------------------------------------------------- // Object Rendering //----------------------------------------------------------------------------- - void ReflectionProbe::updateProbeParams() { if (mProbeInfo == nullptr) @@ -502,19 +476,11 @@ void ReflectionProbe::updateProbeParams() updateMaterial(); - mProbeInfo->mAmbient = LinearColorF(0, 0, 0, 0); - mProbeInfo->mProbeShapeType = mProbeShapeType; mProbeInfo->mTransform = getWorldTransform(); - mProbeInfo->mTransform.inverse(); - mProbeInfo->setPosition(getPosition()); - //Point3F pos = mProbeInfo->mTransform.getPosition(); - - //Update the bounds - //mObjBox.minExtents.set(-1, -1, -1); - //mObjBox.maxExtents.set(1, 1, 1); + mProbeInfo->mPosition = getPosition(); mObjScale.set(mRadius, mRadius, mRadius); @@ -626,11 +592,6 @@ void ReflectionProbe::updateMaterial() } } - if (mBrdfTexture.isValid()) - { - mProbeInfo->mBRDFTexture = &mBrdfTexture; - } - //Make us ready to render if (mEnabled) mProbeInfo->mIsEnabled = true; @@ -678,15 +639,6 @@ bool ReflectionProbe::createClientResources() if (mPrefilterMap->mCubemap.isNull()) Con::errorf("ReflectionProbe::createClientResources() - Unable to load baked prefilter map at %s", getPrefilterMapPath().c_str()); - //brdf lookup texture - String brdfPath = Con::getVariable("$Core::BRDFTexture", "core/art/pbr/brdfTexture.dds"); - mBrdfTexture = TEXMGR->createTexture(brdfPath, &GFXTexturePersistentProfile); - - if (!mBrdfTexture) - { - return false; - } - mResourcesCreated = true; return true; @@ -713,7 +665,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state) if (mReflectionModeType == DynamicCubemap && mRefreshRateMS < (Platform::getRealMilliseconds() - mDynamicLastBakeMS)) { - bake("", 32); + bake(); mDynamicLastBakeMS = Platform::getRealMilliseconds(); } @@ -880,175 +832,53 @@ DefineEngineMethod(ReflectionProbe, postApply, void, (), , String ReflectionProbe::getPrefilterMapPath() { - if (mReflectionPath.isEmpty() || mProbeUniqueID.isEmpty()) + if (mProbeUniqueID.isEmpty()) { Con::errorf("ReflectionProbe::getPrefilterMapPath() - We don't have a set output path or persistant id, so no valid path can be provided!"); return ""; } + String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/"); + char fileName[256]; - dSprintf(fileName, 256, "%s%s_Prefilter.dds", mReflectionPath.c_str(), mProbeUniqueID.c_str()); + dSprintf(fileName, 256, "%s%s_Prefilter.dds", path.c_str(), mProbeUniqueID.c_str()); return fileName; } String ReflectionProbe::getIrradianceMapPath() { - if (mReflectionPath.isEmpty() || mProbeUniqueID.isEmpty()) + if (mProbeUniqueID.isEmpty()) { Con::errorf("ReflectionProbe::getIrradianceMapPath() - We don't have a set output path or persistant id, so no valid path can be provided!"); return ""; } + String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/"); + char fileName[256]; - dSprintf(fileName, 256, "%s%s_Irradiance.dds", mReflectionPath.c_str(), mProbeUniqueID.c_str()); + dSprintf(fileName, 256, "%s%s_Irradiance.dds", path.c_str(), mProbeUniqueID.c_str()); return fileName; } -void ReflectionProbe::bake(String outputPath, S32 resolution, bool renderWithProbes) +void ReflectionProbe::bake() { - GFXDEBUGEVENT_SCOPE(ReflectionProbe_Bake, ColorI::WHITE); + if (mReflectionModeType == DynamicCubemap) + return; - Con::warnf("ReflectionProbe::bake() - Beginning bake!"); - - U32 startMSTime = Platform::getRealMilliseconds(); - - GFXCubemapHandle sceneCaptureCubemap; - - if (mReflectionModeType == DynamicCubemap && mDynamicCubemap.isNull()) - { - //this is wholely reundant when we actually use the proper dynamic cube reflector - mDynamicCubemap = GFX->createCubemap(); - - if(mUseHDRCaptures) - mDynamicCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F); - else - mDynamicCubemap->initDynamic(resolution, GFXFormatB8G8R8A8); - - sceneCaptureCubemap = mDynamicCubemap; - } - else if (mReflectionModeType != DynamicCubemap) - { - //Prep our bake path - if (mReflectionPath.isEmpty()) - { - Con::errorf("ReflectionProbe::bake() - Unable to bake our captures because probe doesn't have a path set"); - return; - } - - if (mProbeUniqueID.isEmpty()) - { - Con::errorf("ReflectionProbe::bake() - Unable to bake our captures because probe doesn't have a unique ID set"); - return; - } - } - - bool validCubemap = true; - - // Save the current transforms so we can restore - // it for child control rendering below. - GFXTransformSaver saver; - - bool probeRenderState = RenderProbeMgr::smRenderReflectionProbes; - - if (!renderWithProbes) - RenderProbeMgr::smRenderReflectionProbes = false; - - F32 farPlane = 1000.0f; - - ReflectorDesc reflDesc; - reflDesc.texSize = resolution; - reflDesc.farDist = farPlane; - reflDesc.detailAdjust = 1; - reflDesc.objectTypeMask = -1; - - CubeReflector cubeRefl; - cubeRefl.registerReflector(this, &reflDesc); - - ReflectParams reflParams; - - //need to get the query somehow. Likely do some sort of get function to fetch from the guiTSControl that's active - CameraQuery query; //need to get the last cameraQuery - query.fov = 90; //90 degree slices for each of the 6 sides - query.nearPlane = 0.1f; - query.farPlane = farPlane; - query.headMatrix = MatrixF(); - query.cameraMatrix = getTransform(); - - Frustum culler; - culler.set(false, - query.fov, - (F32)resolution / (F32)resolution, - query.nearPlane, - query.farPlane, - query.cameraMatrix); - - S32 stereoTarget = GFX->getCurrentStereoTarget(); - - Point2I maxRes(2048, 2048); //basically a boundary so we don't go over this and break stuff - - reflParams.culler = culler; - reflParams.eyeId = stereoTarget; - reflParams.query = &query; - reflParams.startOfUpdateMs = startMSTime; - reflParams.viewportExtent = maxRes; - - cubeRefl.updateReflection(reflParams); - - //Now, save out the maps - //create irridiance cubemap - if (cubeRefl.getCubemap()) - { - //Just to ensure we're prepped for the generation - createClientResources(); - - //Prep it with whatever resolution we've dictated for our bake - if (mUseHDRCaptures) - { - mIrridianceMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F); - mPrefilterMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F); - } - else - { - mIrridianceMap->mCubemap->initDynamic(resolution, GFXFormatR8G8B8A8); - mPrefilterMap->mCubemap->initDynamic(resolution, GFXFormatR8G8B8A8); - } - - GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false); - - IBLUtilities::GenerateIrradianceMap(renderTarget, cubeRefl.getCubemap(), mIrridianceMap->mCubemap); - IBLUtilities::GeneratePrefilterMap(renderTarget, cubeRefl.getCubemap(), mPrefilterMipLevels, mPrefilterMap->mCubemap); - - IBLUtilities::SaveCubeMap(getIrradianceMapPath(), mIrridianceMap->mCubemap); - IBLUtilities::SaveCubeMap(getPrefilterMapPath(), mPrefilterMap->mCubemap); - } - else - { - Con::errorf("ReflectionProbe::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!"); - } - - if(!renderWithProbes) - RenderProbeMgr::smRenderReflectionProbes = probeRenderState; + PROBEMGR->bakeProbe(this); setMaskBits(CubemapMask); - - cubeRefl.unregisterReflector(); - - U32 endMSTime = Platform::getRealMilliseconds(); - F32 diffTime = F32(endMSTime - startMSTime); - - Con::warnf("ReflectionProbe::bake() - Finished bake! Took %g milliseconds", diffTime); } -DefineEngineMethod(ReflectionProbe, Bake, void, (String outputPath, S32 resolution, bool renderWithProbes), ("", 64, false), +DefineEngineMethod(ReflectionProbe, Bake, void, (), , "@brief returns true if control object is inside the fog\n\n.") { ReflectionProbe *clientProbe = (ReflectionProbe*)object->getClientObject(); if (clientProbe) { - clientProbe->bake(outputPath, resolution, renderWithProbes); + clientProbe->bake(); } - //object->bake(outputPath, resolution); } \ No newline at end of file diff --git a/Engine/source/T3D/lighting/reflectionProbe.h b/Engine/source/T3D/lighting/reflectionProbe.h index df7a2e994..8155c5696 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.h +++ b/Engine/source/T3D/lighting/reflectionProbe.h @@ -59,16 +59,10 @@ class BaseMatInstance; class ReflectionProbe : public SceneObject { typedef SceneObject Parent; + friend class RenderProbeMgr; public: - enum IndrectLightingModeType - { - NoIndirect = 0, - AmbientColor = 1, - SphericalHarmonics = 2 - }; - enum ReflectionModeType { NoReflection = 0, @@ -113,9 +107,6 @@ protected: ProbeRenderInst* mProbeInfo; U32 mProbeInfoIdx; - //Indirect Lighting Contribution stuff - IndrectLightingModeType mIndrectLightingModeType; - //Reflection Contribution stuff ReflectionModeType mReflectionModeType; @@ -143,10 +134,6 @@ protected: U32 mPrefilterMipLevels; U32 mPrefilterSize; - //brdflookup resources - shares the texture target with the prefilter - GFXTexHandle mBrdfTexture; - - String mReflectionPath; String mProbeUniqueID; // Define our vertex format here so we don't have to @@ -249,7 +236,7 @@ public: //Baking String getPrefilterMapPath(); String getIrradianceMapPath(); - void bake(String outputPath, S32 resolution, bool renderWithProbes = false); + void bake(); const U32 getProbeInfoIndex() { return mProbeInfoIdx; } }; @@ -257,9 +244,6 @@ public: typedef ProbeRenderInst::ProbeShapeType ReflectProbeType; DefineEnumType(ReflectProbeType); -typedef ReflectionProbe::IndrectLightingModeType IndrectLightingModeEnum; -DefineEnumType(IndrectLightingModeEnum); - typedef ReflectionProbe::ReflectionModeType ReflectionModeEnum; DefineEnumType(ReflectionModeEnum); diff --git a/Engine/source/T3D/lighting/skylight.cpp b/Engine/source/T3D/lighting/skylight.cpp index 010634a31..20564222e 100644 --- a/Engine/source/T3D/lighting/skylight.cpp +++ b/Engine/source/T3D/lighting/skylight.cpp @@ -171,8 +171,6 @@ void Skylight::updateProbeParams() setGlobalBounds(); - mProbeInfo->mAmbient = LinearColorF(1, 1, 1, 1); - mProbeInfo->mIsSkylight = true; mProbeInfo->mScore = -1.0f; //sky comes first } diff --git a/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp b/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp new file mode 100644 index 000000000..a0edafb50 --- /dev/null +++ b/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp @@ -0,0 +1,232 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "T3D/lighting/sphereEnvironmentProbe.h" +#include "math/mathIO.h" +#include "scene/sceneRenderState.h" +#include "console/consoleTypes.h" +#include "core/stream/bitStream.h" +#include "materials/baseMatInstance.h" +#include "console/engineAPI.h" +#include "gfx/gfxDrawUtil.h" +#include "gfx/gfxDebugEvent.h" +#include "gfx/gfxTransformSaver.h" +#include "math/mathUtils.h" +#include "gfx/bitmap/gBitmap.h" +#include "core/stream/fileStream.h" +#include "core/fileObject.h" +#include "core/resourceManager.h" +#include "console/simPersistId.h" +#include "T3D/gameFunctions.h" +#include "postFx/postEffect.h" +#include "renderInstance/renderProbeMgr.h" +#include "renderInstance/renderProbeMgr.h" + +#include "math/util/sphereMesh.h" +#include "materials/materialManager.h" +#include "math/util/matrixSet.h" +#include "gfx/bitmap/cubemapSaver.h" + +#include "materials/materialFeatureTypes.h" + +#include "materials/shaderData.h" +#include "gfx/gfxTextureManager.h" + +#include "gfx/bitmap/imageUtils.h" + +#include "T3D/lighting/IBLUtilities.h" + +extern bool gEditingMission; +extern ColorI gCanvasClearColor; + +IMPLEMENT_CO_NETOBJECT_V1(SphereEnvironmentProbe); + +ConsoleDocClass(SphereEnvironmentProbe, + "@brief An example scene object which renders a mesh.\n\n" + "This class implements a basic SceneObject that can exist in the world at a " + "3D position and render itself. There are several valid ways to render an " + "object in Torque. This class implements the preferred rendering method which " + "is to submit a MeshRenderInst along with a Material, vertex buffer, " + "primitive buffer, and transform and allow the RenderMeshMgr handle the " + "actual setup and rendering for you.\n\n" + "See the C++ code for implementation details.\n\n" + "@ingroup Examples\n"); + +//----------------------------------------------------------------------------- +// Object setup and teardown +//----------------------------------------------------------------------------- +SphereEnvironmentProbe::SphereEnvironmentProbe() : ReflectionProbe() +{ + mCaptureMask = REFLECTION_PROBE_CAPTURE_TYPEMASK; +} + +SphereEnvironmentProbe::~SphereEnvironmentProbe() +{ +} + +//----------------------------------------------------------------------------- +// Object Editing +//----------------------------------------------------------------------------- +void SphereEnvironmentProbe::initPersistFields() +{ + // SceneObject already handles exposing the transform + Parent::initPersistFields(); +} + +void SphereEnvironmentProbe::inspectPostApply() +{ + Parent::inspectPostApply(); + + mDirty = true; + + // Flag the network mask to send the updates + // to the client object + setMaskBits(-1); +} + +bool SphereEnvironmentProbe::onAdd() +{ + if (!Parent::onAdd()) + return false; + + return true; +} + +void SphereEnvironmentProbe::onRemove() +{ + Parent::onRemove(); +} + +void SphereEnvironmentProbe::setTransform(const MatrixF & mat) +{ + // Let SceneObject handle all of the matrix manipulation + Parent::setTransform(mat); + + mDirty = true; + + // Dirty our network mask so that the new transform gets + // transmitted to the client object + setMaskBits(TransformMask); +} + +U32 SphereEnvironmentProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream) +{ + // Allow the Parent to get a crack at writing its info + U32 retMask = Parent::packUpdate(conn, mask, stream); + + return retMask; +} + +void SphereEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream) +{ + // Let the Parent read any info it sent + Parent::unpackUpdate(conn, stream); +} + +//----------------------------------------------------------------------------- +// Object Rendering +//----------------------------------------------------------------------------- + +void SphereEnvironmentProbe::updateProbeParams() +{ + Parent::updateProbeParams(); + + mProbeInfo->mProbeShapeType = ProbeRenderInst::Sphere; +} + +void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state) +{ + if (!mEnabled || !ReflectionProbe::smRenderPreviewProbes) + return; + + //special hook-in for SphereEnvironmentProbes + Point3F camPos = state->getCameraPosition(); + mProbeInfo->mBounds.setCenter(camPos); + + mProbeInfo->setPosition(camPos); + + if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr) + { + GFXTransformSaver saver; + + // Calculate the distance of this object from the camera + Point3F cameraOffset; + getRenderTransform().getColumn(3, &cameraOffset); + cameraOffset -= state->getDiffuseCameraPosition(); + F32 dist = cameraOffset.len(); + if (dist < 0.01f) + dist = 0.01f; + + // Set up the LOD for the shape + F32 invScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z)); + + mEditorShapeInst->setDetailFromDistance(state, dist * invScale); + + // Make sure we have a valid level of detail + if (mEditorShapeInst->getCurrentDetail() < 0) + return; + + BaseMatInstance* probePrevMat = mEditorShapeInst->getMaterialList()->getMaterialInst(0); + + setPreviewMatParameters(state, probePrevMat); + + // GFXTransformSaver is a handy helper class that restores + // the current GFX matrices to their original values when + // it goes out of scope at the end of the function + + // Set up our TS render state + TSRenderState rdata; + rdata.setSceneState(state); + rdata.setFadeOverride(1.0f); + + // We might have some forward lit materials + // so pass down a query to gather lights. + LightQuery query; + query.init(getWorldSphere()); + rdata.setLightQuery(&query); + + // Set the world matrix to the objects render transform + MatrixF mat = getRenderTransform(); + mat.scale(Point3F(1, 1, 1)); + GFX->setWorldMatrix(mat); + + // Animate the the shape + mEditorShapeInst->animate(); + + // Allow the shape to submit the RenderInst(s) for itself + mEditorShapeInst->render(rdata); + + saver.restore(); + } + + // If the light is selected or light visualization + // is enabled then register the callback. + const bool isSelectedInEditor = (gEditingMission && isSelected()); + if (isSelectedInEditor) + { + } +} + +void SphereEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat) +{ + Parent::setPreviewMatParameters(renderState, mat); +} \ No newline at end of file diff --git a/Engine/source/T3D/lighting/sphereEnvironmentProbe.h b/Engine/source/T3D/lighting/sphereEnvironmentProbe.h new file mode 100644 index 000000000..59c602cc3 --- /dev/null +++ b/Engine/source/T3D/lighting/sphereEnvironmentProbe.h @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef SPHERE_ENVIRONMENT_PROBE_H +#define SPHERE_ENVIRONMENT_PROBE_H + +#ifndef REFLECTIONPROBE_H +#include "T3D/lighting/reflectionProbe.h" +#endif +#ifndef _GFXVERTEXBUFFER_H_ +#include "gfx/gfxVertexBuffer.h" +#endif +#ifndef _GFXPRIMITIVEBUFFER_H_ +#include "gfx/gfxPrimitiveBuffer.h" +#endif +#ifndef _TSSHAPEINSTANCE_H_ +#include "ts/tsShapeInstance.h" +#endif +#include "lighting/lightInfo.h" + +#ifndef _RENDERPASSMANAGER_H_ +#include "renderInstance/renderPassManager.h" +#endif + +class BaseMatInstance; + + +//----------------------------------------------------------------------------- +// This class implements a basic SceneObject that can exist in the world at a +// 3D position and render itself. There are several valid ways to render an +// object in Torque. This class implements the preferred rendering method which +// is to submit a MeshRenderInst along with a Material, vertex buffer, +// primitive buffer, and transform and allow the RenderMeshMgr handle the +// actual setup and rendering for you. +//----------------------------------------------------------------------------- + +class SphereEnvironmentProbe : public ReflectionProbe +{ + typedef ReflectionProbe Parent; + +public: + SphereEnvironmentProbe(); + virtual ~SphereEnvironmentProbe(); + + // Declare this object as a ConsoleObject so that we can + // instantiate it into the world and network it + DECLARE_CONOBJECT(SphereEnvironmentProbe); + + //-------------------------------------------------------------------------- + // Object Editing + // Since there is always a server and a client object in Torque and we + // actually edit the server object we need to implement some basic + // networking functions + //-------------------------------------------------------------------------- + // Set up any fields that we want to be editable (like position) + static void initPersistFields(); + + // Allows the object to update its editable settings + // from the server object to the client + virtual void inspectPostApply(); + + // Handle when we are added to the scene and removed from the scene + bool onAdd(); + void onRemove(); + + // Override this so that we can dirty the network flag when it is called + void setTransform(const MatrixF &mat); + + // This function handles sending the relevant data from the server + // object to the client object + U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream); + // This function handles receiving relevant data from the server + // object and applying it to the client object + void unpackUpdate(NetConnection *conn, BitStream *stream); + + //-------------------------------------------------------------------------- + // Object Rendering + // Torque utilizes a "batch" rendering system. This means that it builds a + // list of objects that need to render (via RenderInst's) and then renders + // them all in one batch. This allows it to optimized on things like + // minimizing texture, state, and shader switching by grouping objects that + // use the same Materials. + //-------------------------------------------------------------------------- + virtual void updateProbeParams(); + + // This is the function that allows this object to submit itself for rendering + void prepRenderImage(SceneRenderState *state); + + void setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat); +}; + +#endif // SPHERE_ENVIRONMENT_PROBE_H \ No newline at end of file diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 289c9a4f4..f5d3504d3 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -38,6 +38,11 @@ #include "gfx/gfxTextureManager.h" #include "postFx/postEffect.h" +#include "T3D/lighting/reflectionProbe.h" +#include "T3D/lighting/IBLUtilities.h" + +//For our cameraQuery setup +#include "T3D/gameTSCtrl.h" IMPLEMENT_CONOBJECT(RenderProbeMgr); @@ -69,22 +74,13 @@ S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b) ProbeRenderInst::ProbeRenderInst() : SystemInterface(), mTransform(true), mDirty(false), - mAmbient(0.0f, 0.0f, 0.0f, 1.0f), mPriority(1.0f), mScore(0.0f), - mDebugRender(false), mCubemap(NULL), mIrradianceCubemap(NULL), - mBRDFTexture(NULL), mRadius(1.0f), - mIntensity(1.0f), - mProbePosOffset(0, 0, 0), - numPrims(0) + mProbePosOffset(0, 0, 0) { - for (U32 i = 0; i < 5; ++i) - { - mSHConstants[i] = 0; - } } ProbeRenderInst::~ProbeRenderInst() @@ -97,46 +93,22 @@ ProbeRenderInst::~ProbeRenderInst() { mIrradianceCubemap.free(); } - if (mBRDFTexture && mBRDFTexture->isValid()) - { - mBRDFTexture->free(); - } } void ProbeRenderInst::set(const ProbeRenderInst *probeInfo) { mTransform = probeInfo->mTransform; - mAmbient = probeInfo->mAmbient; mCubemap = probeInfo->mCubemap; mIrradianceCubemap = probeInfo->mIrradianceCubemap; - mBRDFTexture = probeInfo->mBRDFTexture; mRadius = probeInfo->mRadius; - mIntensity = probeInfo->mIntensity; mProbeShapeType = probeInfo->mProbeShapeType; - numPrims = probeInfo->numPrims; - numVerts = probeInfo->numVerts; - numIndicesForPoly = probeInfo->numIndicesForPoly; mBounds = probeInfo->mBounds; mIsSkylight = probeInfo->mIsSkylight; mScore = probeInfo->mScore; - - for (U32 i = 0; i < 9; i++) - { - mSHTerms[i] = probeInfo->mSHTerms[i]; - } - - for (U32 i = 0; i < 5; i++) - { - mSHConstants[i] = probeInfo->mSHConstants[i]; - } -} - -void ProbeRenderInst::getWorldToLightProj(MatrixF *outMatrix) const -{ - *outMatrix = getTransform(); - outMatrix->inverse(); } +// +// ProbeShaderConstants::ProbeShaderConstants() : mInit(false), mShader(NULL), @@ -193,69 +165,18 @@ void ProbeShaderConstants::_onShaderReload() init(mShader); } -// -// -bool ReflectProbeMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat) -{ - mShaderMat = nullptr; - - bool success = Parent::init(features, vertexFormat); - - // If the initialization failed don't continue. - if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0) - return false; - - mShaderMat = static_cast(getShaderMaterial()); - mShaderMat->init(features, vertexFormat, mFeaturesDelegate); - - //mShaderMat->setMaterialParameters(mDefaultParameters, 0); - - return true; -} - -bool ReflectProbeMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData) -{ - if (!Parent::setupPass(state, sgData)) - return false; - - AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes"); - const RenderPassData *rpd = mProcessedMaterial->getPass(0); - AssertFatal(rpd, "No render pass data!"); - AssertFatal(rpd->mRenderStates[0], "No render state 0!"); - - if (!mProjectionState) - { - GFXStateBlockDesc desc; - desc.setZReadWrite(false); - desc.zWriteEnable = false; - desc.setCullMode(GFXCullNone); - desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvDestAlpha, GFXBlendOpAdd); - mProjectionState = GFX->createStateBlock(desc); - } - // Now override stateblock with our own - GFX->setStateBlock(mProjectionState); - - return true; -} - // // RenderProbeMgr::RenderProbeMgr() : RenderBinManager(RenderPassManager::RIT_Probes, 1.0f, 1.0f), - mReflectProbeMaterial(nullptr), mLastShader(nullptr), mLastConstants(nullptr) { - String brdfPath = Con::getVariable("$Core::BRDFTexture", "core/art/pbr/brdfTexture.dds"); - mBrdfTexture = TEXMGR->createTexture(brdfPath, &GFXTexturePersistentProfile); - mEffectiveProbeCount = 0; mMipCount = 0; mProbeArrayEffect = nullptr; - numProbesSC = nullptr; - smProbeManager = this; } @@ -264,6 +185,12 @@ RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 proce { } +void RenderProbeMgr::onRemove() +{ + SAFE_DELETE(mLastConstants); + + Parent::onRemove(); +} void RenderProbeMgr::initPersistFields() { Parent::initPersistFields(); @@ -350,13 +277,24 @@ void RenderProbeMgr::_setupStaticParameters() mEffectiveProbeCount = 0; mMipCount = 0; - probePositions.setSize(MAXPROBECOUNT); - probeWorldToObj.setSize(MAXPROBECOUNT); - probeBBMin.setSize(MAXPROBECOUNT); - probeBBMax.setSize(MAXPROBECOUNT); - probeUseSphereMode.setSize(MAXPROBECOUNT); - probeRadius.setSize(MAXPROBECOUNT); - probeAttenuation.setSize(MAXPROBECOUNT); + if (probePositionsData.size() != MAXPROBECOUNT) + { + probePositionsData.setSize(MAXPROBECOUNT); + probeWorldToObjData.setSize(MAXPROBECOUNT); + probeBBMinData.setSize(MAXPROBECOUNT); + probeBBMaxData.setSize(MAXPROBECOUNT); + probeUseSphereModeData.setSize(MAXPROBECOUNT); + probeRadiusData.setSize(MAXPROBECOUNT); + probeAttenuationData.setSize(MAXPROBECOUNT); + } + + probePositionsData.fill(Point4F::Zero); + probeWorldToObjData.fill(MatrixF::Identity); + probeBBMinData.fill(Point4F::Zero); + probeBBMaxData.fill(Point4F::Zero); + probeUseSphereModeData.fill(Point4F::Zero); + probeRadiusData.fill(Point4F::Zero); + probeAttenuationData.fill(Point4F::Zero); cubeMaps.clear(); irradMaps.clear(); @@ -366,43 +304,40 @@ void RenderProbeMgr::_setupStaticParameters() if (mEffectiveProbeCount >= MAXPROBECOUNT) break; - ProbeRenderInst* curEntry = ProbeRenderInst::all[i]; - if (!curEntry->mIsEnabled) + const ProbeRenderInst& curEntry = *ProbeRenderInst::all[i]; + if (!curEntry.mIsEnabled) continue; - if (curEntry->mCubemap.isNull() || curEntry->mIrradianceCubemap.isNull()) + if (curEntry.mCubemap.isNull() || curEntry.mIrradianceCubemap.isNull()) continue; - if (!curEntry->mCubemap->isInitialised()) + if (!curEntry.mCubemap->isInitialised()) continue; - if (!curEntry->mIrradianceCubemap->isInitialised()) + if (!curEntry.mIrradianceCubemap->isInitialised()) continue; - if (curEntry->mIsSkylight) + if (curEntry.mIsSkylight) continue; - mMipCount = curEntry->mCubemap.getPointer()->getMipMapLevels(); + mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels(); //Setup - const Point3F &probePos = curEntry->getPosition(); - probePositions[mEffectiveProbeCount] = probePos + curEntry->mProbePosOffset; + Point3F probePos = curEntry.getPosition() + curEntry.mProbePosOffset; + probePositionsData[mEffectiveProbeCount] = Point4F(probePos.x, probePos.y, probePos.z,0); - MatrixF trans = curEntry->getTransform(); - trans.inverse(); + probeWorldToObjData[mEffectiveProbeCount] = curEntry.getTransform(); - probeWorldToObj[mEffectiveProbeCount] = trans; + probeBBMinData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.minExtents.x, curEntry.mBounds.minExtents.y, curEntry.mBounds.minExtents.z, 0); + probeBBMaxData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.maxExtents.x, curEntry.mBounds.maxExtents.y, curEntry.mBounds.maxExtents.z, 0); - probeBBMin[mEffectiveProbeCount] = curEntry->mBounds.minExtents; - probeBBMax[mEffectiveProbeCount] = curEntry->mBounds.maxExtents; + probeUseSphereModeData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 0,0,0); - probeUseSphereMode[mEffectiveProbeCount] = Point4F(curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 0,0,0); + probeRadiusData[mEffectiveProbeCount] = Point4F(curEntry.mRadius,0,0,0); + probeAttenuationData[mEffectiveProbeCount] = Point4F(1, 0, 0, 0); - probeRadius[mEffectiveProbeCount] = Point4F(curEntry->mRadius,0,0,0); - probeAttenuation[mEffectiveProbeCount] = Point4F(1, 0, 0, 0); - - cubeMaps.push_back(curEntry->mCubemap); - irradMaps.push_back(curEntry->mIrradianceCubemap); + cubeMaps.push_back(curEntry.mCubemap); + irradMaps.push_back(curEntry.mIrradianceCubemap); mEffectiveProbeCount++; } @@ -420,75 +355,6 @@ void RenderProbeMgr::_setupStaticParameters() void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state) { PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters); - const Frustum &frustum = state->getCameraFrustum(); - - MatrixF invCam(frustum.getTransform()); - invCam.inverse(); - - const Point3F *wsFrustumPoints = frustum.getPoints(); - const Point3F& cameraPos = frustum.getPosition(); - - // Perform a camera offset. We need to manually perform this offset on the sun (or vector) light's - // polygon, which is at the far plane. - Point3F cameraOffsetPos = cameraPos; - - // Now build the quad for drawing full-screen vector light - // passes.... this is a volatile VB and updates every frame. - FarFrustumQuadVert verts[4]; - { - verts[0].point.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraPos); - invCam.mulP(wsFrustumPoints[Frustum::FarTopLeft], &verts[0].normal); - verts[0].texCoord.set(-1.0, 1.0); - verts[0].tangent.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraOffsetPos); - - verts[1].point.set(wsFrustumPoints[Frustum::FarTopRight] - cameraPos); - invCam.mulP(wsFrustumPoints[Frustum::FarTopRight], &verts[1].normal); - verts[1].texCoord.set(1.0, 1.0); - verts[1].tangent.set(wsFrustumPoints[Frustum::FarTopRight] - cameraOffsetPos); - - verts[2].point.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraPos); - invCam.mulP(wsFrustumPoints[Frustum::FarBottomLeft], &verts[2].normal); - verts[2].texCoord.set(-1.0, -1.0); - verts[2].tangent.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraOffsetPos); - - verts[3].point.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraPos); - invCam.mulP(wsFrustumPoints[Frustum::FarBottomRight], &verts[3].normal); - verts[3].texCoord.set(1.0, -1.0); - verts[3].tangent.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraOffsetPos); - } - - mFarFrustumQuadVerts.set(GFX, 4); - dMemcpy(mFarFrustumQuadVerts.lock(), verts, sizeof(verts)); - mFarFrustumQuadVerts.unlock(); - - PlaneF farPlane(wsFrustumPoints[Frustum::FarBottomLeft], wsFrustumPoints[Frustum::FarTopLeft], wsFrustumPoints[Frustum::FarTopRight]); - PlaneF vsFarPlane(verts[0].normal, verts[1].normal, verts[2].normal); - - ReflectProbeMaterialInfo* reflProbeMat = getReflectProbeMaterial(); - - if (reflProbeMat != nullptr && reflProbeMat->matInstance != nullptr) - { - reflProbeMat->setViewParameters(frustum.getNearDist(), - frustum.getFarDist(), - frustum.getPosition(), - farPlane, - vsFarPlane); - } -} - -RenderProbeMgr::ReflectProbeMaterialInfo* RenderProbeMgr::getReflectProbeMaterial() -{ - PROFILE_SCOPE(AdvancedLightBinManager_getReflectProbeMaterial); - - //ReflectProbeMaterialInfo *info = NULL; - - if (!mReflectProbeMaterial) - - // Now create the material info object. - mReflectProbeMaterial = new ReflectProbeMaterialInfo("ReflectionProbeMaterial", - getGFXVertexFormat()); - - return mReflectProbeMaterial; } ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuffer* buffer) @@ -507,27 +373,25 @@ ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuff ProbeConstantMap::Iterator iter = mConstantLookup.find(shader); if (iter != mConstantLookup.end()) { - mLastForwardConstants = iter->value; + mLastConstants = iter->value; } else { ProbeShaderConstants* psc = new ProbeShaderConstants(); mConstantLookup[shader] = psc; - mLastForwardConstants = psc; + mLastConstants = psc; } // Set our new shader mLastShader = shader; } - mLastForwardConstants = new ProbeShaderConstants(); - // Make sure that our current lighting constants are initialized - if (!mLastForwardConstants->mInit) - mLastForwardConstants->init(shader); + if (mLastConstants && !mLastConstants->mInit) + mLastConstants->init(shader); - return mLastForwardConstants; + return mLastConstants; } void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, @@ -548,7 +412,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, probeRadiusSC->isValid() || probeBoxMinSC->isValid() || probeBoxMaxSC->isValid() || - probeCubemapSC->isValid() && (!ProbeRenderInst::all.empty())) + probeCubemapSC->isValid()/* && (!ProbeRenderInst::all.empty())*/) { PROFILE_SCOPE(ProbeManager_Update4ProbeConsts_setProbes); @@ -576,7 +440,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, const MatrixF &worldToCameraXfm = matSet.getWorldToCamera(); // Gather the data for the first 4 probes. - const ProbeRenderInst *probe; + /*const ProbeRenderInst *probe; for (U32 i = 0; i < 4; i++) { if (i >= ProbeRenderInst::all.size()) @@ -625,6 +489,33 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, if (samplerReg != -1) GFX->setCubeTexture(samplerReg + i, probe->mCubemap.getPointer()); } + }*/ + + for (U32 i = 0; i < 4; i++) + { + probePositions[i].x = 0; + probePositions[i].y = 0; + probePositions[i].z = 0; + + probeRadius[i] = 0; + + probeBoxMins[i].x = 0; + probeBoxMins[i].y = 0; + probeBoxMins[i].z = 0; + + probeBoxMaxs[i].x = 0; + probeBoxMaxs[i].y = 0; + probeBoxMaxs[i].z = 0; + + probeIsSphere[i] = 0; + + probeLocalPositions[i].x = 0; + probeLocalPositions[i].y = 0; + probeLocalPositions[i].z = 0; + + S32 samplerReg = probeCubemapSC->getSamplerRegister(); + + GFX->setCubeTexture(samplerReg + i, nullptr); } shaderConsts->setSafe(probePositionSC, probePositions); @@ -633,18 +524,9 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, shaderConsts->setSafe(probeBoxMaxSC, probeBoxMaxs); shaderConsts->setSafe(probeLocalPosSC, probeLocalPositions); shaderConsts->setSafe(probeIsSphereSC, probeIsSphere); - - // - - //shaderConsts->setSafe(lightSpotAngleSC, lightSpotAngle); - //shaderConsts->setSafe(lightSpotFalloffSC, lightSpotFalloff); } else { - /*if (probe->mCubemap && !probe->mCubemap.isNull()) - { - GFX->setCubeTexture(1, probe->mCubemap.getPointer()); - }*/ if (probeCubemapSC->isValid()) { for (U32 i = 0; i < 4; ++i) @@ -672,9 +554,6 @@ void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat, ProbeShaderConstants *psc = getProbeShaderConstants(shaderConsts); - //ProbeInfo *probe; - //probe = mRegisteredProbes[0]; - // NOTE: If you encounter a crash from this point forward // while setting a shader constant its probably because the // mConstantLookup has bad shaders/constants in it. @@ -683,7 +562,6 @@ void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat, // are reloaded and the light manager is not reset. // // We should look to fix this by clearing the table. - MatrixSet matSet = state->getRenderPass()->getMatrixSet(); // Update the forward shading light constants. @@ -708,6 +586,8 @@ void RenderProbeMgr::render( SceneRenderState *state ) if (getProbeArrayEffect() == nullptr) return; + updateProbes(); + // Early out if nothing to draw. if (!ProbeRenderInst::all.size() || !RenderProbeMgr::smRenderReflectionProbes || mEffectiveProbeCount == 0 || !state->isDiffusePass() || cubeMaps.empty() || irradMaps.empty()) @@ -723,223 +603,161 @@ void RenderProbeMgr::render( SceneRenderState *state ) // Initialize and set the per-frame parameters after getting // the vector light material as we use lazy creation. //_setupPerFrameParameters(state); - - //Specular - //PROFILE_START(RenderProbeManager_ReflectProbeRender); - - // If this is a non-diffuse pass or we have no objects to - // render then tell the effect to skip rendering. //Array rendering U32 probeCount = ProbeRenderInst::all.size(); if (mEffectiveProbeCount != 0) { - //These will in theory be set by the postFX - /*NamedTexTarget *deferredTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName); - if (deferredTarget) - GFX->setTexture(0, deferredTarget->getTexture()); - else - GFX->setTexture(0, NULL); - - NamedTexTarget *colorTarget = NamedTexTarget::find(RenderDeferredMgr::ColorBufferName); - if (colorTarget) - GFX->setTexture(1, colorTarget->getTexture()); - else - GFX->setTexture(1, NULL); - - NamedTexTarget *matinfoTarget = NamedTexTarget::find(RenderDeferredMgr::MatInfoBufferName); - if (matinfoTarget) - GFX->setTexture(2, matinfoTarget->getTexture()); - else - GFX->setTexture(2, NULL);*/ - - /*if (mBrdfTexture) - { - GFX->setTexture(3, mBrdfTexture); - } - else - GFX->setTexture(3, NULL);*/ - - //GFX->setCubeArrayTexture(4, mCubemapArray); - //GFX->setCubeArrayTexture(5, mIrradArray); mProbeArrayEffect->setCubemapArrayTexture(4, mCubemapArray); mProbeArrayEffect->setCubemapArrayTexture(5, mIrradArray); mProbeArrayEffect->setShaderConst("$cubeMips", (float)mMipCount); mProbeArrayEffect->setShaderConst("$numProbes", (float)mEffectiveProbeCount); - mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositions); - mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObj); - mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMin); - mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMax); - mProbeArrayEffect->setShaderConst("$useSphereMode", probeUseSphereMode); - mProbeArrayEffect->setShaderConst("$radius", probeRadius); - mProbeArrayEffect->setShaderConst("$attenuation", probeAttenuation); + mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositionsData); + mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData); + mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMinData); + mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMaxData); + mProbeArrayEffect->setShaderConst("$useSphereMode", probeUseSphereModeData); + mProbeArrayEffect->setShaderConst("$radius", probeRadiusData); + mProbeArrayEffect->setShaderConst("$attenuation", probeAttenuationData); } - // Finish up. - //if (isRenderingToTarget) - // _onPostRender(); - // Make sure the effect is gonna render. getProbeArrayEffect()->setSkip(false); //PROFILE_END(); } -// -// -RenderProbeMgr::ReflectProbeMaterialInfo::ReflectProbeMaterialInfo(const String &matName, - const GFXVertexFormat *vertexFormat) - : matInstance(NULL), - zNearFarInvNearFar(NULL), - farPlane(NULL), - vsFarPlane(NULL), - negFarPlaneDotEye(NULL), - probeWSPos(NULL), - attenuation(NULL), - radius(NULL), - cubeMips(NULL) +void RenderProbeMgr::bakeProbe(ReflectionProbe *probe) { - Material *mat = MATMGR->getMaterialDefinitionByName(matName); - if (!mat) - return; + GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE); - matInstance = new ReflectProbeMatInstance(*mat); + Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!"); + U32 startMSTime = Platform::getRealMilliseconds(); - const Vector ¯os = Vector(); + String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/"); + U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64); + U32 prefilterMipLevels = mLog2(F32(resolution)); + bool renderWithProbes = Con::getIntVariable("$pref::ReflectionProbes::RenderWithProbes", false); - for (U32 i = 0; i < macros.size(); i++) - matInstance->addShaderMacro(macros[i].name, macros[i].value); + ReflectionProbe *clientProbe = static_cast(probe->getClientObject()); - matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat); + String probePrefilterPath = clientProbe->getPrefilterMapPath(); + String probeIrradPath = clientProbe->getIrradianceMapPath(); - attenuation = matInstance->getMaterialParameterHandle("$attenuation"); - radius = matInstance->getMaterialParameterHandle("$radius"); - probeLSPos = matInstance->getMaterialParameterHandle("$probeLSPos"); - probeWSPos = matInstance->getMaterialParameterHandle("$probeWSPos"); - farPlane = matInstance->getMaterialParameterHandle("$farPlane"); - vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane"); - negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye"); - zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar"); - - useCubemap = matInstance->getMaterialParameterHandle("$useCubemap"); - - cubemap = matInstance->getMaterialParameterHandle("$cubeMap"); - cubeMips = matInstance->getMaterialParameterHandle("$cubeMips"); - - eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld"); - bbMin = matInstance->getMaterialParameterHandle("$bbMin"); - bbMax = matInstance->getMaterialParameterHandle("$bbMax"); - - useSphereMode = matInstance->getMaterialParameterHandle("$useSphereMode"); - - probeCount = matInstance->getMaterialParameterHandle("$numProbes"); - - for (U32 i = 0; i < 9; i++) - shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i)); - - for (U32 i = 0; i < 5; i++) - shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i)); -} - -RenderProbeMgr::ReflectProbeMaterialInfo::~ReflectProbeMaterialInfo() -{ - SAFE_DELETE(matInstance); -} - -void RenderProbeMgr::ReflectProbeMaterialInfo::setViewParameters(const F32 _zNear, - const F32 _zFar, - const Point3F &_eyePos, - const PlaneF &_farPlane, - const PlaneF &_vsFarPlane) -{ - MaterialParameters *matParams = matInstance->getMaterialParameters(); - - matParams->setSafe(farPlane, *((const Point4F *)&_farPlane)); - - matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane)); - - if (negFarPlaneDotEye->isValid()) + if (clientProbe->mReflectionModeType != ReflectionProbe::DynamicCubemap) { - // -dot( farPlane, eyePos ) - const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d); - matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal); + //Prep our bake path + if (probePrefilterPath.isEmpty() || probeIrradPath.isEmpty()) + { + Con::errorf("RenderProbeMgr::bake() - Unable to bake our captures because probe doesn't have a path set"); + return; + } } - matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar)); + // Save the current transforms so we can restore + // it for child control rendering below. + GFXTransformSaver saver; - Point4F frPlane = *((const Point4F *)&_farPlane); - Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane); - Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar); - const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d); -} + bool probeRenderState = RenderProbeMgr::smRenderReflectionProbes; -void RenderProbeMgr::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly) -{ - //Set up the params - MaterialParameters *matParams = matInstance->getMaterialParameters(); + F32 farPlane = 1000.0f; - matParams->setSafe(radius, probeInfo->mRadius); + ReflectorDesc reflDesc; + reflDesc.texSize = resolution; + reflDesc.farDist = farPlane; + reflDesc.detailAdjust = 1; + reflDesc.objectTypeMask = -1; - Point3F probePos = probeInfo->getPosition() + probeInfo->mProbePosOffset; - //worldViewOnly.mulP(probeInfo->getPosition(), &probePos); - matParams->setSafe(probeWSPos, probePos); + CubeReflector cubeRefl; + cubeRefl.registerReflector(probe, &reflDesc); - worldViewOnly.mulP(probeInfo->getPosition(), &probePos); - matParams->setSafe(probeLSPos, probePos); + ReflectParams reflParams; - // Get the attenuation falloff ratio and normalize it. - Point3F attenRatio = Point3F(0.0f, 1.0f, 1.0f); - F32 total = attenRatio.x + attenRatio.y + attenRatio.z; - if (total > 0.0f) - attenRatio /= total; + //need to get the query somehow. Likely do some sort of get function to fetch from the guiTSControl that's active + CameraQuery query; //need to get the last cameraQuery + query.fov = 90; //90 degree slices for each of the 6 sides + query.nearPlane = 0.1f; + query.farPlane = farPlane; + query.headMatrix = MatrixF(); + query.cameraMatrix = clientProbe->getTransform(); - F32 probeRadius = probeInfo->mRadius; + Frustum culler; + culler.set(false, + query.fov, + (F32)resolution / (F32)resolution, + query.nearPlane, + query.farPlane, + query.cameraMatrix); - Point2F attenParams((1.0f / probeRadius) * attenRatio.y, - (1.0f / (probeRadius * probeRadius)) * attenRatio.z); + S32 stereoTarget = GFX->getCurrentStereoTarget(); - matParams->setSafe(attenuation, attenParams); + Point2I maxRes(2048, 2048); //basically a boundary so we don't go over this and break stuff - NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred"); - NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo"); - NamedTexTarget* colorTexTarget = NamedTexTarget::find("color"); + reflParams.culler = culler; + reflParams.eyeId = stereoTarget; + reflParams.query = &query; + reflParams.startOfUpdateMs = startMSTime; + reflParams.viewportExtent = maxRes; - if (!deferredTexTarget || !matInfoTexTarget || !colorTexTarget) + if (!renderWithProbes) + RenderProbeMgr::smRenderReflectionProbes = false; + + cubeRefl.updateReflection(reflParams); + + //Now, save out the maps + //create irridiance cubemap + if (cubeRefl.getCubemap()) { - Con::errorf("ProbeManager::ReflectProbeMaterialInfo::setProbeParameters: Could not retrieve gbuffer"); - return; - } + //Just to ensure we're prepped for the generation + clientProbe->createClientResources(); - //set textures - GFX->setTexture(0, deferredTexTarget->getTexture()); - GFX->setTexture(1, colorTexTarget->getTexture()); - GFX->setTexture(2, matInfoTexTarget->getTexture()); + //Prep it with whatever resolution we've dictated for our bake + if (clientProbe->mUseHDRCaptures) + { + clientProbe->mIrridianceMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F); + clientProbe->mPrefilterMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F); + } + else + { + clientProbe->mIrridianceMap->mCubemap->initDynamic(resolution, GFXFormatR8G8B8A8); + clientProbe->mPrefilterMap->mCubemap->initDynamic(resolution, GFXFormatR8G8B8A8); + } - //Add some safety catches in the event the cubemaps aren't fully initialized yet - if (probeInfo->mCubemap == nullptr || probeInfo->mCubemap.isNull()) - { - GFX->setCubeTexture(3, nullptr); - matParams->setSafe(cubeMips, 2.0f); + GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false); + + IBLUtilities::GenerateIrradianceMap(renderTarget, cubeRefl.getCubemap(), clientProbe->mIrridianceMap->mCubemap); + IBLUtilities::GeneratePrefilterMap(renderTarget, cubeRefl.getCubemap(), prefilterMipLevels, clientProbe->mPrefilterMap->mCubemap); + + IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap); + IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap); } else { - GFX->setCubeTexture(3, probeInfo->mCubemap.getPointer()); - matParams->setSafe(cubeMips, mPow(probeInfo->mCubemap.getPointer()->getMipMapLevels(), 2.0f)); + Con::errorf("RenderProbeMgr::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!"); } - if (probeInfo->mIrradianceCubemap == nullptr || probeInfo->mIrradianceCubemap.isNull()) - GFX->setCubeTexture(4, nullptr); - else - GFX->setCubeTexture(4, probeInfo->mIrradianceCubemap.getPointer()); + if (!renderWithProbes) + RenderProbeMgr::smRenderReflectionProbes = probeRenderState; - GFX->setTexture(5, probeInfo->mBRDFTexture->getPointer()); + cubeRefl.unregisterReflector(); - //set material params - matParams->setSafe(eyePosWorld, renderState->getCameraPosition()); - matParams->setSafe(bbMin, probeInfo->mBounds.minExtents); - matParams->setSafe(bbMax, probeInfo->mBounds.maxExtents); - matParams->setSafe(useSphereMode, probeInfo->mProbeShapeType == ProbeRenderInst::Sphere ? 1.0f : 0.0f); + U32 endMSTime = Platform::getRealMilliseconds(); + F32 diffTime = F32(endMSTime - startMSTime); + + Con::warnf("RenderProbeMgr::bake() - Finished bake! Took %g milliseconds", diffTime); +} + +void RenderProbeMgr::bakeProbes() +{ + //TODO: make this just find every probe in the current missionGroup and run the bake on it automagically +} + +DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()), + "@brief returns true if control object is inside the fog\n\n.") +{ + if(probe != nullptr) + object->bakeProbe(probe); } \ No newline at end of file diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index fd9147b27..f9e2fb87e 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -55,28 +55,26 @@ static U32 MAXPROBECOUNT = 50; class PostEffect; +class ReflectionProbe; struct ProbeRenderInst : public SystemInterface { - LinearColorF mAmbient; - MatrixF mTransform; F32 mRadius; - F32 mIntensity; bool mDirty; Box3F mBounds; + Point3F mPosition; Point3F mProbePosOffset; GFXCubemapHandle mCubemap; GFXCubemapHandle mIrradianceCubemap; + //Utilized in dynamic reflections CubeReflector mCubeReflector; - GFXTexHandle *mBRDFTexture; - /// The priority of this light used for /// light and shadow scoring. F32 mPriority; @@ -87,16 +85,6 @@ struct ProbeRenderInst : public SystemInterface bool mIsSkylight; - /// Whether to render debugging visualizations - /// for this light. - bool mDebugRender; - - GFXPrimitiveBufferHandle primBuffer; - GFXVertexBufferHandle vertBuffer; - U32 numPrims; - U32 numVerts; - Vector< U32 > numIndicesForPoly; - enum ProbeShapeType { Sphere = 0, ///< Sphere shaped @@ -105,10 +93,6 @@ struct ProbeRenderInst : public SystemInterface ProbeShapeType mProbeShapeType; - //Spherical Harmonics data - LinearColorF mSHTerms[9]; - F32 mSHConstants[5]; - public: ProbeRenderInst(); @@ -121,28 +105,18 @@ public: const MatrixF& getTransform() const { return mTransform; } void setTransform(const MatrixF &xfm) { mTransform = xfm; } - Point3F getPosition() const { return mTransform.getPosition(); } - void setPosition(const Point3F &pos) { mTransform.setPosition(pos); } + Point3F getPosition() const { return mPosition; } + void setPosition(const Point3F &pos) { mPosition = pos; } VectorF getDirection() const { return mTransform.getForwardVector(); } void setDirection(const VectorF &val); - const LinearColorF& getAmbient() const { return mAmbient; } - void setAmbient(const LinearColorF &val) { mAmbient = val; } - void setPriority(F32 priority) { mPriority = priority; } F32 getPriority() const { return mPriority; } void setScore(F32 score) { mScore = score; } F32 getScore() const { return mScore; } - bool isDebugRenderingEnabled() const { return mDebugRender; } - void enableDebugRendering(bool value) { mDebugRender = value; } - - // Builds the world to light view projection used for - // shadow texture and cookie lookups. - void getWorldToLightProj(MatrixF *outMatrix) const; - void clear(); }; @@ -174,26 +148,6 @@ struct ProbeShaderConstants typedef Map ProbeConstantMap; -class ReflectProbeMatInstance : public MatInstance -{ - typedef MatInstance Parent; -protected: - MaterialParameterHandle * mProbeParamsSC; - bool mInternalPass; - - GFXStateBlockRef mProjectionState; - - ProcessedShaderMaterial* mShaderMat; - -public: - ReflectProbeMatInstance(Material &mat) : Parent(mat), mProbeParamsSC(NULL), mInternalPass(false), mProjectionState(NULL) {} - - virtual bool init(const FeatureSet &features, const GFXVertexFormat *vertexFormat); - virtual bool setupPass(SceneRenderState *state, const SceneData &sgData); - - ProcessedShaderMaterial* getProcessedShaderMaterial() { return mShaderMat; } -}; - //************************************************************************** // RenderObjectMgr //************************************************************************** @@ -201,99 +155,53 @@ class RenderProbeMgr : public RenderBinManager { typedef RenderBinManager Parent; - struct ReflectProbeMaterialInfo - { - ReflectProbeMatInstance *matInstance; - - // { zNear, zFar, 1/zNear, 1/zFar } - MaterialParameterHandle *zNearFarInvNearFar; - - // Far frustum plane (World Space) - MaterialParameterHandle *farPlane; - - // Far frustum plane (View Space) - MaterialParameterHandle *vsFarPlane; - - // -dot( farPlane, eyePos ) - MaterialParameterHandle *negFarPlaneDotEye; - - // Light Parameters - MaterialParameterHandle *probeLSPos; - MaterialParameterHandle *probeWSPos; - MaterialParameterHandle *attenuation; - MaterialParameterHandle *radius; - - MaterialParameterHandle *useCubemap; - MaterialParameterHandle *cubemap; - MaterialParameterHandle *cubeMips; - - MaterialParameterHandle *eyePosWorld; - MaterialParameterHandle *bbMin; - MaterialParameterHandle *bbMax; - - MaterialParameterHandle *useSphereMode; - - MaterialParameterHandle *shTerms[9]; - MaterialParameterHandle *shConsts[5]; - - MaterialParameterHandle *probeCount; - - ReflectProbeMaterialInfo(const String &matName, const GFXVertexFormat *vertexFormat); - - virtual ~ReflectProbeMaterialInfo(); - - - void setViewParameters(const F32 zNear, - const F32 zFar, - const Point3F &eyePos, - const PlaneF &farPlane, - const PlaneF &_vsFarPlane); - - void setProbeParameters(const ProbeRenderInst *probe, const SceneRenderState* renderState, const MatrixF &worldViewOnly); - }; - - enum SpecialProbeTypesEnum - { - SkylightProbeType, - SpecialProbeTypesCount - }; - Vector mRegisteredProbes; - ReflectProbeMaterialInfo* mReflectProbeMaterial; + //Array rendering + U32 mEffectiveProbeCount; + S32 mMipCount; + Vector probePositionsData; + Vector probeWorldToObjData; + Vector probeBBMinData; + Vector probeBBMaxData; + Vector probeUseSphereModeData; + Vector probeRadiusData; + Vector probeAttenuationData; + Vector cubeMaps; + Vector irradMaps; - GFXShaderConstHandle *numProbesSC; - GFXShaderConstHandle *probePositionSC; - GFXShaderConstHandle *probeWorldToObjSC; - GFXShaderConstHandle *probeBBMinSC; - GFXShaderConstHandle *probeBBMaxSC; - GFXShaderConstHandle *probeUseSphereModeSC; - GFXShaderConstHandle *probeRadiusSC; - GFXShaderConstHandle *probeAttenuationSC; + AlignedArray mProbePositions; + AlignedArray mProbeBBMin; + AlignedArray mProbeBBMax; + AlignedArray mProbeUseSphereMode; + AlignedArray mProbeRadius; + AlignedArray mProbeAttenuation; - /// The scene graph the light manager is associated with. - //SceneManager *mSceneManager; + GFXCubemapArrayHandle mCubemapArray; + GFXCubemapArrayHandle mIrradArray; + //Utilized in forward rendering ProbeConstantMap mConstantLookup; GFXShaderRef mLastShader; - GFXShaderConstBufferRef mLastConstants; - ProbeShaderConstants* mLastForwardConstants; - - // - // - PostEffect* getProbeArrayEffect(); + ProbeShaderConstants* mLastConstants; // SimObjectPtr mProbeArrayEffect; -protected: +public: + RenderProbeMgr(); + RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder); + virtual void onRemove(); + + // ConsoleObject + static void initPersistFields(); + DECLARE_CONOBJECT(RenderProbeMgr); + +protected: /// The current active light manager. static RenderProbeMgr *smProbeManager; - typedef GFXVertexPNTT FarFrustumQuadVert; - GFXVertexBufferHandle mFarFrustumQuadVerts; - /// This helper function sets the shader constansts /// for the stock 4 light forward lighting code. void _update4ProbeConsts(const SceneData &sgData, @@ -307,38 +215,6 @@ protected: GFXShaderConstHandle *probeLocalPosSC, GFXShaderConstBuffer *shaderConsts); - GFXTextureObject * mBrdfTexture; - - //Array rendering - U32 mEffectiveProbeCount; - S32 mMipCount; - Vector probePositions; - Vector probeWorldToObj; - Vector probeBBMin; - Vector probeBBMax; - Vector probeUseSphereMode; - Vector probeRadius; - Vector probeAttenuation; - Vector cubeMaps; - Vector irradMaps; - - AlignedArray mProbePositions; - AlignedArray mProbeBBMin; - AlignedArray mProbeBBMax; - AlignedArray mProbeUseSphereMode; - AlignedArray mProbeRadius; - AlignedArray mProbeAttenuation; - - GFXCubemapArrayHandle mCubemapArray; - GFXCubemapArrayHandle mIrradArray; -public: - RenderProbeMgr(); - RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder); - - // RenderBinMgr - void updateProbes(); - -protected: void _setupStaticParameters(); void _setupPerFrameParameters(const SceneRenderState *state); virtual void addElement(RenderInst *inst); @@ -346,18 +222,16 @@ protected: ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer); + PostEffect* getProbeArrayEffect(); + public: - // ConsoleObject - static void initPersistFields(); - DECLARE_CONOBJECT(RenderProbeMgr); + // RenderBinMgr + void updateProbes(); /// Returns the active LM. static inline RenderProbeMgr* getProbeManager(); - ReflectProbeMaterialInfo* getReflectProbeMaterial(); - void registerProbe(U32 probeIdx); - void unregisterProbe(U32 probeIdx); virtual void setProbeInfo(ProcessedMaterial *pmat, @@ -369,6 +243,9 @@ public: /// Debug rendering static bool smRenderReflectionProbes; + + void bakeProbe(ReflectionProbe *probeInfo); + void bakeProbes(); }; RenderProbeMgr* RenderProbeMgr::getProbeManager() diff --git a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs index 4a40b8075..12925d102 100644 --- a/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs +++ b/Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs @@ -277,94 +277,7 @@ new CustomMaterial( AL_ParticlePointLightMaterial ) pixVersion = 3.0; }; -//Reflection probe Specular -new ShaderData( ReflectionProbeShader ) -{ - /*DXVertexShaderFile = "shaders/common/lighting/advanced/convexGeometryV.hlsl"; - DXPixelShaderFile = "shaders/common/lighting/advanced/reflectionProbeP.hlsl"; - - OGLVertexShaderFile = "shaders/common/lighting/advanced/gl/convexGeometryV.glsl"; - OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/reflectionProbeP.glsl"; - - samplerNames[0] = "$deferredBuffer"; - samplerNames[1] = "$colorBuffer"; - samplerNames[2] = "$matInfoBuffer"; - samplerNames[3] = "$cubeMap"; - samplerNames[4] = "$irradianceCubemap"; - samplerNames[5] = "$BRDFTexture";*/ - - DXVertexShaderFile = "shaders/common/lighting/advanced/farFrustumQuadV.hlsl"; - DXPixelShaderFile = "shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl"; - - OGLVertexShaderFile = "shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl"; - OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/reflectionProbeArrayP.glsl"; - - samplerNames[0] = "$deferredBuffer"; - samplerNames[1] = "$colorBuffer"; - samplerNames[2] = "$matInfoBuffer"; - samplerNames[3] = "$BRDFTexture"; - samplerNames[4] = "$cubeMap"; - samplerNames[5] = "$irradianceCubemap"; - - pixVersion = 3.0; -}; - -// Convex-geometry light states -new GFXStateBlockData( AL_ProbeState ) -{ - blendDefined = true; - blendEnable = true; - blendSrc = GFXBlendSrcAlpha; //TODO change this to GFXBlendOne once probes are done in one pass! - blendDest = GFXBlendOne; - blendOp = GFXBlendOpAdd; - - colorWriteDefined = true; - colorWriteRed = true; - colorWriteBlue = true; - colorWriteGreen = true; - colorWriteAlpha = true; - - zDefined = true; - zEnable = true; - zWriteEnable = false; - zFunc = GFXCmpGreaterEqual; - - samplersDefined = true; - samplerStates[0] = SamplerClampPoint; // G-buffer - mSamplerNames[0] = "deferredBuffer"; - samplerStates[1] = SamplerClampLinear; - mSamplerNames[1] = "colorBuffer"; - samplerStates[2] = SamplerClampLinear; - mSamplerNames[2] = "matInfoBuffer"; - - mSamplerNames[3] = "BRDFTexture"; - mSamplerNames[4] = "cubeMap"; - mSamplerNames[5] = "irradianceCubemap"; - - cullDefined = true; - cullMode = GFXCullCW; - - stencilDefined = true; - stencilEnable = true; - stencilFailOp = GFXStencilOpKeep; - stencilZFailOp = GFXStencilOpKeep; - stencilPassOp = GFXStencilOpKeep; - stencilFunc = GFXCmpLess; - stencilRef = 0; -}; - -new CustomMaterial( ReflectionProbeMaterial ) -{ - shader = ReflectionProbeShader; - stateBlock = AL_ProbeState; - - sampler["deferredBuffer"] = "#deferred"; - sampler["matInfoBuffer"] = "#matinfo"; - - pixVersion = 3.0; -}; - -//Skylight +//Probe Processing new ShaderData( IrradianceShader ) { DXVertexShaderFile = "shaders/common/lighting/advanced/cubemapV.hlsl"; @@ -391,68 +304,6 @@ new ShaderData( PrefiterCubemapShader ) pixVersion = 3.0; }; -new ShaderData( SkyLightShader ) -{ - DXVertexShaderFile = "shaders/common/lighting/advanced/convexGeometryV.hlsl"; - DXPixelShaderFile = "shaders/common/lighting/advanced/skylightP.hlsl"; - - OGLVertexShaderFile = "shaders/common/lighting/advanced/gl/convexGeometryV.glsl"; - OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/skylightP.glsl"; - - samplerNames[0] = "$deferredBuffer"; - samplerNames[1] = "$matInfoBuffer"; - samplerNames[2] = "$colorBuffer"; - samplerNames[3] = "$cubeMap"; - samplerNames[4] = "$irradianceCubemap"; - samplerNames[5] = "$BRDFTexture"; - - pixVersion = 3.0; -}; - -new CustomMaterial( SkyLightMaterial ) -{ - shader = SkyLightShader; - stateBlock = AL_ProbeState; - - sampler["deferredBuffer"] = "#deferred"; - sampler["matInfoBuffer"] = "#matinfo"; - sampler["colorBuffer"] = "#color"; - - pixVersion = 3.0; -}; - -new ShaderData( ReflectionProbeArrayShader ) -{ - DXVertexShaderFile = "shaders/common/lighting/advanced/reflectionProbeArrayV.hlsl"; - DXPixelShaderFile = "shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl"; - - OGLVertexShaderFile = "shaders/common/lighting/advanced/gl/reflectionProbeArrayV.glsl"; - OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/reflectionProbeArrayP.glsl"; - - samplerNames[0] = "$deferredBuffer"; - samplerNames[1] = "$colorBuffer"; - samplerNames[2] = "$matInfoBuffer"; - samplerNames[3] = "$BRDFTexture"; - samplerNames[4] = "$cubeMap"; - samplerNames[5] = "$irradianceCubemap"; - - pixVersion = 3.0; -}; - -new CustomMaterial( ReflectionProbeArrayMaterial ) -{ - shader = ReflectionProbeArrayShader; - stateBlock = AL_ProbeState; - - sampler["deferredBuffer"] = "#deferred"; - sampler["colorBuffer"] = "#color"; - sampler["matInfoBuffer"] = "#matinfo"; - sampler["BRDFTexture"] = "core/art/pbr/brdfTexture.dds"; - - pixVersion = 3.0; -}; - -// // singleton ShaderData( PFX_ReflectionProbeArray ) { @@ -461,8 +312,6 @@ singleton ShaderData( PFX_ReflectionProbeArray ) //OGLVertexShaderFile = "shaders/common/postFx/gl//postFxV.glsl"; //OGLPixelShaderFile = "shaders/common/postFx/gl/passthruP.glsl"; - - //samplerNames[0] = "$inputTex"; samplerNames[0] = "$deferredBuffer"; samplerNames[1] = "$colorBuffer"; @@ -476,10 +325,6 @@ singleton ShaderData( PFX_ReflectionProbeArray ) singleton GFXStateBlockData( PFX_ReflectionProbeArrayStateBlock ) { - //zDefined = true; - //zEnable = false; - //zWriteEnable = false; - samplersDefined = true; samplerStates[0] = SamplerClampLinear; }; @@ -497,15 +342,11 @@ singleton PostEffect( reflectionProbeArrayPostFX ) shader = PFX_ReflectionProbeArray; stateBlock = PFX_ReflectionProbeArrayStateBlock; - //texture[0] = "#highlight"; - //texture[1] = "$backBuffer"; texture[0] = "#deferred"; texture[1] = "#color"; texture[2] = "#matinfo"; texture[3] = "core/art/pbr/brdfTexture.dds"; - //texture[4] = "$cubeMap"; - //texture[5] = "$irradianceCubemap"; target = "AL_FormatToken"; }; \ No newline at end of file diff --git a/Templates/Full/game/core/scripts/client/missionDownload.cs b/Templates/Full/game/core/scripts/client/missionDownload.cs index 78abee79f..d53464d20 100644 --- a/Templates/Full/game/core/scripts/client/missionDownload.cs +++ b/Templates/Full/game/core/scripts/client/missionDownload.cs @@ -89,6 +89,7 @@ function clientCmdMissionStartPhase3(%seq,%missionName) echo ("*** Phase 3: Mission Lighting"); $MSeq = %seq; $Client::MissionFile = %missionName; + $pref::ReflectionProbes::CurrentLevelPath = filePath($Client::MissionFile) @ "/" @ fileBase($Client::MissionFile) @ "/probes/"; // Need to light the mission before we are ready. // The sceneLightingComplete function will complete the handshake diff --git a/Templates/Full/game/levels/AProbeTest.mis b/Templates/Full/game/levels/AProbeTest.mis index 5e7a97e48..c39162fef 100644 --- a/Templates/Full/game/levels/AProbeTest.mis +++ b/Templates/Full/game/levels/AProbeTest.mis @@ -39,11 +39,9 @@ new SimGroup(MissionGroup) { }; new Skylight() { enabled = "0"; - ProbeShape = "Box"; radius = "10"; posOffset = "0 0 0"; ReflectionMode = "Static Cubemap"; - reflectionPath = "levels/AProbeTest/probes/"; StaticCubemap = "sky_day_hdr_cubemap"; Bake = "0"; position = "0 0 0"; @@ -52,6 +50,8 @@ new SimGroup(MissionGroup) { canSave = "1"; canSaveDynamicFields = "1"; persistentId = "e4c73467-4089-11e8-b478-cd227cd60b8b"; + ProbeShape = "Box"; + reflectionPath = "levels/AProbeTest/probes/"; }; new SimGroup(PlayerDropPoints) { canSave = "1"; @@ -126,15 +126,13 @@ new SimGroup(MissionGroup) { canSaveDynamicFields = "1"; direction = "1 1 -1"; }; - new ReflectionProbe() { + new BoxEnvironmentProbe() { enabled = "1"; - ProbeShape = "Box"; radius = "5"; posOffset = "0 0 0"; ReflectionMode = "Baked Cubemap"; - reflectionPath = "levels/probeTest/probes/"; Bake = "0"; - position = "0 0.280415 4.80432"; + position = "0 0 4"; rotation = "1 0 0 0"; scale = "5 5 5"; canSave = "1"; @@ -144,6 +142,65 @@ new SimGroup(MissionGroup) { IndirectLight = "1 1 1 1"; IndirectLightMode = "Spherical Harmonics"; Intensity = "1"; + ProbeShape = "Box"; + reflectionPath = "levels/probeTest/probes/"; + SkyColor = "0.5 0.5 1 1"; + }; + new BoxEnvironmentProbe() { + enabled = "1"; + radius = "5"; + posOffset = "0 0 0"; + ReflectionMode = "Baked Cubemap"; + Bake = "0"; + position = "-10 8 4"; + rotation = "1 0 0 0"; + scale = "5 5 5"; + canSave = "1"; + canSaveDynamicFields = "1"; + persistentId = "f281a5ff-1ae9-11e9-9c9a-df9135416cc7"; + GroundColor = "0.8 0.7 0.5 1"; + IndirectLight = "1 1 1 1"; + IndirectLightMode = "Spherical Harmonics"; + Intensity = "1"; + reflectionPath = "levels/probeTest/probes/"; + SkyColor = "0.5 0.5 1 1"; + }; + new BoxEnvironmentProbe() { + enabled = "1"; + radius = "5"; + posOffset = "0 0 0"; + ReflectionMode = "Baked Cubemap"; + Bake = "0"; + position = "-10 0 4"; + rotation = "1 0 0 0"; + scale = "5 5 5"; + canSave = "1"; + canSaveDynamicFields = "1"; + persistentId = "e9c2eed2-1ae9-11e9-9c9a-df9135416cc7"; + GroundColor = "0.8 0.7 0.5 1"; + IndirectLight = "1 1 1 1"; + IndirectLightMode = "Spherical Harmonics"; + Intensity = "1"; + reflectionPath = "levels/probeTest/probes/"; + SkyColor = "0.5 0.5 1 1"; + }; + new BoxEnvironmentProbe() { + enabled = "1"; + radius = "5"; + posOffset = "0 0 0"; + ReflectionMode = "Baked Cubemap"; + Bake = "0"; + position = "-10 -8 4"; + rotation = "1 0 0 0"; + scale = "5 5 5"; + canSave = "1"; + canSaveDynamicFields = "1"; + persistentId = "f4db4dde-1ae9-11e9-9c9a-df9135416cc7"; + GroundColor = "0.8 0.7 0.5 1"; + IndirectLight = "1 1 1 1"; + IndirectLightMode = "Spherical Harmonics"; + Intensity = "1"; + reflectionPath = "levels/probeTest/probes/"; SkyColor = "0.5 0.5 1 1"; }; new ConvexShape() { @@ -313,65 +370,5 @@ new SimGroup(MissionGroup) { canSave = "1"; canSaveDynamicFields = "1"; }; - new ReflectionProbe() { - enabled = "1"; - ProbeShape = "Box"; - radius = "5"; - posOffset = "0 0 0"; - ReflectionMode = "Baked Cubemap"; - reflectionPath = "levels/probeTest/probes/"; - Bake = "0"; - position = "-9.34007 0.48281 2.5031"; - rotation = "1 0 0 0"; - scale = "5 5 5"; - canSave = "1"; - canSaveDynamicFields = "1"; - persistentId = "e9c2eed2-1ae9-11e9-9c9a-df9135416cc7"; - GroundColor = "0.8 0.7 0.5 1"; - IndirectLight = "1 1 1 1"; - IndirectLightMode = "Spherical Harmonics"; - Intensity = "1"; - SkyColor = "0.5 0.5 1 1"; - }; - new ReflectionProbe() { - enabled = "1"; - ProbeShape = "Box"; - radius = "5"; - posOffset = "0 0 0"; - ReflectionMode = "Baked Cubemap"; - reflectionPath = "levels/probeTest/probes/"; - Bake = "0"; - position = "-10.1924 8.78742 2.18272"; - rotation = "1 0 0 0"; - scale = "5 5 5"; - canSave = "1"; - canSaveDynamicFields = "1"; - persistentId = "f281a5ff-1ae9-11e9-9c9a-df9135416cc7"; - GroundColor = "0.8 0.7 0.5 1"; - IndirectLight = "1 1 1 1"; - IndirectLightMode = "Spherical Harmonics"; - Intensity = "1"; - SkyColor = "0.5 0.5 1 1"; - }; - new ReflectionProbe() { - enabled = "0"; - ProbeShape = "Box"; - radius = "5"; - posOffset = "0 0 0"; - ReflectionMode = "Baked Cubemap"; - reflectionPath = "levels/probeTest/probes/"; - Bake = "0"; - position = "8.24487 -3.37372 2.18272"; - rotation = "1 0 0 0"; - scale = "5 5 5"; - canSave = "1"; - canSaveDynamicFields = "1"; - persistentId = "f4db4dde-1ae9-11e9-9c9a-df9135416cc7"; - GroundColor = "0.8 0.7 0.5 1"; - IndirectLight = "1 1 1 1"; - IndirectLightMode = "Spherical Harmonics"; - Intensity = "1"; - SkyColor = "0.5 0.5 1 1"; - }; }; //--- OBJECT WRITE END --- diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayV.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayV.hlsl deleted file mode 100644 index 9fa2eda0e..000000000 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayV.hlsl +++ /dev/null @@ -1,52 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "../../hlslStructs.hlsl" -#include "../../shaderModel.hlsl" -#include "../../torque.hlsl" - -struct GFXVertexPT -{ - float3 pos : POSITION; - float4 uv : TEXCOORD1; -}; - -struct ConnectData -{ - float4 hpos : TORQUE_POSITION; - float4 uv0 : TEXCOORD1; - float4 vsEyeDir : TEXCOORD2; -}; - -uniform float4 rtParams0; -uniform float4x4 worldViewOnly; - -ConnectData main( GFXVertexPT IN ) -{ - ConnectData OUT; - - OUT.hpos = float4(IN.pos,1.0); - OUT.uv0 = float4(viewportCoordToRenderTarget( IN.uv, rtParams0 ),0,0); - OUT.vsEyeDir = mul(worldViewOnly, float4(IN.pos, 1.0)); - - return OUT; -} diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl deleted file mode 100644 index 2288fc078..000000000 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl +++ /dev/null @@ -1,171 +0,0 @@ -#include "../../shaderModelAutoGen.hlsl" - -#include "farFrustumQuad.hlsl" -#include "../../lighting.hlsl" -#include "../../torque.hlsl" - -struct ConvexConnectP -{ - float4 pos : TORQUE_POSITION; - float4 wsEyeDir : TEXCOORD0; - float4 ssPos : TEXCOORD1; - float4 vsEyeDir : TEXCOORD2; -}; - -TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0); -TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 1); -TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 2); -TORQUE_UNIFORM_SAMPLERCUBE(cubeMap, 3); -TORQUE_UNIFORM_SAMPLERCUBE(irradianceCubemap, 4); -TORQUE_UNIFORM_SAMPLER2D(BRDFTexture, 5); -uniform float cubeMips; - -uniform float4 rtParams0; - -uniform float3 probeWSPos; -uniform float3 probeLSPos; -uniform float4 vsFarPlane; - -uniform float radius; -uniform float2 attenuation; - -uniform float4x4 worldToObj; -uniform float4x4 cameraToWorld; - -uniform float3 eyePosWorld; -uniform float3 bbMin; -uniform float3 bbMax; - -uniform float useSphereMode; - -#define MAX_PROBES 50 - -uniform float numProbes; -uniform float3 inProbePosArray[MAX_PROBES]; - -// Box Projected IBL Lighting -// Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/ -// and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ -float3 boxProject(float3 wsPosition, float3 reflectDir, float3 boxWSPos, float3 boxMin, float3 boxMax) -{ - float3 nrdir = reflectDir; - float3 offset = wsPosition; - float3 plane1vec = (boxMax - offset) / nrdir; - float3 plane2vec = (boxMin - offset) / nrdir; - - float3 furthestPlane = max(plane1vec, plane2vec); - float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z); - float3 posonbox = offset + nrdir * dist; - - return posonbox - boxWSPos; -} - -float3 iblBoxSpecular(float3 normal, float3 wsPos, float roughness, float3 surfToEye, - TORQUE_SAMPLER2D(brdfTexture), - TORQUE_SAMPLERCUBE(radianceCube), - float3 boxPos, - float3 boxMin, - float3 boxMax) -{ - float ndotv = clamp(dot(normal, surfToEye), 0.0, 1.0); - - // BRDF - float2 brdf = TORQUE_TEX2DLOD(brdfTexture, float4(roughness, ndotv,0.0,0.0)).xy; - - // Radiance (Specular) - float maxmip = pow(cubeMips+1,2); - float lod = roughness*maxmip; - float3 r = reflect(surfToEye, normal); - float3 cubeR = normalize(r); - cubeR = boxProject(wsPos, cubeR, boxPos, boxMin, boxMax); - - float3 radiance = TORQUE_TEXCUBELOD(radianceCube, float4(cubeR, lod)).xyz * (brdf.x + brdf.y); - - return radiance; -} - -float defineBoxSpaceInfluence(float3 surfPosWS, float3 probePos, float radius, float atten) -{ - float3 surfPosLS = mul( worldToObj, float4(surfPosWS,1.0)).xyz; - - float3 boxMinLS = probePos-(float3(1,1,1)*radius); - float3 boxMaxLS = probePos+(float3(1,1,1)*radius); - - float boxOuterRange = length(boxMaxLS - boxMinLS); - float boxInnerRange = boxOuterRange / atten; - - float3 localDir = float3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z)); - localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange); - - return max(localDir.x, max(localDir.y, localDir.z)) * -1; -} - -float4 main( ConvexConnectP IN ) : SV_TARGET -{ - // Compute scene UV - float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; - float2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); - - //eye ray WS/LS - float3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); - float3 wsEyeRay = mul(cameraToWorld, float4(vsEyeRay, 0)).xyz; - - //unpack normal and linear depth - float4 normDepth = TORQUE_DEFERRED_UNCONDITION(deferredBuffer, uvScene); - - //create surface - Surface surface = createSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer), - uvScene, eyePosWorld, wsEyeRay, cameraToWorld); - float blendVal = 1.0; - /*if(useSphereMode) - { - float3 L = probeWSPos - surface.P; - blendVal = 1.0-length(L)/radius; - clip(blendVal); - } - else - { - float tempAttenVal = 3.5; - blendVal = defineBoxSpaceInfluence(surface.P, probeWSPos, radius, tempAttenVal); - clip(blendVal); - float compression = 0.05; - blendVal=(1.0-compression)+blendVal*compression; - }*/ - - float3 surfToEye = normalize(surface.P - eyePosWorld); - float3 irradiance = TORQUE_TEXCUBELOD(irradianceCubemap, float4(surface.N,0)).xyz; - float3 specular = iblBoxSpecular(surface.N, surface.P, surface.roughness, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture), TORQUE_SAMPLERCUBE_MAKEARG(cubeMap), probeWSPos, bbMin, bbMax); - - int i; - irradiance = float3(0,0,0); - float blendSum = 0.00001; - for(i=0; i < numProbes; i++) - { - float3 probeWS = inProbePosArray[i]; - - float3 L = probeWS - surface.P; - blendVal = 1.0-length(L)/radius; - blendVal = max(0,blendVal); - - irradiance += float3(blendVal,blendVal,blendVal); - specular = irradiance; - blendSum += blendVal; - } - //irradiance /= blendSum; - //specular /= blendSum; - blendSum /= numProbes; - - //render into the bound space defined above - // - //float3 irradiance = TORQUE_TEXCUBELOD(irradianceCubemap, float4(surface.N,0)).xyz; - //float3 specular = iblBoxSpecular(surface.N, surface.P, surface.roughness, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture), TORQUE_SAMPLERCUBE_MAKEARG(cubeMap), probeWSPos, bbMin, bbMax); - float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); - specular *= F; - //energy conservation - float3 kD = 1.0.xxx - F; - kD *= 1.0 - surface.metalness; - //final diffuse color - float3 diffuse = kD * irradiance * surface.baseColor.rgb; - - return float4(diffuse + specular * surface.ao, blendSum); -} diff --git a/Templates/Full/game/shaders/common/lighting/advanced/skylightP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/skylightP.hlsl deleted file mode 100644 index 3bf8c111f..000000000 --- a/Templates/Full/game/shaders/common/lighting/advanced/skylightP.hlsl +++ /dev/null @@ -1,62 +0,0 @@ -#include "../../shaderModelAutoGen.hlsl" - -#include "farFrustumQuad.hlsl" -#include "../../lighting.hlsl" -#include "../../torque.hlsl" - -struct ConvexConnectP -{ - float4 pos : TORQUE_POSITION; - float4 wsEyeDir : TEXCOORD0; - float4 ssPos : TEXCOORD1; - float4 vsEyeDir : TEXCOORD2; -}; - -TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0); -TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 1); -TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 2); -TORQUE_UNIFORM_SAMPLERCUBE(cubeMap, 3); -TORQUE_UNIFORM_SAMPLERCUBE(irradianceCubemap, 4); -TORQUE_UNIFORM_SAMPLER2D(BRDFTexture, 5); - -uniform float4 rtParams0; -uniform float4 vsFarPlane; -uniform float4x4 cameraToWorld; -uniform float3 eyePosWorld; - -float3 iblSpecular(in Surface surface, float3 F) -{ - const float MAX_REFLECTION_LOD = 4.0; - float3 prefilteredColor = TORQUE_TEXCUBELOD(cubeMap, float4(surface.R, surface.roughness * MAX_REFLECTION_LOD)).rgb; - float2 envBRDF = TORQUE_TEX2D(BRDFTexture, float2(surface.NdotV, surface.roughness)).rg; - return prefilteredColor * (F * envBRDF.x + envBRDF.y); -} - -float4 main( ConvexConnectP IN ) : SV_TARGET -{ - // Compute scene UV - float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; - float2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); - - //eye ray WS/LS - float3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); - float3 wsEyeRay = mul(cameraToWorld, float4(vsEyeRay, 0)).xyz; - - //unpack normal and linear depth - float4 normDepth = TORQUE_DEFERRED_UNCONDITION(deferredBuffer, uvScene); - - //create surface - Surface surface = createSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer), - uvScene, eyePosWorld, wsEyeRay, cameraToWorld); - - float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); - float3 irradiance = TORQUE_TEXCUBELOD(irradianceCubemap, float4(surface.N,0)).rgb; - float3 specular = iblSpecular(surface, F); - //energy conservation - float3 kD = 1.0.xxx - F; - kD *= 1.0 - surface.metalness; - //final diffuse color - float3 diffuse = kD * irradiance * surface.baseColor.rgb; - - return float4(diffuse + specular * surface.ao, 0); -} diff --git a/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs index 712986e38..22c823b1f 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs @@ -56,7 +56,8 @@ function EWCreatorWindow::init( %this ) %this.registerMissionObject( "PointLight", "Point Light" ); %this.registerMissionObject( "SpotLight", "Spot Light" ); - %this.registerMissionObject( "ReflectionProbe", "Reflection Probe" ); + %this.registerMissionObject( "BoxEnvironmentProbe", "Box Environment Probe" ); + %this.registerMissionObject( "SphereEnvironmentProbe", "Sphere Environment Probe" ); %this.registerMissionObject( "Skylight", "Skylight" ); %this.registerMissionObject( "GroundCover", "Ground Cover" ); diff --git a/Templates/Full/game/tools/worldEditor/scripts/lighting.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/lighting.ed.cs index f9afcaad4..180504f38 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/lighting.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/lighting.ed.cs @@ -64,18 +64,5 @@ function EditorLightingMenu::onMenuSelect( %this ) function updateReflectionProbes() { - /*%probeIds = parseMissionGroupForIds("ReflectionProbe", ""); - %probeCount = getWordCount(%probeIds); - - for(%i=0; %i < %probeCount; %i++) - { - %probe = getWord(%probeIds, %i); - - %path = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/"; - %probe.bake(%path, 64); - } - - EWorldEditor.isDirty = true;*/ - - Canvas.pushDialog(ProbeBakeDlg); + Canvas.pushDialog(ProbeBakeDlg); } diff --git a/Templates/Full/game/tools/worldEditor/scripts/probeBake.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/probeBake.ed.cs index 981658d91..9c561e0bf 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/probeBake.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/probeBake.ed.cs @@ -16,14 +16,16 @@ function ProbeBakeDlg::onWake(%this) function ProbeBakeDlg_RunBake::onClick(%this) { - %probeIds = parseMissionGroupForIds("ReflectionProbe", ""); + %boxProbeIds = parseMissionGroupForIds("BoxEnvironmentProbe", ""); + %sphereProbeIds = parseMissionGroupForIds("SphereEnvironmentProbe", ""); %skylightIds = parseMissionGroupForIds("Skylight", ""); + %probeIds = rtrim(ltrim(%boxProbeIds SPC %sphereProbeIds)); %probeIds = rtrim(ltrim(%probeIds SPC %skylightIds)); %probeCount = getWordCount(%probeIds); %numIter = ProbeBakeDlg_NumIterTxt.getText(); - %resolution = ProbeBakeDlg_ProbeResList.getText(); + $pref::ReflectionProbes::BakeResolution = ProbeBakeDlg_ProbeResList.getText(); %progressStep = 100 / (%numIter * %probeCount); %currentProgressValue = 0; @@ -32,17 +34,17 @@ function ProbeBakeDlg_RunBake::onClick(%this) for(%iter=0; %iter < %numIter; %iter++) { - %renderWithProbes = false; + $pref::ReflectionProbes::RenderWithProbes = false; if(%iter != 0) - %renderWithProbes = true; + $pref::ReflectionProbes::RenderWithProbes = true; for(%i=0; %i < %probeCount; %i++) { %probe = getWord(%probeIds, %i); - %path = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/"; - %probe.bake(%path, %resolution, %renderWithProbes); + $pref::ReflectionProbes::CurrentLevelPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/"; + ProbeBin.bakeProbe(%probe); %currentProgressValue += %progressStep; ProbeBakeDlg_Progress.setValue(%currentProgressValue);