Skip to content
Permalink
Browse files

Slight refresh with a few additions from BAR. Enabled SunChanged to c…

…ontrol the sun color and shadow density. This is blind change. Please test if it works correctly and report back if it does not.
  • Loading branch information...
lhog committed Mar 15, 2019
1 parent 90f3b3e commit 0fa47ba724bbc86756d84ee8bbe16dff9b31f58f
@@ -1,22 +1,23 @@
local GL_RG16F = 0x822F
local GL_COLOR_ATTACHMENT0_EXT = 0x8CE0

local function new(class, textureSize)
local function new(class, textureSize, gOption)
return setmetatable(
{
gOption = math.min(math.max(gOption or 3, 1), 4), --clamp between 1 and 3
textureSize = textureSize or 512,
brdfShader = nil,
brdfTexture = nil,
brdfFBO = nil,
}, class)
end

local genBrdfLut = setmetatable({}, {
local GenBrdfLut = setmetatable({}, {
__call = function(self, ...) return new(self, ...) end,
})
genBrdfLut.__index = genBrdfLut
GenBrdfLut.__index = GenBrdfLut

function genBrdfLut:Initialize()
function GenBrdfLut:Initialize()
self.brdfTexture = gl.CreateTexture(self.textureSize, self.textureSize, {
format = GL_RG16F,
border = false,
@@ -27,7 +28,7 @@ function genBrdfLut:Initialize()
})

if not self.brdfTexture then
Spring.Echo("genBrdfLut: [%s] brdfTexture creation error:\n%s")
Spring.Echo("GenBrdfLut: [%s] brdfTexture creation error:\n%s")
end

self.brdfFBO = gl.CreateFBO({
@@ -36,12 +37,15 @@ function genBrdfLut:Initialize()
})

if not self.brdfFBO then
Spring.Echo("genBrdfLut: [%s] FBO creation error:\n%s")
Spring.Echo("GenBrdfLut: [%s] FBO creation error:\n%s")
end

local fragCode = VFS.LoadFile("Luarules/Gadgets/Shaders/GenBrdfLut.frag")
fragCode = fragCode:gsub("###G_OPTION###", tostring(self.gOption))

self.brdfShader = gl.CreateShader({
vertex = VFS.LoadFile("ModelMaterials/Shaders/genBrdfLut.vert"),
fragment = VFS.LoadFile("ModelMaterials/Shaders/genBrdfLut.frag"),
vertex = VFS.LoadFile("Luarules/Gadgets/Shaders/GenBrdfLut.vert"),
fragment = fragCode,
uniformInt = {
texSize = {self.textureSize, self.textureSize},
},
@@ -50,39 +54,41 @@ function genBrdfLut:Initialize()
local shLog = gl.GetShaderLog() or ""

if not self.brdfShader then
Spring.Echo(string.format("genBrdfLut: [%s] shader errors:\n%s", "genBrdfLut", shLog))
Spring.Echo(string.format("GenBrdfLut: [%s] shader errors:\n%s", "GenBrdfLut", shLog))
return false
elseif shLog ~= "" then
Spring.Echo(string.format("genBrdfLut: [%s] shader warnings:\n%s", "genBrdfLut", shLog))
Spring.Echo(string.format("GenBrdfLut: [%s] shader warnings:\n%s", "GenBrdfLut", shLog))
end
end

function genBrdfLut:GetTexture()
function GenBrdfLut:GetTexture()
return self.brdfTexture
end

function genBrdfLut:Execute(isScreenSpace)
function GenBrdfLut:Execute(saveDebug)
if gl.IsValidFBO(self.brdfFBO) then
gl.ActiveShader(self.brdfShader, function ()
gl.ActiveFBO(self.brdfFBO, function()
gl.DepthTest(false)
gl.Blending(false)
if isScreenSpace then
gl.TexRect(0, 0, self.textureSize, self.textureSize)
else
gl.PushPopMatrix(function()
gl.MatrixMode(GL.PROJECTION); gl.LoadIdentity();
gl.MatrixMode(GL.MODELVIEW); gl.LoadIdentity();
gl.TexRect(-1, -1, 1, 1)
end)
if saveDebug then
local gf = Spring.GetGameFrame()
gl.SaveImage( 0, 0, self.textureSize, self.textureSize, string.format("brdf_%s.png", gf))
end
--gl.SaveImage( 0, 0, self.textureSize, self.textureSize, string.format("brdf_%s.png", select(1, Spring.GetGameFrame())) )
end)
end)
end
end


function genBrdfLut:Finalize()
function GenBrdfLut:Finalize()
gl.DeleteFBO(self.brdfFBO)
gl.DeleteTexture(self.brdfTexture)
gl.DeleteShader(self.brdfShader)
end

return genBrdfLut
return GenBrdfLut
@@ -7,19 +7,17 @@ uniform vec2 texSize;

//https://www.shadertoy.com/view/4djSRW
// Hash without Sine
#define HASHSCALE1 .1031
#define HASHSCALE1 443.8975

//----------------------------------------------------------------------------------------
// 1 out, 2 in...
float hash12(vec2 p)
{
float hash12(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * HASHSCALE1);
p3 += dot(p3, p3.yzx + 19.19);
return fract((p3.x + p3.y) * p3.z);
}

vec2 hammersley2d(uint i, uint N)
{
vec2 hammersley2d(uint i, uint N) {
// Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
uint bits = (i << 16u) | (i >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
@@ -33,8 +31,7 @@ vec2 hammersley2d(uint i, uint N)
#define RESTRICT_BRANCHING

// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
{
vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal) {
// Maps a 2D point to a hemisphere with spread based on roughness
float alpha = roughness * roughness;
float phi = 2.0 * M_PI * Xi.x + hash12(normal.xz) * 0.1;
@@ -55,11 +52,10 @@ vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
}

#define G_OPTION 3
#define G_OPTION ###G_OPTION###

// Geometric Shadowing function
float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
{
float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) {
#if (G_OPTION == 1)
float k = (roughness * roughness) / 2.0;
#elif (G_OPTION == 2)
@@ -77,8 +73,7 @@ float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
return GL * GV;
}

vec2 BRDF(float NoV, float roughness)
{
vec2 BRDF(float NoV, float roughness) {
// Normal always points along z-axis for the 2D lookup
const vec3 N = vec3(0.0, 0.0, 1.0);
vec3 V = vec3(sqrt(1.0 - NoV * NoV), 0.0, NoV); //normalized
@@ -116,5 +111,4 @@ void main() {
//NdotV, roughness
vec2 inUV = gl_FragCoord.xy / texSize;
gl_FragColor = vec4(BRDF(inUV.x, 1.0 - inUV.y), 0.0, 1.0);
//gl_FragColor = pow(gl_FragColor, vec4(2.2));
}
@@ -1,5 +1,5 @@
#version 150 compatibility

void main() {
gl_Position = ftransform();
gl_Position = gl_Vertex;
}
@@ -57,6 +57,8 @@ local shadows = false
local advShading = false
local normalmapping = false

local sunChanged = false

local unitRendering = {
drawList = {},
materialInfos = {},
@@ -419,6 +421,11 @@ function gadget:Update()
end
end


function gadget:SunChanged()
sunChanged = true
end

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

@@ -478,6 +485,46 @@ local function ObjectDestroyed(rendering, objectID, objectDefID)
end
end

function gadget:DrawGenesis()
if sunChanged then
for _, mat in pairs(unitRendering.materialDefs) do
local SunChangedFunc = mat.SunChanged

if mat.standardShader and SunChangedFunc then
gl.ActiveShader(mat.standardShader, function()
SunChangedFunc(mat.standardShader)
end)
end

if mat.deferredShader and SunChangedFunc then
gl.ActiveShader(mat.deferredShader, function()
SunChangedFunc(mat.deferredShader)
end)
end

end

for _, mat in pairs(featureRendering.materialDefs) do
local SunChangedFunc = mat.SunChanged

if mat.standardShader and SunChangedFunc then
gl.ActiveShader(mat.standardShader, function()
SunChangedFunc(mat.standardShader)
end)
end

if mat.deferredShader and SunChangedFunc then
gl.ActiveShader(mat.deferredShader, function()
SunChangedFunc(mat.deferredShader)
end)
end

end

sunChanged = false
end
end

function gadget:RenderUnitDestroyed(unitID, unitDefID)
ObjectDestroyed(unitRendering, unitID, unitDefID)
end
@@ -0,0 +1,50 @@
function gadget:GetInfo()
return {
name = "PBR enabler",
desc = "Generates BRDF Lookup table for PBR shaders and sets necessary spring configuration parameters",
author = "ivand",
date = "2019",
license = "PD",
layer = -1,
enabled = true,
}
end

if (not gadgetHandler:IsSyncedCode()) then --unsynced gadget
local genLut

local BRDFLUT_TEXDIM = 512 --512 is BRDF LUT texture resolution
local BRDFLUT_GOPTION = 3

local function GetBrdfTexture()
return genLut:GetTexture()
end

function gadget:DrawGenesis()
if genLut then
genLut:Execute(false)
end
gadgetHandler:RemoveCallIn("DrawGenesis")
end

function gadget:Initialize()
Spring.SetConfigInt("CubeTexGenerateMipMaps", 1)
Spring.SetConfigInt("CubeTexSizeReflection", 2048)
local genLutClass = VFS.Include("Luarules/Gadgets/Include/GenBrdfLut.lua")
if genLutClass then
genLut = genLutClass(BRDFLUT_TEXDIM, BRDFLUT_GOPTION)
if genLut then
genLut:Initialize()
GG.GetBrdfTexture = GetBrdfTexture
end
end
end

function gadget:Shutdown()
if genLut then
genLut:Finalize()
GG.GetBrdfTexture = nil
end
end
end

@@ -9,33 +9,10 @@ local mapInfo = VFS.FileExists(MAPSIDE_MAPINFO) and VFS.Include(MAPSIDE_MAPINFO)
local pbrMapRaw = (mapInfo.custom or {}).pbr

-----------===================================-------------
local genBrdfLutClass = VFS.Include("ModelMaterials/Shaders/genBrdfLut.lua")
local BRDFLUT_TEXDIM = 512 --512 is BRDF LUT texture size
local genBrdfLut = genBrdfLutClass(BRDFLUT_TEXDIM)

genBrdfLut:Initialize()
local brdflutTex = genBrdfLut:GetTexture()
local brdflutTexInitialized = false

genBrdfLut.scream = Script.CreateScream()
genBrdfLut.scream.func = function()
genBrdfLut:Finalize()
brdflutTex = nil
end
-----------===================================-------------

local function DrawUnit(unitID, material, drawMode)
if drawMode == normalDraw and material.customStandardUniforms then
if brdflutTex and (not brdflutTexInitialized) then
-- Terrible workaround to missing DrawGenesis callin.
gl.PushPopMatrix(function()
gl.MatrixMode(GL.PROJECTION); gl.LoadIdentity();
gl.MatrixMode(GL.MODELVIEW); gl.LoadIdentity();
Spring.Echo("~brdflutTexInitialized")
genBrdfLut:Execute(false)
brdflutTexInitialized = true
end)
end
gl.BlendFuncSeparate(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA, GL.ZERO, GL.ZERO)
local curShader = material.standardShader
for _, uniformData in pairs(material.customStandardUniforms) do
@@ -51,11 +28,17 @@ local function DrawUnit(unitID, material, drawMode)
Spring.Echo(string.format("10_pbr.lua: Wrong shader uniform type (%s) for uniform (%s)", valType, uniformData.name))
end
end
-- TODO: check if this is reqired(it should not be)
local gf = Spring.GetGameFrame()
gl.UniformInt(gl.GetUniformLocation(curShader, "simFrame"), gf)
end
end

local function SunChanged(curShader)
gl.Uniform(gl.GetUniformLocation(curShader, "shadowDensity"), gl.GetSun("shadowDensity" ,"unit"))
gl.Uniform(gl.GetUniformLocation(curShader, "sunColor"), gl.GetSun("diffuse" ,"unit"))
end

local function adler32(str)
local MOD_ADLER = 65521
local a = 1
@@ -488,13 +471,14 @@ local function createNewMatDef(modelNiceName, pbrModel, pbrMap)
[2] = "%TEX2",
[3] = "%TEX3",
--[4] = "%TEX4",
[5] = brdflutTex or "unittextures/brdflutTex.png",
[5] = GG.GetBrdfTexture() or "unittextures/brdflutTex.png",
--[5] = "unittextures/brdflutTex.png",
[6] = "$shadow",
[7] = "%IRRADIANCEMAP", --TODO replace with radiance map!!!
[8] = "%SPECULARMAP",
},
DrawUnit = DrawUnit,
SunChanged = SunChanged,
--UnitCreated = UnitCreated,
--UnitDestroyed = UnitDestroyed,

@@ -15,8 +15,8 @@ return {
specularEnvTex = 8,
},
uniformFloat = {
sunColor = {1.0, 1.0, 1.0},
shadowDensity = {gl.GetSun("shadowDensity" ,"unit")},
sunColor = {gl.GetSun("diffuse" ,"unit")},
shadowDensity = gl.GetSun("shadowDensity" ,"unit"),
},
uniformMatrix = {
},

0 comments on commit 0fa47ba

Please sign in to comment.
You can’t perform that action at this time.