Skip to content

Commit

Permalink
WIP lighting
Browse files Browse the repository at this point in the history
  • Loading branch information
PazerOP committed May 25, 2019
1 parent 056c00c commit 9c7f46b
Show file tree
Hide file tree
Showing 13 changed files with 759 additions and 98 deletions.
152 changes: 152 additions & 0 deletions ShaderDebuggingEnv/ShaderDebuggingEnv.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// ShaderDebuggingEnv.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>

using namespace TF2Vulkan::Shaders;

namespace Env
{
struct
{
float3 color = { 1, 1, 1 };
float1 bIsDirectional = 1;
float3 dir = { 0, 0, -1 };
float1 bIsSpot = 0;
float3 pos = { 0, 0, -2000000 };
float1 falloff = 0;
float3 atten = { 1, 0, 0 };
float1 stopdot1 = 1;
float1 stopdot2 = 1;
float1 OOdot = 1;

} static const cLightInfo[1];

struct
{
float3 x[2];
float3 y[2];
float3 z[2];

} static const cAmbientCube;

static constexpr int g_nLightCount = std::size(cLightInfo);

// The following "internal" routines are called "privately" by other routines in this file which
// handle the particular flavor of vs20 control flow appropriate to the original caller
float VertexAttenInternal(const float3 worldPos, int lightNum)
{
float result = 0.0f;

// Get light direction
float3 lightDir = cLightInfo[lightNum].pos - worldPos;

// Get light distance squared.
float lightDistSquared = dot(lightDir, lightDir);

// Get 1/lightDistance
float ooLightDist = rsqrt(lightDistSquared);

// Normalize light direction
lightDir *= ooLightDist;

float3 vDist = (float3)dst(lightDistSquared, ooLightDist);

float flDistanceAtten = 1.0f / dot(cLightInfo[lightNum].atten, vDist);

// Spot attenuation
float flCosTheta = dot(cLightInfo[lightNum].dir, -lightDir);
float flSpotAtten = (flCosTheta - cLightInfo[lightNum].stopdot2) * cLightInfo[lightNum].OOdot;
flSpotAtten = max(0.0001f, flSpotAtten);
flSpotAtten = pow(flSpotAtten, cLightInfo[lightNum].falloff);
flSpotAtten = saturate(flSpotAtten);

// Select between point and spot
float flAtten = lerp(flDistanceAtten, flDistanceAtten * flSpotAtten, cLightInfo[lightNum].bIsSpot);

// Select between above and directional (no attenuation)
result = lerp(flAtten, 1.0f, cLightInfo[lightNum].bIsDirectional);

return result;
}

float CosineTermInternal(const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert)
{
// Calculate light direction assuming this is a point or spot
float3 lightDir = (float3)normalize(cLightInfo[lightNum].pos - worldPos);

// Select the above direction or the one in the structure, based upon light type
lightDir = lerp(lightDir, -cLightInfo[lightNum].dir, cLightInfo[lightNum].bIsDirectional);

// compute N dot L
float NDotL = dot(worldNormal, lightDir);

if (!bHalfLambert)
{
NDotL = max(0.0f, NDotL);
}
else // Half-Lambert
{
NDotL = NDotL * 0.5 + 0.5;
NDotL = NDotL * NDotL;
}
return NDotL;
}

float3 DoLightInternal(const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert)
{
return (cLightInfo[lightNum].color *
CosineTermInternal(worldPos, worldNormal, lightNum, bHalfLambert) *
VertexAttenInternal(worldPos, lightNum));
}

float3 AmbientLight(const float3 worldNormal)
{
float3 nSquared = worldNormal * worldNormal;
int3 isNegative = (worldNormal < 0.0);
float3 linearColor;
linearColor = nSquared.x * cAmbientCube.x[isNegative.x] +
nSquared.y * cAmbientCube.y[isNegative.y] +
nSquared.z * cAmbientCube.z[isNegative.z];
return linearColor;
}

float3 DoLighting(const float3 worldPos, const float3 worldNormal,
const float3 staticLightingColor, const bool bStaticLight,
const bool bDynamicLight, bool bHalfLambert)
{
float3 linearColor = float3(0.0f, 0.0f, 0.0f);

#if false
if (bStaticLight) // Static light
{
float3 col = staticLightingColor * cOverbright;
linearColor += GammaToLinear(col);
}
#endif

if (bDynamicLight) // Dynamic light
{
for (int i = 0; i < g_nLightCount; i++)
{
linearColor += DoLightInternal(worldPos, worldNormal, i, bHalfLambert);
}
}

if (bDynamicLight)
{
linearColor += AmbientLight(worldNormal); //ambient light is already remapped
}

return linearColor;
}
}

int main()
{
std::cout << "Hello World!\n";

const float3 worldPos(-4.42067, -4.34696, 39.01047);
const float3 worldNormal(-0.91896, 0.02635, 0.39346);
auto result = Env::DoLighting(worldPos, worldNormal, {}, false, true, false);
}
104 changes: 104 additions & 0 deletions ShaderDebuggingEnv/ShaderDebuggingEnv.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{7B521A4D-BB8E-466F-9E8B-EBE3FB1BE919}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>ShaderDebuggingEnv</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="ShaderDebuggingEnv_Shared_Project.props" />
<Import Project="..\TF2VulkanUtil\TF2VulkanUtil_Link.props" />
<Import Project="..\TF2Vulkan_Shared_Solution.props" />
<Import Project="..\TF2Vulkan_Debug_Solution.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="ShaderDebuggingEnv_Shared_Project.props" />
<Import Project="..\TF2VulkanUtil\TF2VulkanUtil_Link.props" />
<Import Project="..\TF2Vulkan_Shared_Solution.props" />
<Import Project="..\TF2Vulkan_Release_Solution.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<ForcedIncludeFiles>$(SolutionDir)shaderapivulkan/include/TF2Vulkan/AlignedTypes.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="ShaderDebuggingEnv.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ShaderFunctions.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
12 changes: 12 additions & 0 deletions ShaderDebuggingEnv/ShaderDebuggingEnv_Shared_Project.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<ForcedIncludeFiles>$(SolutionDir)shaderapivulkan/include/TF2Vulkan/AlignedTypes.h;ShaderFunctions.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
116 changes: 116 additions & 0 deletions ShaderDebuggingEnv/ShaderFunctions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#pragma once

#include <cmath>

#undef min
#undef max

using namespace TF2Vulkan::Shaders;

template<typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
constexpr inline T distance(const T& a, const T& b)
{
return (a > b) ? (a - b) : (b - a);
}

template<typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
constexpr inline T dst(const T& a, const T& b)
{
return distance(a, b);
}

template<typename T, size_t elements>
inline vector<T, elements> dst(const vector<T, elements>& lhs, const vector<T, elements>& rhs)
{
vector<T, elements> retVal;

for (size_t i = 0; i < elements; i++)
retVal[i] = distance(lhs[i], rhs[i]);

return retVal;
}

constexpr inline float lerp(float a, float b, float t)
{
return a + (b - a) * t;
}

inline float rsqrt(float x)
{
return 1.0f / sqrt(x);
}

template<typename T, size_t elements>
inline T dot(const vector<T, elements>& lhs, const vector<T, elements>& rhs)
{
T retVal{};

for (size_t i = 0; i < elements; i++)
retVal += lhs[i] * rhs[i];

return retVal;
}

template<typename TElem, size_t elements, typename TScalar>
inline vector<TElem, elements> lerp(const vector<TElem, elements>& lhs, const vector<TElem, elements>& rhs, const TScalar& scalar)
{
vector<TElem, elements> retVal;

for (size_t i = 0; i < elements; i++)
retVal[i] = lerp(lhs[i], rhs[i], scalar);

return retVal;
}

template<typename T>
constexpr inline T max(const T& a, const T& b)
{
return (a > b) ? a : b;
}

template<typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
constexpr inline T clamp(const T& x, const T& min, const T& max)
{
if (x < min)
return min;

if (x > max)
return max;

return max;
}

template<typename T, size_t elements>
constexpr inline vector<T, elements> clamp(const vector<T, elements>& x, const vector<T, elements>& min, const vector<T, elements>& max)
{
vector<T, elements> retVal;

for (size_t i = 0; i < elements; i++)
retVal[i] = clamp(x[i], min[i], max[i]);

return retVal;
}

template<typename T, size_t elements>
constexpr inline vector<T, elements> saturate(const vector<T, elements>& x)
{
return clamp(x, vector<T, elements>(0), vector<T, elements>(1));
}

template<typename T>
constexpr inline T saturate(const T& x)
{
return clamp(x, (T)0, (T)1);
}

template<typename T, size_t elements>
inline T length(const vector<T, elements>& x)
{
return sqrt(dot(x, x));
}

template<typename T, size_t elements>
inline vector<T, elements> normalize(const vector<T, elements>& x)
{
return x / length(x);
}
Loading

0 comments on commit 9c7f46b

Please sign in to comment.