This commit is contained in:
Areloch 2019-04-15 23:11:18 -05:00
parent c025760422
commit 000c7b2263
21 changed files with 4102 additions and 108 deletions

View file

@ -36,6 +36,11 @@ singleton Material( Grid512_Blue_Mat )
metalness[0] = "0.803922";
translucent = "1";
translucentBlendOp = "Add";
normalMap[0] = "art/pbr/floor/FloorEbony_normal.png";
invertSmoothness[0] = "1";
roughMap[0] = "art/pbr/floor/FloorEbony_rough.png";
aoMap[0] = "art/pbr/floor/FloorEbony_ao.png";
metalMap[0] = "art/pbr/floor/FloorEbony_metal.png";
};
singleton Material( Grid512_ForestGreen_Mat )

View file

@ -310,15 +310,17 @@ singleton ShaderData( PFX_ReflectionProbeArray )
DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl";
DXPixelShaderFile = "shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl";
//OGLVertexShaderFile = "shaders/common/postFx/gl//postFxV.glsl";
//OGLPixelShaderFile = "shaders/common/postFx/gl/passthruP.glsl";
OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.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";
samplerNames[4] = "$specularCubemapAR";
samplerNames[5] = "$irradianceCubemapAR";
samplerNames[6] = "$skylightSpecularMap";
samplerNames[7] = "$skylightIrradMap";
pixVersion = 2.0;
};

View file

@ -99,18 +99,17 @@ new SimGroup(MissionGroup) {
};
new Skylight(theSkyLight) {
enabled = "1";
ProbeShape = "Box";
radius = "10";
posOffset = "0 0 0";
ReflectionMode = "Baked Cubemap";
reflectionPath = "levels/Timmy Test/probes/";
Bake = "0";
position = "8.74661 10.1457 2.48852";
position = "8.74661 10.1457 2.94337";
rotation = "1 0 0 0";
scale = "1 1 1";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "247d7009-db8a-11e8-87b8-ed691a78e155";
posOffset = "0 0 0";
ProbeShape = "Box";
radius = "10";
reflectionPath = "levels/Timmy Test/probes/";
scale = "1 1 1";
};
new TSStatic() {
shapeName = "art/shapes/material_ball/material_ball.dae";
@ -351,5 +350,33 @@ new SimGroup(MissionGroup) {
canSave = "1";
canSaveDynamicFields = "1";
};
new ConvexShape() {
Material = "Grid512_Blue_Mat";
position = "-6.41329 13.7734 2.12278";
rotation = "0 0 1 3.19212";
scale = "1 1 1";
canSave = "1";
canSaveDynamicFields = "1";
surface = "0 0 0 1 0 0 0.384079";
surface = "0 1 0 0 0 0 -0.384079";
surface = "0.707107 0 0 0.707107 0 0.285194 0";
surface = "0 0.707107 -0.707107 0 0 -0.285194 -1.42109e-14";
surface = "0.5 0.5 -0.5 0.5 -0.758333 0 -1.07696e-07";
surface = "0.5 -0.5 0.5 0.5 0.758333 0 -1.07696e-07";
};
new BoxEnvironmentProbe() {
enabled = "0";
refOffset = "0 0 0";
refScale = "10 10 10";
ReflectionMode = "Baked Cubemap";
position = "-11.7544 15.2634 4.67576";
rotation = "1 0 0 0";
scale = "10 10 10";
canSave = "1";
canSaveDynamicFields = "1";
persistentId = "8c7e1f23-5f1c-11e9-8089-c88cdaba85a3";
attenuation = "1";
};
};
//--- OBJECT WRITE END ---

View file

@ -44,6 +44,9 @@ uniform vec4 albedo;
#endif // !TORQUE_SHADERGEN
#define MAX_PROBES 50
#define MAX_FORWARD_PROBES 4
vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane )
{
float denum = dot( plane.xyz, direction.xyz );
@ -119,15 +122,15 @@ void Surface::Update()
F = F_Schlick(f0, f90, NdotV);
}
Surface createSurface(vec4 gbuffer0, sampler2D gbufferTex1, sampler2D gbufferTex2, in vec2 uv, in vec3 wsEyePos, in vec3 wsEyeRay, in mat4 invView)
Surface createSurface(vec4 normDepth, sampler2D colorBuffer, sampler2D matInfoBuffer, in vec2 uv, in vec3 wsEyePos, in vec3 wsEyeRay, in mat4 invView)
{
Surface surface;// = Surface();
vec4 gbuffer1 = texture(gbufferTex1, uv);
vec4 gbuffer2 = texture(gbufferTex2, uv);
surface.depth = gbuffer0.a;
vec4 gbuffer1 = texture(colorBuffer, uv);
vec4 gbuffer2 = texture(matInfoBuffer, uv);
surface.depth = normDepth.a;
surface.P = wsEyePos + wsEyeRay * surface.depth;
surface.N = tMul(invView, vec4(gbuffer0.xyz,0)).xyz; //TODO move t3d to use WS normals
surface.N = tMul(invView, vec4(normDepth.xyz,0)).xyz; //TODO move t3d to use WS normals
surface.V = normalize(wsEyePos - surface.P);
surface.baseColor = gbuffer1;
const float minRoughness=1e-4;
@ -266,4 +269,158 @@ vec3 directSpecular(vec3 N, vec3 V, vec3 L, float roughness, float F0)
float specular = dotNL * D * F * vis;
return vec3(specular,specular,specular);
}
}
//Probe IBL stuff
float defineSphereSpaceInfluence(vec3 wsPosition, vec3 wsProbePosition, float radius)
{
vec3 L = wsProbePosition.xyz - wsPosition;
float contribution = 1.0 - length(L) / radius;
return contribution;
}
float getDistBoxToPoint(vec3 pt, vec3 extents)
{
vec3 d = max(max(-extents - pt, 0), pt - extents);
return max(max(d.x, d.y), d.z);
}
float defineBoxSpaceInfluence(vec3 wsPosition, mat4 worldToObj, float attenuation)
{
vec3 surfPosLS = tMul(worldToObj, vec4(wsPosition, 1.0)).xyz;
float atten = 1.0 - attenuation;
float baseVal = 0.25;
float dist = getDistBoxToPoint(surfPosLS, vec3(baseVal, baseVal, baseVal));
return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist));
}
// 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/
vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 bbMin, vec3 bbMax, vec3 refPosition)
{
vec3 RayLS = tMul(worldToObj, vec4(wsReflectVec, 0.0)).xyz;
vec3 PositionLS = tMul(worldToObj, vec4(wsPosition, 1.0)).xyz;
vec3 unit = bbMax.xyz - bbMin.xyz;
vec3 plane1vec = (unit / 2 - PositionLS) / RayLS;
vec3 plane2vec = (-unit / 2 - PositionLS) / RayLS;
vec3 furthestPlane = max(plane1vec, plane2vec);
float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
vec3 posonbox = wsPosition + wsReflectVec * dist;
return posonbox - refPosition.xyz;
}
/*vec4 computeForwardProbes(Surface surface,
float cubeMips, float numProbes, mat4 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)
{
return vec4(0,0,0,1);
int i = 0;
float blendFactor[MAX_FORWARD_PROBES];
float blendSum = 0;
float blendFacSum = 0;
float invBlendSum = 0;
float probehits = 0;
//Set up our struct data
float contribution[MAX_FORWARD_PROBES];
for (i = 0; i < numProbes; ++i)
{
contribution[i] = 0;
if (probeConfigData[i].r == 0) //box
{
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
if (contribution[i] > 0.0)
probehits++;
}
else if (probeConfigData[i].r == 1) //sphere
{
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g);
if (contribution[i] > 0.0)
probehits++;
}
contribution[i] = max(contribution[i], 0);
blendSum += contribution[i];
invBlendSum += (1.0f - contribution[i]);
}
if (probehits > 1.0)
{
for (i = 0; i < numProbes; i++)
{
blendFactor[i] = ((contribution[i] / blendSum)) / probehits;
blendFactor[i] *= ((contribution[i]) / invBlendSum);
blendFactor[i] = saturate(blendFactor[i]);
blendFacSum += blendFactor[i];
}
// Normalize blendVal
if (blendFacSum == 0.0f) // Possible with custom weight
{
blendFacSum = 1.0f;
}
float invBlendSumWeighted = 1.0f / blendFacSum;
for (i = 0; i < numProbes; ++i)
{
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);
// Radiance (Specular)
float lod = surface.roughness*cubeMips;
float alpha = 1;
for (i = 0; i < numProbes; ++i)
{
float contrib = contribution[i];
if (contrib != 0)
{
int cubemapIdx = 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;
specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
alpha -= contrib;
}
}
if (hasSkylight == 1 && alpha > 0.001)
{
irradiance += textureLod(skylightIrradMap, surface.R, 0).xyz * alpha;
specular += textureLod(skylightSpecularMap, surface.R, lod).xyz * alpha;
}
vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
//energy conservation
vec3 kD = 1.0.xxx - 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;
specular *= brdf.x * F + brdf.y;
//final diffuse color
vec3 diffuse = kD * irradiance * surface.baseColor.rgb;
vec4 finalColor = vec4(diffuse + specular * surface.ao, 1.0);
finalColor = vec4(irradiance.rgb,1);
return finalColor;
}*/

View file

@ -1,63 +1,212 @@
//-----------------------------------------------------------------------------
// 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 "../../../gl/hlslCompat.glsl"
#include "../../../postFx/gl/postFx.glsl"
#include "../../../gl/torque.glsl"
#include "shadergen:/autogenConditioners.h"
#include "../../../gl/lighting.glsl"
#include "../../torque.hlsl"
#line 7
struct ConnectData
uniform sampler2D deferredBuffer;
uniform sampler2D colorBuffer;
uniform sampler2D matInfoBuffer;
uniform sampler2D BRDFTexture;
uniform vec4 rtParams0;
uniform vec4 vsFarPlane;
uniform mat4 cameraToWorld;
uniform vec3 eyePosWorld;
//cubemap arrays require all the same size. so shared mips# value
uniform float cubeMips;
uniform float numProbes;
uniform samplerCubeArray specularCubemapAR;
uniform samplerCubeArray irradianceCubemapAR;
uniform vec4 inProbePosArray[MAX_PROBES];
uniform vec4 inRefPosArray[MAX_PROBES];
uniform mat4 worldToObjArray[MAX_PROBES];
uniform vec4 bbMinArray[MAX_PROBES];
uniform vec4 bbMaxArray[MAX_PROBES];
uniform vec4 probeConfigData[MAX_PROBES]; //r,g,b/mode,radius,atten
#if DEBUGVIZ_CONTRIB
uniform vec4 probeContribColors[MAX_PROBES];
#endif
uniform samplerCube skylightSpecularMap;
uniform samplerCube skylightIrradMap;
uniform float hasSkylight;
out vec4 OUT_col;
void main()
{
float4 hpos : TORQUE_POSITION;
float2 uv : TEXCOORD;
};
//unpack normal and linear depth
vec4 normDepth = deferredUncondition(deferredBuffer, IN_uv0.xy);
uniform int face;
//create surface
Surface surface = createSurface(normDepth, colorBuffer, matInfoBuffer, IN_uv0.xy, eyePosWorld, IN_wsEyeRay, cameraToWorld);
TORQUE_UNIFORM_SAMPLERCUBE(environmentMap, 0);
//early out if emissive
if (getFlag(surface.matFlag, 0))
{
discard;
}
float4 main(ConnectData IN) : TORQUE_TARGET0
{
float3 N = getCubeDir(face,IN.uv);
float3 irradiance = 0;
// tangent space calculation from origin point
float3 up = float3(0.0, 0.0, 1.0);
float3 right = cross(up, N);
up = cross(N, right);
float sampleDelta = 0.025;
int nrSamples = 0;
for(float phi = 0.0; phi < M_2PI_F; phi += sampleDelta)
{
for(float theta = 0.0; theta < M_HALFPI_F; theta += sampleDelta)
{
// spherical to cartesian (in tangent space)
float3 tangentSample = float3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
// tangent space to world
float3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N;
float alpha = 1;
irradiance += TORQUE_TEXCUBE(environmentMap, sampleVec).rgb * cos(theta) * sin(theta);
nrSamples++;
}
}
irradiance = M_PI_F * irradiance * (1.0 / float(nrSamples));
return float4(irradiance, 1.0);
}
int i = 0;
float blendFactor[MAX_PROBES];
float blendSum = 0;
float blendFacSum = 0;
float invBlendSum = 0;
float probehits = 0;
//Set up our struct data
float contribution[MAX_PROBES];
if (alpha > 0)
{
//Process prooooobes
for (i = 0; i < numProbes; ++i)
{
contribution[i] = 0;
if (probeConfigData[i].r == 0) //box
{
contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
if (contribution[i]>0.0)
probehits++;
}
else if (probeConfigData[i].r == 1) //sphere
{
contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g);
if (contribution[i]>0.0)
probehits++;
}
contribution[i] = max(contribution[i],0);
blendSum += contribution[i];
invBlendSum += (1.0f - contribution[i]);
}
// 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.
if (probehits>1.0)
{
for (i = 0; i < numProbes; i++)
{
blendFactor[i] = ((contribution[i] / blendSum)) / probehits;
blendFactor[i] *= ((contribution[i]) / invBlendSum);
blendFactor[i] = saturate(blendFactor[i]);
blendFacSum += blendFactor[i];
}
// Normalize blendVal
#if DEBUGVIZ_ATTENUATION == 0 //this can likely be removed when we fix the above normalization behavior
if (blendFacSum == 0.0f) // Possible with custom weight
{
blendFacSum = 1.0f;
}
#endif
float invBlendSumWeighted = 1.0f / blendFacSum;
for (i = 0; i < numProbes; ++i)
{
blendFactor[i] *= invBlendSumWeighted;
contribution[i] *= blendFactor[i];
alpha -= contribution[i];
}
}
else
alpha -= blendSum;
#if DEBUGVIZ_ATTENUATION == 1
float contribAlpha = 1;
for (i = 0; i < numProbes; ++i)
{
contribAlpha -= contribution[i];
}
OUT_col = vec4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1);
return;
#endif
#if DEBUGVIZ_CONTRIB == 1
vec3 finalContribColor = vec3(0, 0, 0);
float contribAlpha = 1;
for (i = 0; i < numProbes; ++i)
{
finalContribColor += contribution[i] *probeContribColors[i].rgb;
contribAlpha -= contribution[i];
}
//Skylight coloration for anything not covered by probes above
finalContribColor += vec3(0.3, 0.3, 0.3) * contribAlpha;
OUT_col = vec4(finalContribColor, 1);
return;
#endif
}
vec3 irradiance = vec3(0, 0, 0);
vec3 specular = vec3(0, 0, 0);
// Radiance (Specular)
#if DEBUGVIZ_SPECCUBEMAP == 0
float lod = surface.roughness*cubeMips;
#elif DEBUGVIZ_SPECCUBEMAP == 1
float lod = 0;
#endif
alpha = 1;
for (i = 0; i < numProbes; ++i)
{
float contrib = contribution[i];
if (contrib != 0)
{
float cubemapIdx = 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;
//specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
irradiance += vec3(1,1,1) * contrib;
specular += vec3(1,1,1) * contrib;
alpha -= contrib;
}
}
if (hasSkylight == 1 && alpha > 0.001)
{
irradiance += textureLod(skylightIrradMap, surface.R, 0).xyz * alpha;
specular += textureLod(skylightSpecularMap, surface.R, lod).xyz * alpha;
}
#if DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0
OUT_col = vec4(specular, 1);
return;
#elif DEBUGVIZ_DIFFCUBEMAP == 1
OUT_col = vec4(irradiance, 1);
return;
#endif
vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
//energy conservation
vec3 kD = vec3(1,1,1) - 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;
specular *= brdf.x * F + brdf.y;
//final diffuse color
vec3 diffuse = kD * irradiance * surface.baseColor.rgb;
vec4 finalColor = vec4(diffuse + specular * surface.ao, 1.0);
OUT_col = finalColor;
}