mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-19 19:35:26 +00:00
Merge branch 'MatInstanceViewer' of https://github.com/Areloch/Torque3D into Preview4_0
Fixed up forward IBL Reimplemented old forward light shader code as a baseline so it can be updated to new PBR math
This commit is contained in:
commit
e5bbd12d4b
19 changed files with 696 additions and 127 deletions
|
|
@ -88,9 +88,121 @@ void compute4Lights( float3 wsView,
|
|||
out float4 outDiffuse,
|
||||
out float4 outSpecular )
|
||||
{
|
||||
// NOTE: The light positions and spotlight directions
|
||||
// are stored in SoA order, so inLightPos[0] is the
|
||||
// x coord for all 4 lights... inLightPos[1] is y... etc.
|
||||
//
|
||||
// This is the key to fully utilizing the vector units and
|
||||
// saving a huge amount of instructions.
|
||||
//
|
||||
// For example this change saved more than 10 instructions
|
||||
// over a simple for loop for each light.
|
||||
|
||||
int i;
|
||||
|
||||
outDiffuse = float4(0,0,0,0);
|
||||
outSpecular = float4(0,0,0,0);
|
||||
float4 lightVectors[3];
|
||||
for ( i = 0; i < 3; i++ )
|
||||
lightVectors[i] = wsPosition[i] - inLightPos[i];
|
||||
|
||||
float4 squareDists = 0;
|
||||
for ( i = 0; i < 3; i++ )
|
||||
squareDists += lightVectors[i] * lightVectors[i];
|
||||
|
||||
// Accumulate the dot product between the light
|
||||
// vector and the normal.
|
||||
//
|
||||
// The normal is negated because it faces away from
|
||||
// the surface and the light faces towards the
|
||||
// surface... this keeps us from needing to flip
|
||||
// the light vector direction which complicates
|
||||
// the spot light calculations.
|
||||
//
|
||||
// We normalize the result a little later.
|
||||
//
|
||||
float4 nDotL = 0;
|
||||
for ( i = 0; i < 3; i++ )
|
||||
nDotL += lightVectors[i] * -wsNormal[i];
|
||||
|
||||
float4 rDotL = 0;
|
||||
#ifndef TORQUE_BL_NOSPECULAR
|
||||
|
||||
// We're using the Phong specular reflection model
|
||||
// here where traditionally Torque has used Blinn-Phong
|
||||
// which has proven to be more accurate to real materials.
|
||||
//
|
||||
// We do so because its cheaper as do not need to
|
||||
// calculate the half angle for all 4 lights.
|
||||
//
|
||||
// Advanced Lighting still uses Blinn-Phong, but the
|
||||
// specular reconstruction it does looks fairly similar
|
||||
// to this.
|
||||
//
|
||||
float3 R = reflect( wsView, -wsNormal );
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
rDotL += lightVectors[i] * R[i];
|
||||
|
||||
#endif
|
||||
|
||||
// Normalize the dots.
|
||||
//
|
||||
// Notice we're using the half type here to get a
|
||||
// much faster sqrt via the rsq_pp instruction at
|
||||
// the loss of some precision.
|
||||
//
|
||||
// Unless we have some extremely large point lights
|
||||
// i don't believe the precision loss will matter.
|
||||
//
|
||||
half4 correction = (half4)rsqrt( squareDists );
|
||||
nDotL = saturate( nDotL * correction );
|
||||
rDotL = clamp( rDotL * correction, 0.00001, 1.0 );
|
||||
|
||||
// First calculate a simple point light linear
|
||||
// attenuation factor.
|
||||
//
|
||||
// If this is a directional light the inverse
|
||||
// radius should be greater than the distance
|
||||
// causing the attenuation to have no affect.
|
||||
//
|
||||
float4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) );
|
||||
|
||||
#ifndef TORQUE_BL_NOSPOTLIGHT
|
||||
|
||||
// The spotlight attenuation factor. This is really
|
||||
// fast for what it does... 6 instructions for 4 spots.
|
||||
|
||||
float4 spotAtten = 0;
|
||||
for ( i = 0; i < 3; i++ )
|
||||
spotAtten += lightVectors[i] * inLightSpotDir[i];
|
||||
|
||||
float4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle;
|
||||
atten *= saturate( cosAngle * inLightSpotFalloff );
|
||||
|
||||
#endif
|
||||
|
||||
// Finally apply the shadow masking on the attenuation.
|
||||
atten *= shadowMask;
|
||||
|
||||
// Get the final light intensity.
|
||||
float4 intensity = nDotL * atten;
|
||||
|
||||
// Combine the light colors for output.
|
||||
outDiffuse = 0;
|
||||
for ( i = 0; i < 4; i++ )
|
||||
outDiffuse += intensity[i] * inLightColor[i];
|
||||
|
||||
// Output the specular power.
|
||||
float4 specularIntensity = pow( rDotL, float4(1,1,1,1) ) * atten;
|
||||
|
||||
// Apply the per-light specular attenuation.
|
||||
float4 specular = float4(0,0,0,1);
|
||||
for ( i = 0; i < 4; i++ )
|
||||
specular += float4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 );
|
||||
|
||||
// Add the final specular intensity values together
|
||||
// using a single dot product operation then get the
|
||||
// final specular lighting color.
|
||||
outSpecular = float4(1,1,1,1) * specular;
|
||||
}
|
||||
|
||||
struct Surface
|
||||
|
|
@ -159,7 +271,7 @@ inline Surface createForwardSurface(float4 baseColor, float3 normal, float4 pbrP
|
|||
surface.V = normalize(wsEyePos - surface.P);
|
||||
surface.baseColor = baseColor;
|
||||
const float minRoughness=1e-4;
|
||||
surface.roughness = clamp(1.0 - pbrProperties.b, minRoughness, 1); //t3d uses smoothness, so we convert to roughness.
|
||||
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;
|
||||
|
|
@ -302,13 +414,13 @@ float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, f
|
|||
}
|
||||
|
||||
float4 computeForwardProbes(Surface surface,
|
||||
float cubeMips, float numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES],
|
||||
float cubeMips, int numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES],
|
||||
float4 inProbePosArray[MAX_FORWARD_PROBES], float4 bbMinArray[MAX_FORWARD_PROBES], float4 bbMaxArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
|
||||
float hasSkylight, TORQUE_SAMPLER2D(BRDFTexture),
|
||||
TORQUE_SAMPLERCUBE(skylightIrradMap), TORQUE_SAMPLERCUBE(skylightSpecularMap),
|
||||
TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR))
|
||||
float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture),
|
||||
TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR))
|
||||
{
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
float alpha = 1;
|
||||
float blendFactor[MAX_FORWARD_PROBES];
|
||||
float blendSum = 0;
|
||||
float blendFacSum = 0;
|
||||
|
|
@ -332,6 +444,8 @@ float4 computeForwardProbes(Surface surface,
|
|||
if (contribution[i] > 0.0)
|
||||
probehits++;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
contribution[i] = max(contribution[i], 0);
|
||||
|
||||
|
|
@ -360,8 +474,43 @@ float4 computeForwardProbes(Surface surface,
|
|||
{
|
||||
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];
|
||||
}
|
||||
|
||||
return float4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1);
|
||||
#endif
|
||||
|
||||
#if DEBUGVIZ_CONTRIB == 1
|
||||
float3 probeContribColors[4];
|
||||
probeContribColors[0] = float3(1,0,0);
|
||||
probeContribColors[1] = float3(0,1,0);
|
||||
probeContribColors[2] = float3(0,0,1);
|
||||
probeContribColors[3] = float3(1,1,0);
|
||||
|
||||
float3 finalContribColor = float3(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
|
||||
if(skylightCubemapIdx != -1)
|
||||
finalContribColor += float3(0.3, 0.3, 0.3) * contribAlpha;
|
||||
|
||||
return float4(finalContribColor, 1);
|
||||
#endif
|
||||
|
||||
float3 irradiance = float3(0, 0, 0);
|
||||
float3 specular = float3(0, 0, 0);
|
||||
|
|
@ -369,7 +518,6 @@ float4 computeForwardProbes(Surface surface,
|
|||
// Radiance (Specular)
|
||||
float lod = surface.roughness*cubeMips;
|
||||
|
||||
float alpha = 1;
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
float contrib = contribution[i];
|
||||
|
|
@ -384,10 +532,10 @@ float4 computeForwardProbes(Surface surface,
|
|||
}
|
||||
}
|
||||
|
||||
if (hasSkylight && alpha > 0.001)
|
||||
if(skylightCubemapIdx != -1 && alpha >= 0.001)
|
||||
{
|
||||
irradiance += TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz;
|
||||
specular = TORQUE_TEXCUBELOD(skylightSpecularMap, float4(surface.R, lod)).xyz;
|
||||
irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.R, skylightCubemapIdx, 0).xyz * alpha;
|
||||
specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, surface.R, skylightCubemapIdx, lod).xyz * alpha;
|
||||
}
|
||||
|
||||
float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
|
||||
|
|
@ -403,7 +551,7 @@ float4 computeForwardProbes(Surface surface,
|
|||
|
||||
//final diffuse color
|
||||
float3 diffuse = kD * irradiance * surface.baseColor.rgb;
|
||||
float4 finalColor = float4(diffuse + specular, 1);
|
||||
//finalColor.rgb += abs(surface.N);
|
||||
float4 finalColor = float4(diffuse + specular * surface.ao, 1.0);
|
||||
|
||||
return finalColor;
|
||||
}
|
||||
|
|
@ -14,11 +14,8 @@ singleton Material(Grid_512_Orange)
|
|||
specularStrength0 = "25";
|
||||
specular0 = "0.8 0.8 0.8 1";
|
||||
specularPower0 = "0.25";
|
||||
emissive[0] = "1";
|
||||
emissive[0] = "0";
|
||||
translucent = "1";
|
||||
normalMap[0] = "data/pbr/images/FloorEbony_normal.png";
|
||||
invertSmoothness[0] = "1";
|
||||
roughMap[0] = "data/pbr/images/FloorEbony_rough.png";
|
||||
aoMap[0] = "data/pbr/images/FloorEbony_ao.png";
|
||||
metalMap[0] = "data/pbr/images/FloorEbony_metal.png";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -269,5 +269,51 @@ new Scene(PbrMatTestLevel) {
|
|||
canSave = "1";
|
||||
canSaveDynamicFields = "1";
|
||||
};
|
||||
new ConvexShape() {
|
||||
Material = "Grid_512_Orange";
|
||||
position = "-0.957664 -2.14584 1.3379";
|
||||
rotation = "1 0 0 0";
|
||||
scale = "1 1 1";
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "1";
|
||||
|
||||
surface = "0 0 0 1 0 0 0.837898 0 0 0 1 1 0 1 1";
|
||||
surface = "0 1 0 0 0 0 -0.837898 0 0 0 1 1 0 1 1";
|
||||
surface = "0.707107 0 0 0.707106 0 0.847632 0 0 0 0 1 1 0 1 1";
|
||||
surface = "0 0.707107 -0.707107 0 0 -0.847632 0 0 0 0 1 1 0 1 1";
|
||||
surface = "0.5 0.5 -0.5 0.5 -0.412576 0 -1.53859e-07 0 0 0 1 1 0 1 1";
|
||||
surface = "0.5 -0.5 0.5 0.5 0.412576 0 -1.53859e-07 0 0 0 1 1 0 1 1";
|
||||
};
|
||||
new PointLight() {
|
||||
radius = "5";
|
||||
isEnabled = "1";
|
||||
color = "1 1 1 1";
|
||||
brightness = "1";
|
||||
castShadows = "0";
|
||||
staticRefreshFreq = "250";
|
||||
dynamicRefreshFreq = "8";
|
||||
priority = "1";
|
||||
animate = "1";
|
||||
animationPeriod = "1";
|
||||
animationPhase = "1";
|
||||
flareScale = "1";
|
||||
attenuationRatio = "0 1 1";
|
||||
shadowType = "DualParaboloidSinglePass";
|
||||
texSize = "512";
|
||||
overDarkFactor = "2000 1000 500 100";
|
||||
shadowDistance = "400";
|
||||
shadowSoftness = "0.15";
|
||||
numSplits = "1";
|
||||
logWeight = "0.91";
|
||||
fadeStartDistance = "0";
|
||||
lastSplitTerrainOnly = "0";
|
||||
representedInLightmap = "0";
|
||||
shadowDarkenColor = "0 0 0 -1";
|
||||
includeLightmappedGeometryInShadow = "0";
|
||||
position = "-0.0881653 -2.35794 1.41582";
|
||||
rotation = "1 0 0 0";
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "1";
|
||||
};
|
||||
};
|
||||
//--- OBJECT WRITE END ---
|
||||
|
|
|
|||
|
|
@ -0,0 +1,170 @@
|
|||
//--- OBJECT WRITE BEGIN ---
|
||||
%guiContent = new GuiControl(MaterialInstanceViewCtrl) {
|
||||
position = "0 0";
|
||||
extent = "1024 768";
|
||||
minExtent = "8 2";
|
||||
horizSizing = "right";
|
||||
vertSizing = "bottom";
|
||||
profile = "GuiDefaultProfile";
|
||||
visible = "1";
|
||||
active = "1";
|
||||
tooltipProfile = "GuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
isContainer = "1";
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "1";
|
||||
|
||||
new GuiWindowCtrl(MaterialInstanceViewWindow) {
|
||||
text = "Material Instances Viewer";
|
||||
resizeWidth = "1";
|
||||
resizeHeight = "1";
|
||||
canMove = "1";
|
||||
canClose = "1";
|
||||
canMinimize = "1";
|
||||
canMaximize = "1";
|
||||
canCollapse = "0";
|
||||
closeCommand = "Canvas.popDialog(MaterialInstanceViewCtrl);";
|
||||
edgeSnap = "1";
|
||||
margin = "0 0 0 0";
|
||||
padding = "0 0 0 0";
|
||||
anchorTop = "1";
|
||||
anchorBottom = "0";
|
||||
anchorLeft = "1";
|
||||
anchorRight = "0";
|
||||
position = "429 123";
|
||||
extent = "550 550";
|
||||
minExtent = "8 2";
|
||||
horizSizing = "right";
|
||||
vertSizing = "bottom";
|
||||
profile = "ToolsGuiWindowProfile";
|
||||
visible = "1";
|
||||
active = "1";
|
||||
tooltipProfile = "GuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
isContainer = "1";
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "0";
|
||||
|
||||
new GuiTextEditCtrl(MaterialInstanceFilter) {
|
||||
historySize = "0";
|
||||
tabComplete = "0";
|
||||
sinkAllKeyEvents = "0";
|
||||
password = "0";
|
||||
passwordMask = "*";
|
||||
text = "\c2Filter...";
|
||||
maxLength = "1024";
|
||||
margin = "0 0 0 0";
|
||||
padding = "0 0 0 0";
|
||||
anchorTop = "1";
|
||||
anchorBottom = "0";
|
||||
anchorLeft = "1";
|
||||
anchorRight = "0";
|
||||
position = "11 21";
|
||||
extent = "516 18";
|
||||
minExtent = "8 2";
|
||||
horizSizing = "width";
|
||||
vertSizing = "bottom";
|
||||
profile = "ToolsGuiTextEditProfile";
|
||||
visible = "1";
|
||||
active = "1";
|
||||
tooltipProfile = "GuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
isContainer = "1";
|
||||
class = "AssetBrowserSearchFilterText";
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
new GuiBitmapButtonCtrl(MaterialInstanceFilterBtn) {
|
||||
bitmap = "tools/gui/images/delete";
|
||||
bitmapMode = "Stretched";
|
||||
autoFitExtents = "0";
|
||||
useModifiers = "0";
|
||||
useStates = "1";
|
||||
masked = "0";
|
||||
groupNum = "-1";
|
||||
buttonType = "PushButton";
|
||||
useMouseEvents = "0";
|
||||
position = "529 22";
|
||||
extent = "15 15";
|
||||
minExtent = "8 2";
|
||||
horizSizing = "left";
|
||||
vertSizing = "bottom";
|
||||
profile = "ToolsGuiDefaultProfile";
|
||||
visible = "1";
|
||||
active = "1";
|
||||
tooltipProfile = "GuiToolTipProfile";
|
||||
tooltip = "Delete Asset";
|
||||
hovertime = "1000";
|
||||
isContainer = "0";
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
new GuiScrollCtrl() {
|
||||
willFirstRespond = "1";
|
||||
hScrollBar = "dynamic";
|
||||
vScrollBar = "dynamic";
|
||||
lockHorizScroll = "0";
|
||||
lockVertScroll = "0";
|
||||
constantThumbHeight = "0";
|
||||
childMargin = "0 0";
|
||||
mouseWheelScrollSpeed = "-1";
|
||||
margin = "0 0 0 0";
|
||||
padding = "0 0 0 0";
|
||||
anchorTop = "1";
|
||||
anchorBottom = "0";
|
||||
anchorLeft = "1";
|
||||
anchorRight = "0";
|
||||
position = "0 38";
|
||||
extent = "550 510";
|
||||
minExtent = "8 2";
|
||||
horizSizing = "width";
|
||||
vertSizing = "height";
|
||||
profile = "ToolsGuiScrollProfile";
|
||||
visible = "1";
|
||||
active = "1";
|
||||
tooltipProfile = "GuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
isContainer = "1";
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "0";
|
||||
|
||||
new GuiTreeViewCtrl(MaterialInstanceViewTree) {
|
||||
tabSize = "16";
|
||||
textOffset = "2";
|
||||
fullRowSelect = "0";
|
||||
itemHeight = "21";
|
||||
destroyTreeOnSleep = "1";
|
||||
mouseDragging = "1";
|
||||
multipleSelections = "1";
|
||||
deleteObjectAllowed = "1";
|
||||
dragToItemAllowed = "1";
|
||||
clearAllOnSingleSelection = "1";
|
||||
showRoot = "1";
|
||||
useInspectorTooltips = "0";
|
||||
tooltipOnWidthOnly = "0";
|
||||
showObjectIds = "1";
|
||||
showClassNames = "1";
|
||||
showObjectNames = "1";
|
||||
showInternalNames = "1";
|
||||
showClassNameForUnnamedObjects = "0";
|
||||
compareToObjectID = "1";
|
||||
canRenameObjects = "1";
|
||||
renameInternal = "0";
|
||||
position = "1 1";
|
||||
extent = "550 510";
|
||||
minExtent = "8 2";
|
||||
horizSizing = "width";
|
||||
vertSizing = "height";
|
||||
profile = "ToolsGuiTreeViewProfile";
|
||||
visible = "1";
|
||||
active = "1";
|
||||
tooltipProfile = "GuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
isContainer = "1";
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
//--- OBJECT WRITE END ---
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
function MaterialInstanceFilter::onGainFirstResponder( %this )
|
||||
{
|
||||
%this.selectAllText();
|
||||
}
|
||||
|
||||
function MaterialInstanceFilter::onReturn( %this )
|
||||
{
|
||||
%text = %this.getText();
|
||||
if( %text $= "" )
|
||||
{
|
||||
%this.reset();
|
||||
MaterialInstanceViewTree.clearFilterText();
|
||||
}
|
||||
else
|
||||
{
|
||||
MaterialInstanceViewTree.setFilterText(%text);
|
||||
}
|
||||
|
||||
MaterialInstanceViewTree.buildVisibleTree(true);
|
||||
}
|
||||
|
||||
function MaterialInstanceFilterBtn::onClick(%this)
|
||||
{
|
||||
MaterialInstanceFilter.reset();
|
||||
MaterialInstanceViewTree.clearFilterText();
|
||||
MaterialInstanceViewTree.buildVisibleTree(true);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue