diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp index 61b6681ea..a511cd4ad 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp @@ -2870,3 +2870,214 @@ void HardwareSkinningFeatureGLSL::processVert(Vector &componen output = meta; } + +//**************************************************************************** +// ReflectionProbeFeatHLSL +//**************************************************************************** + +ReflectionProbeFeatGLSL::ReflectionProbeFeatGLSL() + : mDep(ShaderGen::smCommonShaderPath + String("/gl/lighting.glsl")) +{ + addDependency(&mDep); +} +void ReflectionProbeFeatGLSL::processPix(Vector& componentList, + const MaterialFeatureData& fd) +{ + // Skip out on realtime lighting if we don't have a normal + // or we're doing some sort of baked lighting. + // + // TODO: We can totally detect for this in the material + // feature setup... we should move it out of here! + // + if (fd.features[MFT_LightMap] || fd.features[MFT_ToneMap] || fd.features[MFT_VertLit]) + return; + + ShaderConnector * connectComp = dynamic_cast(componentList[C_CONNECTOR]); + + MultiLine * meta = new MultiLine; + + // Now the wsPosition and wsView. + Var * wsPosition = getInWsPosition(componentList); + Var * wsView = getWsView(wsPosition, meta); + + Var * albedo = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); + + //Reflection Probe WIP + U32 MAX_FORWARD_PROBES = 4; + + Var * numProbes = new Var("numProbes", "float"); + numProbes->uniform = true; + numProbes->constSortPos = cspPotentialPrimitive; + + Var * cubeMips = new Var("cubeMips", "float"); + cubeMips->uniform = true; + cubeMips->constSortPos = cspPotentialPrimitive; + + Var * hasSkylight = new Var("hasSkylight", "float"); + hasSkylight->uniform = true; + hasSkylight->constSortPos = cspPotentialPrimitive; + + Var * inProbePosArray = new Var("inProbePosArray", "vec4"); + inProbePosArray->arraySize = MAX_FORWARD_PROBES; + inProbePosArray->uniform = true; + inProbePosArray->constSortPos = cspPotentialPrimitive; + + Var * inRefPosArray = new Var("inRefPosArray", "vec4"); + inRefPosArray->arraySize = MAX_FORWARD_PROBES; + inRefPosArray->uniform = true; + inRefPosArray->constSortPos = cspPotentialPrimitive; + + Var * bbMinArray = new Var("inProbeBoxMin", "vec4"); + bbMinArray->arraySize = MAX_FORWARD_PROBES; + bbMinArray->uniform = true; + bbMinArray->constSortPos = cspPotentialPrimitive; + + Var * bbMaxArray = new Var("inProbeBoxMax", "vec4"); + bbMaxArray->arraySize = MAX_FORWARD_PROBES; + bbMaxArray->uniform = true; + bbMaxArray->constSortPos = cspPotentialPrimitive; + + Var * probeConfigData = new Var("probeConfigData", "vec4"); + probeConfigData->arraySize = MAX_FORWARD_PROBES; + probeConfigData->uniform = true; + probeConfigData->constSortPos = cspPotentialPrimitive; + + Var * worldToObjArray = new Var("worldToObjArray", "mat4x4"); + worldToObjArray->arraySize = MAX_FORWARD_PROBES; + worldToObjArray->uniform = true; + worldToObjArray->constSortPos = cspPotentialPrimitive; + + // create texture var + Var* BRDFTexture = new Var; + BRDFTexture->setType("sampler2D"); + BRDFTexture->setName("BRDFTexture"); + BRDFTexture->uniform = true; + BRDFTexture->sampler = true; + BRDFTexture->constNum = Var::getTexUnitNum(); // used as texture unit num here + + Var * specularCubemapAR = new Var("specularCubemapAR", "samplerCubeArray"); + specularCubemapAR->uniform = true; + specularCubemapAR->sampler = true; + specularCubemapAR->constNum = Var::getTexUnitNum(); + + Var * irradianceCubemapAR = new Var("irradianceCubemapAR", "samplerCubeArray"); + irradianceCubemapAR->uniform = true; + irradianceCubemapAR->sampler = true; + irradianceCubemapAR->constNum = Var::getTexUnitNum(); + + Var * skylightSpecularMap = new Var("skylightSpecularMap", "samplerCube"); + skylightSpecularMap->uniform = true; + skylightSpecularMap->sampler = true; + skylightSpecularMap->constNum = Var::getTexUnitNum(); + + Var * skylightIrradMap = new Var("skylightIrradMap", "samplerCube"); + skylightIrradMap->uniform = true; + skylightIrradMap->sampler = true; + skylightIrradMap->constNum = Var::getTexUnitNum(); + + + Var * inTex = getInTexCoord("texCoord", "vec2", componentList); + if (!inTex) + return; + + Var * diffuseColor = (Var*)LangElement::find("diffuseColor"); + if (!diffuseColor) + { + diffuseColor = new Var; + diffuseColor->setType("vec4"); + diffuseColor->setName("diffuseColor"); + LangElement* colorDecl = new DecOp(diffuseColor); + meta->addStatement(new GenOp(" @ = vec4(1.0,1.0,1.0,1.0);\r\n", colorDecl)); //default to flat white + } + + Var* matinfo = (Var*)LangElement::find("specularColor"); + if (!matinfo) + { + Var* metalness = (Var*)LangElement::find("metalness"); + if (!metalness) + { + metalness = new Var("metalness", "float"); + metalness->uniform = true; + metalness->constSortPos = cspPotentialPrimitive; + } + + Var* smoothness = (Var*)LangElement::find("smoothness"); + if (!smoothness) + { + smoothness = new Var("smoothness", "float"); + smoothness->uniform = true; + smoothness->constSortPos = cspPotentialPrimitive; + } + + matinfo = new Var("specularColor", "vec4"); + LangElement* colorDecl = new DecOp(matinfo); + meta->addStatement(new GenOp(" @ = vec4(0.0,1.0,@,@);\r\n", colorDecl, smoothness, metalness)); //reconstruct matinfo, no ao darkening + } + + Var* bumpNormal = (Var*)LangElement::find("bumpNormal"); + if (!bumpNormal) + { + bumpNormal = new Var("bumpNormal", "vec4"); + LangElement* colorDecl = new DecOp(bumpNormal); + meta->addStatement(new GenOp(" @ = vec4(1.0,0.0,0.0,0.0);\r\n", colorDecl)); //default to identity normal + } + + Var* wsEyePos = (Var*)LangElement::find("eyePosWorld"); + + Var* worldToCamera = (Var*)LangElement::find("worldToCamera"); + if (!worldToCamera) + { + worldToCamera = new Var; + worldToCamera->setType("mat4x4"); + worldToCamera->setName("worldToCamera"); + worldToCamera->uniform = true; + worldToCamera->constSortPos = cspPass; + } + + //Reflection vec + Var* surface = new Var("surface", "Surface"); + meta->addStatement(new GenOp(" @ = createForwardSurface(@,@,@,@,@,@,@,@);\r\n\n", new DecOp(surface), diffuseColor, bumpNormal, matinfo, + inTex, wsPosition, wsEyePos, wsView, worldToCamera)); + String computeForwardProbes = String::String(" @.rgb += computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t"); + computeForwardProbes += String::String("@,@,\r\n\t\t"); + computeForwardProbes += String::String("@, @, \r\n\t\t"); + computeForwardProbes += String::String("@,@).rgb; \r\n"); + + meta->addStatement(new GenOp(computeForwardProbes.c_str(), albedo, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, bbMinArray, bbMaxArray, inRefPosArray, + hasSkylight, BRDFTexture, + skylightIrradMap, skylightSpecularMap, + irradianceCubemapAR, specularCubemapAR)); + + output = meta; +} + +ShaderFeature::Resources ReflectionProbeFeatGLSL::getResources(const MaterialFeatureData& fd) +{ + Resources res; + + res.numTex = 5; + res.numTexReg = 5; + + return res; +} + +void ReflectionProbeFeatGLSL::setTexData(Material::StageData& stageDat, + const MaterialFeatureData& stageFeatures, + RenderPassData& passData, + U32& texIndex) +{ + if (stageFeatures.features[MFT_ReflectionProbes]) + { + passData.mSamplerNames[texIndex] = "BRDFTexture"; + passData.mTexType[texIndex++] = Material::Standard; + // assuming here that it is a scenegraph cubemap + passData.mSamplerNames[texIndex] = "specularCubemapAR"; + passData.mTexType[texIndex++] = Material::SGCube; + passData.mSamplerNames[texIndex] = "irradianceCubemapAR"; + passData.mTexType[texIndex++] = Material::SGCube; + passData.mSamplerNames[texIndex] = "skylightSpecularMap"; + passData.mTexType[texIndex++] = Material::SGCube; + passData.mSamplerNames[texIndex] = "skylightIrradMap"; + passData.mTexType[texIndex++] = Material::SGCube; + } +} \ No newline at end of file diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h index d6ef4772a..264e3682b 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h @@ -673,22 +673,22 @@ public: /// Reflection Probes class ReflectionProbeFeatGLSL : public ShaderFeatureGLSL { +protected: + ShaderIncludeDependency mDep; + public: - virtual void processVert(Vector &componentList, - const MaterialFeatureData &fd) {} + ReflectionProbeFeatGLSL(); + + virtual void processPix(Vector& componentList, + const MaterialFeatureData& fd); - virtual void processPix(Vector &componentList, - const MaterialFeatureData &fd) {} - - virtual Resources getResources(const MaterialFeatureData &fd) { - return Resources(); - } + virtual Resources getResources(const MaterialFeatureData& fd); // Sets textures and texture flags for current pass - virtual void setTexData(Material::StageData &stageDat, - const MaterialFeatureData &fd, - RenderPassData &passData, - U32 &texIndex) {} + virtual void setTexData(Material::StageData& stageDat, + const MaterialFeatureData& fd, + RenderPassData& passData, + U32& texIndex); virtual String getName() { diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index 650d36562..febf7d95b 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp @@ -2944,7 +2944,7 @@ void HardwareSkinningFeatureHLSL::processVert( Vector &compo //**************************************************************************** ReflectionProbeFeatHLSL::ReflectionProbeFeatHLSL() - : mDep(String(Con::getVariable("$Core::CommonShaderPath")) + String("/lighting.hlsl")) + : mDep(ShaderGen::smCommonShaderPath + String("/lighting.hlsl")) { addDependency(&mDep); } @@ -2964,27 +2964,7 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList ShaderConnector *connectComp = dynamic_cast(componentList[C_CONNECTOR]); MultiLine *meta = new MultiLine; - - // Look for a wsNormal or grab it from the connector. - /*Var *wsNormal = (Var*)LangElement::find("wsNormal"); - if (!wsNormal) - { - wsNormal = connectComp->getElement(RT_TEXCOORD); - wsNormal->setName("wsNormal"); - wsNormal->setStructName("IN"); - wsNormal->setType("float3"); - - // If we loaded the normal its our responsibility - // to normalize it... the interpolators won't. - // - // Note we cast to half here to get partial precision - // optimized code which is an acceptable loss of - // precision for normals and performs much better - // on older Geforce cards. - // - meta->addStatement(new GenOp(" @ = normalize( half3( @ ) );\r\n", wsNormal, wsNormal)); - }*/ - + // Now the wsPosition and wsView. Var *wsPosition = getInWsPosition(componentList); Var *wsView = getWsView(wsPosition, meta); diff --git a/Templates/Full/game/shaders/common/gl/lighting.glsl b/Templates/Full/game/shaders/common/gl/lighting.glsl index d37b25224..a00d4ad60 100644 --- a/Templates/Full/game/shaders/common/gl/lighting.glsl +++ b/Templates/Full/game/shaders/common/gl/lighting.glsl @@ -143,6 +143,26 @@ Surface createSurface(vec4 normDepth, sampler2D colorBuffer, sampler2D matInfoBu return surface; } +Surface createForwardSurface(vec4 baseColor, vec4 normal, vec4 pbrProperties, in vec2 uv, in vec3 wsPosition, in vec3 wsEyePos, in vec3 wsEyeRay, in mat4x4 invView) +{ + Surface surface;// = Surface(); + + surface.depth = 0; + surface.P = wsPosition; + surface.N = tMul(invView, vec4(normal.xyz,0)).xyz; //TODO move t3d to use WS normals + surface.V = normalize(wsEyePos - surface.P); + surface.baseColor = baseColor; + const float minRoughness=1e-4; + surface.roughness = clamp(1.0 - pbrProperties.b, minRoughness, 1.0); //t3d uses smoothness, so we convert to roughness. + surface.roughness_brdf = surface.roughness * surface.roughness; + surface.metalness = pbrProperties.a; + surface.ao = pbrProperties.g; + surface.matFlag = pbrProperties.r; + + surface.Update(); + return surface; +} + struct SurfaceToLight { vec3 L; // surface to light vector @@ -312,15 +332,13 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 bbMin, return posonbox - refPosition.xyz; } -/*vec4 computeForwardProbes(Surface surface, - float cubeMips, float numProbes, mat4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES], +vec4 computeForwardProbes(Surface surface, + float cubeMips, float numProbes, mat4x4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES], vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 bbMinArray[MAX_FORWARD_PROBES], vec4 bbMaxArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES], - float hasSkylight, samplerCube skylightIrradMap, samplerCube skylightSpecularMap, - sampler2D BRDFTexture, samplerCubeArray irradianceCubemapAR, - samplerCubeArray specularCubemapAR) + float hasSkylight, sampler2D BRDFTexture, + samplerCube skylightIrradMap, samplerCube skylightSpecularMap, + samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR) { - return vec4(0,0,0,1); - int i = 0; float blendFactor[MAX_FORWARD_PROBES]; float blendSum = 0; @@ -373,11 +391,8 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 bbMin, { blendFactor[i] *= invBlendSumWeighted; contribution[i] *= blendFactor[i]; - //alpha -= contribution[i]; } } - //else - // alpha -= blendSum; vec3 irradiance = vec3(0, 0, 0); vec3 specular = vec3(0, 0, 0); @@ -385,13 +400,14 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 bbMin, // Radiance (Specular) float lod = surface.roughness*cubeMips; - float alpha = 1; +//1 + float alpha = 1.0f; for (i = 0; i < numProbes; ++i) { float contrib = contribution[i]; if (contrib != 0) { - int cubemapIdx = probeConfigData[i].a; + int cubemapIdx = int(probeConfigData[i].a); vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], bbMinArray[i].xyz, bbMaxArray[i].xyz, inRefPosArray[i].xyz); irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib; @@ -409,12 +425,12 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 bbMin, vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); //energy conservation - vec3 kD = 1.0.xxx - F; + vec3 kD = vec3(1.0,1.0,1.0) - F; kD *= 1.0 - surface.metalness; //apply brdf //Do it once to save on texture samples - vec2 brdf = texture(BRDFTexture, vec2(surface.roughness, surface.NdotV)).xy; + vec2 brdf = textureLod(BRDFTexture, vec2(surface.roughness, surface.NdotV),0).xy; specular *= brdf.x * F + brdf.y; //final diffuse color @@ -423,4 +439,4 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 bbMin, finalColor = vec4(irradiance.rgb,1); return finalColor; -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/reflectionProbeArrayP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/reflectionProbeArrayP.glsl index c8e17b422..2298c958c 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/reflectionProbeArrayP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/reflectionProbeArrayP.glsl @@ -118,11 +118,8 @@ void main() { blendFactor[i] *= invBlendSumWeighted; contribution[i] *= blendFactor[i]; - alpha -= contribution[i]; } } - else - alpha -= blendSum; #if DEBUGVIZ_ATTENUATION == 1 float contribAlpha = 1;