Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ cmake-build-*/
/mingw/
/.cache/
/_skbuild/

/buildrelease/
# Meta data of macOS's Finder.app
.DS_Store

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ bool CookTorranceLighting::createCpuSubPrograms(ProgramSet* programSet)

// add the lighting computation
auto mrparams = psMain->resolveLocalParameter(GCT_FLOAT2, "metalRoughness");
auto ao = psMain->resolveLocalParameter(GCT_FLOAT1, "ao");
fstage.assign(1.0f, ao); //Default to no AO.
if(!mMetalRoughnessMapName.empty())
{
auto metalRoughnessSampler =
Expand All @@ -106,6 +108,7 @@ bool CookTorranceLighting::createCpuSubPrograms(ProgramSet* programSet)
// This layout intentionally reserves the 'r' channel for (optional) occlusion map data
fstage.sampleTexture(metalRoughnessSampler, psInTexcoord, mrSample);
fstage.assign(In(mrSample).mask(Operand::OPM_YZ), mrparams);
fstage.assign(In(mrSample).x(), ao);
}
else
{
Expand All @@ -124,7 +127,7 @@ bool CookTorranceLighting::createCpuSubPrograms(ProgramSet* programSet)
fstage.assign(Vector3(0), Out(outDiffuse).xyz());
fstage.mul(In(diffuse).w(), In(outDiffuse).w(), Out(outDiffuse).w()); // forward alpha

fstage.callFunction("PBR_MakeParams", {In(baseColor), In(mrparams), InOut(pixelParams)});
fstage.callFunction("PBR_MakeParams", {In(baseColor), In(mrparams), In(ao), InOut(pixelParams)});

fstage = psMain->getStage(FFP_PS_PBR_LIGHTING_END);
if(mLightCount > 0)
Expand Down
65 changes: 57 additions & 8 deletions Components/RTShaderSystem/src/OgreShaderImageBasedLighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int ImageBasedLighting::getExecutionOrder() const { return FFP_LIGHTING + 10; }

bool ImageBasedLighting::setParameter(const String& name, const String& value)
{
if (name == "texture" && !value.empty())
if ((name == "texture" || name == "texture_diffuse") && !value.empty())
{
mEnvMapName = value;
return true;
Expand All @@ -34,14 +34,20 @@ bool ImageBasedLighting::setParameter(const String& name, const String& value)
mIsLuminanceParamDirty = true;
return StringConverter::parse(value, mLuminance);
}

else if (name == "texture_specular" && !value.empty())
{
//If set, the shader will use seperate "diffuse irradiance" and "specular ggx" cubemaps for IBL.
mEnvMapNameSpecular = value;
return true;
}
return false;
}

void ImageBasedLighting::copyFrom(const SubRenderState& rhs)
{
const ImageBasedLighting& rhsIBL = static_cast<const ImageBasedLighting&>(rhs);
mEnvMapName = rhsIBL.mEnvMapName;
mEnvMapNameSpecular = rhsIBL.mEnvMapNameSpecular;
mLuminance = rhsIBL.mLuminance;
}

Expand All @@ -66,6 +72,15 @@ bool ImageBasedLighting::preAddToRenderState(const RenderState* renderState, Pas
tus->setHardwareGammaEnabled(true);
mEnvMapSamplerIndex = dstPass->getNumTextureUnitStates() - 1;

// Check for dual cubemaps (diffuse irradiance plus specular convoluted). Add second texture if applicable.
if (mEnvMapNameSpecular != "")
{
tus = dstPass->createTextureUnitState();
tus->setTextureName(mEnvMapNameSpecular, TEX_TYPE_CUBE_MAP);
tus->setHardwareGammaEnabled(true);
mEnvMapSamplerIndexSpecular = dstPass->getNumTextureUnitStates() - 1;
}

return true;
}

Expand Down Expand Up @@ -101,15 +116,37 @@ bool ImageBasedLighting::createCpuSubPrograms(ProgramSet* programSet)

auto dfgLUTSampler = psProgram->resolveParameter(GCT_SAMPLER2D, "dfgLUTSampler", mDfgLUTSamplerIndex);
auto iblEnvSampler = psProgram->resolveParameter(GCT_SAMPLERCUBE, "iblEnvSampler", mEnvMapSamplerIndex);
Ogre::RTShader::UniformParameterPtr iblEnvSpecularSampler = NULL;
Ogre::RTShader::UniformParameterPtr iblEnvSize = NULL;

// Add secondary cubemap if applicable.
if (mEnvMapNameSpecular != "")
{
psProgram->addPreprocessorDefines("HAS_DUAL_TEXTURE");
iblEnvSpecularSampler = psProgram->resolveParameter(GCT_SAMPLERCUBE, "iblEnvSpecularSampler", mEnvMapSamplerIndexSpecular);
iblEnvSize = psProgram->resolveParameter(GpuProgramParameters::ACT_TEXTURE_SIZE, mEnvMapSamplerIndexSpecular);
}
else
{
iblEnvSize = psProgram->resolveParameter(GpuProgramParameters::ACT_TEXTURE_SIZE, mEnvMapSamplerIndex);
}

auto iblEnvSize = psProgram->resolveParameter(GpuProgramParameters::ACT_TEXTURE_SIZE, mEnvMapSamplerIndex);
auto invViewMat = psProgram->resolveParameter(GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX);

auto fstage = psMain->getStage(FFP_PS_PBR_LIGHTING_BEGIN + 5);

fstage.callFunction("evaluateIBL",
{InOut(pixel), In(viewNormal), In(viewPos), In(invViewMat), In(dfgLUTSampler), In(iblEnvSampler),
In(iblEnvSize).w(), In(mLuminanceParam), InOut(outDiffuse).xyz()});
//Add second texture if set.
if (mEnvMapNameSpecular == "")
{
fstage.callFunction("evaluateIBL",
{InOut(pixel), In(viewNormal), In(viewPos), In(invViewMat), In(dfgLUTSampler),
In(iblEnvSampler), In(iblEnvSize).w(), In(mLuminanceParam), InOut(outDiffuse).xyz()});
}
else
{
fstage.callFunction("evaluateIBL", {InOut(pixel), In(viewNormal), In(viewPos), In(invViewMat), In(dfgLUTSampler),
In(iblEnvSampler), In(iblEnvSpecularSampler), In(iblEnvSize).w(), In(mLuminanceParam), InOut(outDiffuse).xyz()});
}

return true;
}
Expand All @@ -134,13 +171,13 @@ SubRenderState* ImageBasedLightingFactory::createInstance(const ScriptProperty&
if (prop.name != "image_based_lighting" || prop.values.size() < 2)
return NULL;

if(prop.values[0] != "texture")
if (prop.values[0] != "texture" && prop.values[0] != "texture_diffuse")
{
translator->emitError();
return NULL;
}
auto ret = static_cast<ImageBasedLighting*>(createOrRetrieveInstance(translator));
ret->setParameter("texture", prop.values[1]);
ret->setParameter(prop.values[0], prop.values[1]);

if (prop.values.size() < 4)
return ret;
Expand All @@ -153,6 +190,18 @@ SubRenderState* ImageBasedLightingFactory::createInstance(const ScriptProperty&

ret->setParameter("luminance", prop.values[3]);

if (prop.values.size() < 6)
return ret;

//If this is set "texture" is then used as a diffuse texture only
if (prop.values[4] != "texture_specular")
{
translator->emitError();
return NULL;
}

ret->setParameter("texture_specular", prop.values[5]);

return ret;
}

Expand Down
3 changes: 3 additions & 0 deletions Components/RTShaderSystem/src/OgreShaderImageBasedLighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ class ImageBasedLighting : public SubRenderState
friend class ImageBasedLightingFactory;
int mDfgLUTSamplerIndex = 0;
int mEnvMapSamplerIndex = 0;
int mEnvMapSamplerIndexSpecular = 0;
float mLuminance = 1.0f;
String mEnvMapName;
String mEnvMapNameSpecular;
UniformParameterPtr mLuminanceParam;
bool mIsLuminanceParamDirty = true;

public:
const String& getType() const override;
int getExecutionOrder() const override;
Expand Down
16 changes: 15 additions & 1 deletion Media/RTShaderLib/RTSLib_IBL.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ vec3 prefilteredRadiance(samplerCube light_iblSpecular, const vec3 r, float perc
return decodeDataForIBL(textureCubeLod(light_iblSpecular, r, lod));
}

vec3 IrradianceMap(samplerCube iblDiffuse, const vec3 n) {
return decodeDataForIBL(textureCubeLod(iblDiffuse, n, 0.0));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cant you just copy this data into the highest mip level of iblEnvTexSpecular and use the "old" single texture path?

Maybe I should check your sample for actual usage though..

}

vec3 getSpecularDominantDirection(const vec3 n, const vec3 r, float roughness) {
return mix(r, n, roughness * roughness);
}
Expand All @@ -43,6 +47,9 @@ void evaluateIBL(inout PixelParams pixel,
in mat4 invViewMat,
in sampler2D dfgTex,
in samplerCube iblEnvTex,
#ifdef HAS_DUAL_TEXTURE
in samplerCube iblEnvTexSpecular,
#endif
in float iblRoughnessOneLevel,
in float iblLuminance,
inout vec3 color)
Expand All @@ -67,9 +74,16 @@ void evaluateIBL(inout PixelParams pixel,
shading_normal = normalize(mul(invViewMat, vec4(shading_normal, 0.0)).xyz);

// specular layer
#ifdef HAS_DUAL_TEXTURE
//Use dedicated specular texture, iblEnvTex should be diffuse irradiance.
vec3 Fr = E * prefilteredRadiance(iblEnvTexSpecular, r, pixel.perceptualRoughness, iblRoughnessOneLevel);
vec3 diffuseIrradiance = IrradianceMap(iblEnvTex, shading_normal);
#else
//Old behaviour
vec3 Fr = E * prefilteredRadiance(iblEnvTex, r, pixel.perceptualRoughness, iblRoughnessOneLevel);

vec3 diffuseIrradiance = Irradiance_RoughnessOne(iblEnvTex, shading_normal, iblRoughnessOneLevel);
#endif

vec3 Fd = pixel.diffuseColor * diffuseIrradiance * (1.0 - E);

Fr *= iblLuminance;
Expand Down
21 changes: 17 additions & 4 deletions Media/RTShaderLib/SGXLib_CookTorrance.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct PixelParams
vec3 f0;
vec3 dfg;
vec3 energyCompensation;
float ao;
};

float clampNoV(float NoV) {
Expand Down Expand Up @@ -65,6 +66,14 @@ float perceptualRoughnessToRoughness(float perceptualRoughness) {
return perceptualRoughness * perceptualRoughness;
}

// https://github.com/google/filament/blob/7701e7a65afb14c081d2aebbb426c646cc6cb2b9/shaders/src/surface_lighting.fs
float computeMicroShadowing(float NoL, float visibility) {
// Chan 2018, "Material Advances in Call of Duty: WWII"
float aperture = inversesqrt(1.0 - min(visibility, 0.9999));
float microShadow = saturate(NoL * aperture);
return microShadow * microShadow;
}

// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/geometricshadowing(specularg)
float V_SmithGGXCorrelated(float roughness, float NoV, float NoL) {
// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
Expand Down Expand Up @@ -133,7 +142,6 @@ vec3 evaluateLight(

f32vec3 vNormalView = normalize(vNormal);
float NoL = saturate(dot(vNormalView, vLightView));

if(NoL <= 0.0)
return vec3_splat(0.0); // not lit by this light

Expand All @@ -154,8 +162,12 @@ vec3 evaluateLight(
vec3 Fr = (D * V) * F;
vec3 Fd = pixel.diffuseColor * Fd_Lambert();

//Compute AO
float visibility = 1.0;
visibility *= computeMicroShadowing(NoL, pixel.ao);

// https://google.github.io/filament/Filament.md.html#materialsystem/improvingthebrdfs/energylossinspecularreflectance
vec3 color = NoL * lightColor * (Fr * pixel.energyCompensation + Fd);
vec3 color = visibility * NoL * lightColor * (Fr * pixel.energyCompensation + Fd);

color *= getDistanceAttenuation(pointParams.yzw, fLightD);

Expand All @@ -167,9 +179,10 @@ vec3 evaluateLight(
return color;
}

void PBR_MakeParams(in vec3 baseColor, in vec2 mrParam, inout PixelParams pixel)
void PBR_MakeParams(in vec3 baseColor, in vec2 mrParam, in float ao, inout PixelParams pixel)
{
pixel.baseColor = baseColor;
pixel.ao = ao;

float perceptualRoughness = mrParam.x;
// Clamp the roughness to a minimum value to avoid divisions by 0 during lighting
Expand Down Expand Up @@ -233,6 +246,6 @@ void PBR_Lights(
vOutColour += lightVal;
}

vOutColour += pixel.baseColor * pow(ambient.rgb, vec3_splat(2.2));
vOutColour += pixel.baseColor * pow(ambient.rgb, vec3_splat(2.2)) * pixel.ao;
}
#endif
4 changes: 2 additions & 2 deletions RenderSystems/Direct3D11/src/OgreD3D11Mappings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,8 +745,8 @@ namespace Ogre

UINT flags = 0;

if((bindflags & D3D11_BIND_SHADER_RESOURCE) && (bindflags & D3D11_BIND_RENDER_TARGET))
flags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
if((bindflags & D3D11_BIND_SHADER_RESOURCE) && (bindflags & D3D11_BIND_RENDER_TARGET) && (usage & TU_AUTOMIPMAP))
flags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;

if(textype == TEX_TYPE_CUBE_MAP)
flags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
Expand Down