port from perforce

This commit is contained in:
2026-04-18 22:31:51 +02:00
commit 8d0ab5b7cc
8409 changed files with 3972376 additions and 0 deletions

View File

@@ -0,0 +1,971 @@
#include <fstream>
#include <string>
#include <atlconv.h>
#include <atlbase.h>
#include <atlstr.h>
#include <sstream>
#include <assert.h>
#include "DXShaderManager.h"
//#include "Util.h"
ShaderManager g_shaderManager;
using namespace Microsoft::WRL;
template <> HRESULT CreateShader<ID3D11VertexShader>(ID3D11Device* pd3dDevice, ID3D11VertexShader** shader, ID3DBlob* pBlob)
{
HRESULT hr;
ID3D11VertexShader* vs = NULL;
V(pd3dDevice->CreateVertexShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(), NULL, &vs ) );
if(FAILED(hr)) {
SAFE_RELEASE(vs);
}
else
{
SAFE_RELEASE(*shader);
*shader = vs;
}
return hr;
};
template <> HRESULT CreateShader<ID3D11DomainShader>(ID3D11Device* pd3dDevice,ID3D11DomainShader** shader, ID3DBlob* pBlob)
{
HRESULT hr;
ID3D11DomainShader* ds = NULL;
V( pd3dDevice->CreateDomainShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(), NULL, &ds ) );
if(FAILED(hr))
{
SAFE_RELEASE(ds);
}
else
{
SAFE_RELEASE(*shader);
*shader = ds;
}
return hr;
};
template <> HRESULT CreateShader<ID3D11HullShader>(ID3D11Device* pd3dDevice, ID3D11HullShader** shader, ID3DBlob* pBlob)
{
HRESULT hr;
ID3D11HullShader* vs = NULL;
V( pd3dDevice->CreateHullShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(), NULL, &vs ) );
if(FAILED(hr))
{
SAFE_RELEASE(vs);
}
else
{
SAFE_RELEASE(*shader);
*shader = vs;
}
return hr;
};
template <> HRESULT CreateShader<ID3D11GeometryShader>(ID3D11Device* pd3dDevice, ID3D11GeometryShader** shader, ID3DBlob* pBlob)
{
HRESULT hr;
ID3D11GeometryShader* vs = NULL;
V( pd3dDevice->CreateGeometryShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(), NULL, &vs ) );
if(FAILED(hr))
{
SAFE_RELEASE(vs);
}
else
{
SAFE_RELEASE(*shader);
*shader = vs;
}
return hr;
};
template <> HRESULT CreateShader<ID3D11PixelShader>(ID3D11Device* pd3dDevice,ID3D11PixelShader** shader, ID3DBlob* pBlob)
{
HRESULT hr;
ID3D11PixelShader* ps = NULL;
V( pd3dDevice->CreatePixelShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(), NULL, &ps ) );
if(FAILED(hr))
{
SAFE_RELEASE(ps);
}
else
{
SAFE_RELEASE(*shader);
*shader = ps;
}
return hr;
};
template <> HRESULT CreateShader<ID3D11ComputeShader>(ID3D11Device* pd3dDevice,ID3D11ComputeShader** shader, ID3DBlob* pBlob)
{
HRESULT hr;
ID3D11ComputeShader* vs = NULL;
V( pd3dDevice->CreateComputeShader( pBlob->GetBufferPointer(),pBlob->GetBufferSize(), NULL, &vs ) );
if(FAILED(hr))
{
SAFE_RELEASE(vs);
}
else
{
SAFE_RELEASE(*shader);
*shader = vs;
}
return hr;
};
template <>
HRESULT CreateShaderStreamOutput<ID3D11VertexShader>(ID3D11Device* pd3dDevice, ID3D11VertexShader** shader, ID3DBlob* pBlob, D3D11_SO_DECLARATION_ENTRY *pSODeclaration, UINT numSOEntries, UINT* pSOStrides, UINT numSOStrides, UINT rasterizerStream )
{
return S_FALSE;
};
template <>
HRESULT CreateShaderStreamOutput<ID3D11HullShader>(ID3D11Device* pd3dDevice, ID3D11HullShader** shader, ID3DBlob* pBlob, D3D11_SO_DECLARATION_ENTRY *pSODeclaration, UINT numSOEntries, UINT* pSOStrides, UINT numSOStrides, UINT rasterizerStream )
{
return S_FALSE;
};
template <>
HRESULT CreateShaderStreamOutput<ID3D11DomainShader>(ID3D11Device* pd3dDevice, ID3D11DomainShader** shader, ID3DBlob* pBlob, D3D11_SO_DECLARATION_ENTRY *pSODeclaration, UINT numSOEntries, UINT* pSOStrides, UINT numSOStrides, UINT rasterizerStream )
{
return S_FALSE;
};
template <>
HRESULT CreateShaderStreamOutput<ID3D11GeometryShader>(ID3D11Device* pd3dDevice, ID3D11GeometryShader** shader, ID3DBlob* pBlob, D3D11_SO_DECLARATION_ENTRY *pSODeclaration, UINT numSOEntries, UINT* pSOStrides, UINT numSOStrides, UINT rasterizerStream )
{
HRESULT hr;
ID3D11GeometryShader* vs = NULL;
V( pd3dDevice->CreateGeometryShaderWithStreamOutput( pBlob->GetBufferPointer(), pBlob->GetBufferSize(),pSODeclaration, numSOEntries, pSOStrides, numSOStrides, rasterizerStream, NULL, &vs) );
if(FAILED(hr))
{
SAFE_RELEASE(vs);
}
else
{
SAFE_RELEASE(*shader);
*shader = vs;
}
return hr;
};
template <>
HRESULT CreateShaderStreamOutput<ID3D11PixelShader>(ID3D11Device* pd3dDevice, ID3D11PixelShader** shader, ID3DBlob* pBlob, D3D11_SO_DECLARATION_ENTRY *pSODeclaration, UINT numSOEntries, UINT* pSOStrides, UINT numSOStrides, UINT rasterizerStream )
{
return S_FALSE;
};
template <>
HRESULT CreateShaderStreamOutput<ID3D11ComputeShader>(ID3D11Device* pd3dDevice, ID3D11ComputeShader** shader, ID3DBlob* pBlob, D3D11_SO_DECLARATION_ENTRY *pSODeclaration, UINT numSOEntries, UINT* pSOStrides, UINT numSOStrides, UINT rasterizerStream )
{
return S_FALSE;
};
#include <d3dcompiler.h>
template <typename T>
HRESULT Shader<T>::CompileShader(ID3D11Device* pd3dDevice, ID3DBlob** ppBlobOut )
{
HRESULT hr = S_OK;
bool srcChanged = false;
const auto& globIncludes = g_shaderManager.GetIncludes();
if(m_compiledInvalid)
{
srcChanged = true;
}
else
{
WatchedFile* shaderSrcFileWatch = globIncludes.find(m_fileNameSrcString)->second;
srcChanged = CompareFileTime(&shaderSrcFileWatch->getLastWrite().ftLastWriteTime, &m_lastChangeCompiled.ftLastWriteTime) > 0;
}
if(srcChanged == false)
{
// check include
if(m_firstLoad) // first run
{
ID3DBlob* srcBlob;
D3DReadFileToBlob(m_fileNameSrc, &srcBlob);
ID3DBlob* codeBlob;
ID3DBlob* errBlob;
// preparse
CShaderInclude includeObj(m_fileNameSrcString.c_str());
D3DPreprocess(srcBlob->GetBufferPointer(),srcBlob->GetBufferSize(),NULL, m_pDefines, &includeObj, &codeBlob, &errBlob);
const std::set<std::string>& includes = includeObj.GetIncludes();
for(auto inclFileName : includes)
{
m_includes.insert(inclFileName);
WatchedFile* currInclude = g_shaderManager.AddIncludeFile(inclFileName);
//std::cout << inclFileName << std::endl;
//exit(0);
}
SAFE_RELEASE(srcBlob);
SAFE_RELEASE(codeBlob);
SAFE_RELEASE(errBlob);
}
// check if includes are newer
for(const auto it : m_includes)
{
WatchedFile* incFile = globIncludes.find(it)->second;
if(CompareFileTime(&incFile->getLastWrite().ftLastWriteTime, &m_lastChangeCompiled.ftLastWriteTime ) > 0)
{
srcChanged = true;
std::cout << "src changed" << std::endl;
break;
}
}
}
if(m_firstLoad == false && srcChanged == false)
return S_OK;
#ifndef _DEBUG
// for nsight shader debugging: compile shaders on first load, then only modified
if(!g_shaderManager.UsePrecompiledShaders())
{
if(m_firstLoad) srcChanged = true;
}
#endif
if(srcChanged)
{
std::cout << "." ;
// make sure sub directories exist
CreateDirectory(ExtractPath(m_fileNameCompiled).c_str(), NULL);
CShaderInclude includeObj(m_fileNameSrcString.c_str());
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
if(!g_shaderManager.UsePrecompiledShaders())
{
// dwShaderFlags |= D3DCOMPILE_WARNINGS_ARE_ERRORS;
}
#if defined( DEBUG ) || defined( _DEBUG )
// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
// Setting this flag improves the shader debugging experience, but still allows
// the shaders to be optimized and to run exactly the way they will run in
// the release configuration of this program.
dwShaderFlags |= D3DCOMPILE_DEBUG;
//dwShaderFlags |= D3DCOMPILE_IEEE_STRICTNESS;
#endif
//dwShaderFlags |= D3DCOMPILE_DEBUG;
dwShaderFlags |= m_compilerFlags;
ID3DBlob* pErrorBlob= NULL;
std::wcout << "Compile: " << m_fileNameSrc << " Entrypoint: " << m_entryPoint << std::endl;
hr = D3DCompileFromFile(m_fileNameSrc, m_pDefines, &includeObj, m_entryPoint, m_shaderModel, dwShaderFlags, 0, ppBlobOut, &pErrorBlob);
if(pErrorBlob != NULL && pErrorBlob->GetBufferPointer() != NULL && pErrorBlob->GetBufferSize() > 0) {
OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
std::cerr << (char*)pErrorBlob->GetBufferPointer() << std::endl;
SAFE_RELEASE( pErrorBlob );
}
if( FAILED(hr) )
{
OutputDebugStringA(m_fileNameCompiled.c_str());
OutputDebugStringA("\n");
OutputDebugStringA("-------------------------------------------------------------------------------\n");
std::cout << "filename " << m_fileNameCompiled << std::endl;
std::cout << "-------------------------------------------------------------------------------" << std::endl;
std::cout << " shader macros: " << std::endl;
if(m_pDefines)
{
for(int numDefs = 0; m_pDefines[numDefs].Name != NULL; ++numDefs)
{
//std::cout << numDefs << ": " << m_pDefines[numDefs].Name << " " << m_pDefines[numDefs].Definition << std::endl;
std::cout << m_pDefines[numDefs].Name << "=" << m_pDefines[numDefs].Definition << std::endl;
}
}
return hr;
}
// regenerate include file list
//m_includes.clear();
const std::set<std::string>& includes = includeObj.GetIncludes();
for(auto inclFileName : includes)
{
m_includes.insert(inclFileName);
WatchedFile* currInclude = g_shaderManager.AddIncludeFile(inclFileName);
}
// write compiled shader to disk
//std::wcout << m_fileNameCompiled << std::endl;
V(D3DWriteBlobToFile(*ppBlobOut, std::wstring(m_fileNameCompiled.begin(), m_fileNameCompiled.end()).c_str(), true));
if(hr!= S_OK)
{
std::cout << "filename " << m_fileNameCompiled << "to long, aborting" << std::endl;
V_RETURN(hr);
exit(1);
}
std::ofstream compiledFile(m_fileNameCompiled.c_str(), std::ios::out | std::ios::binary);
compiledFile.write((char*)(*ppBlobOut)->GetBufferPointer(), (*ppBlobOut)->GetBufferSize());
compiledFile.close();
// unref old shader if one is bound
SAFE_RELEASE(m_shader);
if(m_SONumEntries>0)
{
V(CreateShaderStreamOutput<T>(pd3dDevice, &m_shader, *ppBlobOut, m_SODeclarationArray, m_SONumEntries, m_SOStridesArray, m_SONumStrides, m_rasterizerStream));
}
else
V(CreateShader<T>(pd3dDevice, &m_shader, *ppBlobOut));
HANDLE hFindCompiled = FindFirstFile(m_fileNameCompiled.c_str(), &m_lastChangeCompiled);
if(hFindCompiled != INVALID_HANDLE_VALUE)
m_compiledInvalid = false;
}
else // load pre-compiled shader
{
std::cout << "." ;
std::ifstream compiledFile(m_fileNameCompiled.c_str(), std::ios::in | std::ios::binary);
assert(compiledFile.is_open());
unsigned int size_data = m_lastChangeCompiled.nFileSizeLow;
V(D3DReadFileToBlob(std::wstring(m_fileNameCompiled.begin(), m_fileNameCompiled.end()).c_str(), ppBlobOut));
if(hr!= S_OK)
{
std::cout << "filename " << m_fileNameCompiled << " path to long, aborting" << std::endl;
V_RETURN(hr);
exit(1);
}
//V(D3DCreateBlob(size_data,ppBlobOut));
//compiledFile.read((char*)(*ppBlobOut)->GetBufferPointer(), size_data);
//compiledFile.close();
// unref old shader if one is bound
SAFE_RELEASE(m_shader);
if(m_SONumEntries>0)
{
V(CreateShaderStreamOutput<T>(pd3dDevice, &m_shader, *ppBlobOut, m_SODeclarationArray, m_SONumEntries, m_SOStridesArray, m_SONumStrides, m_rasterizerStream));
}
else
{
V(CreateShader<T>(pd3dDevice, &m_shader, *ppBlobOut));
}
m_compiledInvalid = false;
}
m_firstLoad = false;
return hr;
}
ShaderManager::ShaderManager()
{
m_compiledShaderDirectory = COMPILED_SHADER_DIR;
CreateDirectory(m_compiledShaderDirectory.c_str(), NULL);
m_precompiledShadersEnabled = true;
}
ShaderManager::~ShaderManager()
{
Destroy();
}
Shader<ID3D11VertexShader>* ShaderManager::AddVertexShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines /*= NULL*/, DWORD compilerFlags, const std::vector<int>& configHashes, ID3D11ClassLinkage* pClassLinkage /*= NULL */ )
{
std::string compiledFileName = CreateCompiledFileName( szFileName, szEntryPoint, szShaderModel, pDefines, compilerFlags, configHashes);
// check if shader is cached
auto it = m_vertexShaders.find(compiledFileName);
if(it != m_vertexShaders.end())
{
return it->second;
}
// otherwise load the shader
Shader<ID3D11VertexShader>* shader = new Shader<ID3D11VertexShader>(pd3dDevice, szFileName, szEntryPoint, szShaderModel, VERTEX_SHADER, ppBlobOut, compiledFileName, pDefines, compilerFlags, pClassLinkage);
m_vertexShaders[compiledFileName] = shader;
return shader;
}
Shader<ID3D11HullShader>* ShaderManager::AddHullShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines /*= NULL*/, DWORD compilerFlags, const std::vector<int>& configHashes, ID3D11ClassLinkage* pClassLinkage /*= NULL */ )
{
std::string compiledFileName = CreateCompiledFileName( szFileName, szEntryPoint, szShaderModel, pDefines, compilerFlags, configHashes);
// check if shader is cached
auto it = m_hullShaders.find(compiledFileName);
if(it != m_hullShaders.end())
return it->second;
// otherwise load the shader
Shader<ID3D11HullShader>* shader = new Shader<ID3D11HullShader>(pd3dDevice, szFileName, szEntryPoint, szShaderModel, HULL_SHADER, ppBlobOut, compiledFileName, pDefines, compilerFlags, pClassLinkage);
m_hullShaders[compiledFileName] = shader;
return shader;
}
Shader<ID3D11DomainShader>* ShaderManager::AddDomainShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines /*= NULL*/, DWORD compilerFlags, const std::vector<int>& configHashes, ID3D11ClassLinkage* pClassLinkage /*= NULL */ )
{
std::string compiledFileName = CreateCompiledFileName( szFileName, szEntryPoint, szShaderModel, pDefines, compilerFlags, configHashes);
// check if shader is cached
auto it = m_domainShaders.find(compiledFileName);
if(it != m_domainShaders.end())
return it->second;
// otherwise load the shader
Shader<ID3D11DomainShader>* shader = new Shader<ID3D11DomainShader>(pd3dDevice, szFileName, szEntryPoint, szShaderModel, DOMAIN_SHADER, ppBlobOut, compiledFileName, pDefines, compilerFlags, pClassLinkage);
if(shader->Get() != NULL)
{
m_domainShaders[compiledFileName] = shader;
return shader;
}
else return NULL;
}
Shader<ID3D11GeometryShader>* ShaderManager::AddGeometryShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines /*= NULL*/, DWORD compilerFlags, const std::vector<int>& configHashes, ID3D11ClassLinkage* pClassLinkage /*= NULL */ )
{
std::string compiledFileName = CreateCompiledFileName( szFileName, szEntryPoint, szShaderModel, pDefines, compilerFlags, configHashes);
// check if shader is cached
auto it = m_geometryShaders.find(compiledFileName);
if(it != m_geometryShaders.end())
return it->second;
// otherwise load the shader
Shader<ID3D11GeometryShader>* shader = new Shader<ID3D11GeometryShader>(pd3dDevice, szFileName, szEntryPoint, szShaderModel, GEOMETRY_SHADER, ppBlobOut, compiledFileName, pDefines, compilerFlags, pClassLinkage);
m_geometryShaders[compiledFileName] = shader;
return shader;
}
Shader<ID3D11GeometryShader>* ShaderManager::AddGeometryShaderSO( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines /*= NULL*/, DWORD compilerFlags /*= 0*/, D3D11_SO_DECLARATION_ENTRY *pSODeclaration /*= NULL*/, UINT numSOEntries /*= 0*/, UINT* pSOStrides /*= NULL*/, UINT numSOStrides /*= 0*/, UINT rasterizerStream /*= D3D11_SO_NO_RASTERIZED_STREAM*/, ID3D11ClassLinkage* pClassLinkage /*= NULL*/ )
{
std::string compiledFileName = CreateCompiledFileName( szFileName, szEntryPoint, szShaderModel, pDefines, compilerFlags);
// check if shader is cached
auto it = m_geometryShaders.find(compiledFileName);
if(it != m_geometryShaders.end())
return it->second;
// otherwise load the shader
Shader<ID3D11GeometryShader>* shader = new Shader<ID3D11GeometryShader>(pd3dDevice, szFileName, szEntryPoint, szShaderModel, GEOMETRY_SHADER, ppBlobOut, compiledFileName, pDefines, compilerFlags,
pSODeclaration, numSOEntries, pSOStrides, numSOStrides, rasterizerStream,
pClassLinkage);
m_geometryShaders[compiledFileName] = shader;
return shader;
}
Shader<ID3D11PixelShader>* ShaderManager::AddPixelShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines /*= NULL*/, DWORD compilerFlags, const std::vector<int>& configHashes, ID3D11ClassLinkage* pClassLinkage /*= NULL */ )
{
std::string compiledFileName = CreateCompiledFileName( szFileName, szEntryPoint, szShaderModel, pDefines, compilerFlags, configHashes);
// check if shader is cached
auto it = m_pixelShaders.find(compiledFileName);
if(it != m_pixelShaders.end())
return it->second;
// otherwise load the shader
Shader<ID3D11PixelShader>* shader = new Shader<ID3D11PixelShader>(pd3dDevice, szFileName, szEntryPoint, szShaderModel, PIXEL_SHADER, ppBlobOut, compiledFileName, pDefines, compilerFlags, pClassLinkage);
m_pixelShaders[compiledFileName] = shader;
return shader;
}
Shader<ID3D11ComputeShader>* ShaderManager::AddComputeShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines /*= NULL*/, DWORD compilerFlags, const std::vector<int>& configHashes, ID3D11ClassLinkage* pClassLinkage /*= NULL */ )
{
std::string compiledFileName = CreateCompiledFileName( szFileName, szEntryPoint, szShaderModel, pDefines, compilerFlags, configHashes);
// check if shader is cached
auto it = m_computeShaders.find(compiledFileName);
if(it != m_computeShaders.end())
return it->second;
// otherwise load the shader
Shader<ID3D11ComputeShader>* shader = new Shader<ID3D11ComputeShader>(pd3dDevice, szFileName, szEntryPoint, szShaderModel, COMPUTE_SHADER, ppBlobOut, compiledFileName, pDefines, compilerFlags, pClassLinkage);
m_computeShaders[compiledFileName] = shader;
return shader;
}
HRESULT ShaderManager::CheckAndReload(ID3D11Device* pd3dDevice)
{
HRESULT hr = S_OK;
for(auto& inc : m_includeFiles )
{
inc.second->CheckIsModified();
}
for( const auto& shader : m_vertexShaders) { hr = shader.second->CheckAndReload(pd3dDevice); if(FAILED(hr)) return hr;}
for( const auto& shader : m_hullShaders) { hr = shader.second->CheckAndReload(pd3dDevice); if(FAILED(hr)) return hr;}
for( const auto& shader : m_domainShaders) { hr = shader.second->CheckAndReload(pd3dDevice); if(FAILED(hr)) return hr;}
for( const auto& shader : m_geometryShaders){ hr = shader.second->CheckAndReload(pd3dDevice); if(FAILED(hr)) return hr;}
for( const auto& shader : m_pixelShaders) { hr = shader.second->CheckAndReload(pd3dDevice); if(FAILED(hr)) return hr;}
for( const auto& shader : m_computeShaders) { hr = shader.second->CheckAndReload(pd3dDevice); if(FAILED(hr)) return hr;}
return hr;
}
void ShaderManager::Destroy()
{
for(auto& inc : m_includeFiles)
{
SAFE_DELETE(inc.second);
}
m_includeFiles.clear();
for(auto &shader : m_vertexShaders) delete shader.second;
for(auto &shader : m_domainShaders) delete shader.second;
for(auto &shader : m_hullShaders) delete shader.second;
for(auto &shader : m_geometryShaders) delete shader.second;
for(auto &shader : m_pixelShaders) delete shader.second;
for(auto &shader : m_computeShaders) delete shader.second;
m_vertexShaders.clear();
m_hullShaders.clear();
m_domainShaders.clear();
m_geometryShaders.clear();
m_pixelShaders.clear();
m_computeShaders.clear();
}
//const char* gSystemDir = "..\\Shader";
std::string ShaderManager::CreateCompiledFileName( const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, D3D_SHADER_MACRO* pDefines /*= NULL*/, DWORD compilerFlags /*= 0*/, const std::vector<int>& config_hashes )
{
std::string compiledFileName = m_compiledShaderDirectory;
compiledFileName.append(szFileName);
compiledFileName.append("-");
compiledFileName.append( szEntryPoint );
if(!config_hashes.empty())
{
for(auto hash : config_hashes)
{
std::stringstream ws;
ws << (int)hash;
compiledFileName.append("_");
compiledFileName.append(ws.str().c_str());
}
}
else
{
if(pDefines)
{
compiledFileName.append("-");
for(UINT i = 0; pDefines[i].Name != NULL; ++i)
{
std::string name = pDefines[i].Name;
if(name[0] == L'\"') name[0] = L'x';
if(name[name.length() -1 ] == '\"') name[name.length()-1] = L'x';
std::string def = pDefines[i].Definition;
if(def[0] == L'\"') def[0] = L'x';
if(def[def.length() -1 ] == L'\"') def[def.length()-1] = 'x';
compiledFileName.append(name);
compiledFileName.append("_");
compiledFileName.append(def);
if(pDefines[i+1].Name != NULL)
compiledFileName.append("-");
}
}
}
if(compilerFlags)
{
compiledFileName.append("-");
std::stringstream ss;
ss << compilerFlags;
compiledFileName.append(ss.str());
}
compiledFileName.append(".p");
//std::wcout << compiledFileName.c_str()<< std::endl;
return compiledFileName;
}
WatchedFile* ShaderManager::AddIncludeFile( std::string includeFileName )
{
const auto& it = m_includeFiles.find(includeFileName);
if(it == m_includeFiles.end())
{
WatchedFile* inc = new WatchedFile(includeFileName);
m_includeFiles[includeFileName] = inc;
return inc;
}
else
return it->second;
}
CShaderInclude::CShaderInclude( const char* shaderDir, const char* systemDir )
{
m_ShaderDir = ExtractPath(shaderDir);
m_SystemDir = ExtractPath(systemDir);
}
HRESULT __stdcall CShaderInclude::Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) {
try {
std::string finalPath;
switch(IncludeType) {
case D3D_INCLUDE_LOCAL:
if (m_ShaderDir != std::string(""))
finalPath = m_ShaderDir + "\\" + pFileName;
else
finalPath = pFileName;
break;
case D3D_INCLUDE_SYSTEM:
if (m_SystemDir != std::string(""))
finalPath = m_SystemDir + "\\" + pFileName;
else
finalPath = pFileName;
break;
default:
assert(0);
}
m_includeFiles.insert(finalPath);
//std::cout << finalPath << std::endl;
std::ifstream includeFile(finalPath.c_str(), std::ios::in|std::ios::binary|std::ios::ate);
if (includeFile.is_open()) {
long long fileSize = includeFile.tellg();
char* buf = new char[(unsigned int)fileSize];
includeFile.seekg (0, std::ios::beg);
includeFile.read (buf, fileSize);
includeFile.close();
*ppData = buf;
*pBytes = (unsigned int)fileSize;
} else {
return E_FAIL;
}
return S_OK;
}
catch(std::exception) {
return E_FAIL;
}
}
HRESULT __stdcall CShaderInclude::Close(LPCVOID pData) {
char* buf = (char*)pData;
delete[] buf;
return S_OK;
}
WatchedFile::WatchedFile( const std::string& includeFileName )
{
m_fileName = includeFileName;
HANDLE hFind = FindFirstFile(m_fileName.c_str(), &m_lastWrite);
}
WatchedFile::~WatchedFile()
{
}
bool WatchedFile::CheckIsModified()
{
auto lastWrite = m_lastWrite.ftLastWriteTime;
HANDLE hFind = FindFirstFile(m_fileName.c_str(), &m_lastWrite);
return CompareFileTime(&m_lastWrite.ftLastWriteTime,&lastWrite) > 0;
}
DrawSourceConfig::~DrawSourceConfig()
{
for(auto e: commonShader.defines)
{
e.first.clear();
e.second.clear();
}
for(auto e: vertexShader.defines)
{
e.first.clear();
e.second.clear();
}
for(auto e: hullShader.defines)
{
e.first.clear();
e.second.clear();
}
for(auto e: domainShader.defines)
{
e.first.clear();
e.second.clear();
}
for(auto e: geometryShader.defines)
{
e.first.clear();
e.second.clear();
}
for(auto e: pixelShader.defines)
{
e.first.clear();
e.second.clear();
}
for(auto e: commonShader.defines)
{
e.first.clear();
e.second.clear();
}
commonShader.defines.clear();
computeShader.defines.clear();
vertexShader.defines.clear();
hullShader.defines.clear();
domainShader.defines.clear();
geometryShader.defines.clear();
pixelShader.defines.clear();
}
DrawSourceConfig * DrawRegistryBase::_CreateDrawSourceConfig( DescType const & desc, ID3D11Device * pd3dDevice ) const
{
DrawSourceConfig * sconfig = _NewDrawSourceConfig();
sconfig->vertexShader.target = "vs_5_0";
sconfig->hullShader.target = "hs_5_0";
sconfig->domainShader.target = "ds_5_0";
sconfig->geometryShader.target = "gs_5_0";
sconfig->pixelShader.target = "ps_5_0";
sconfig->computeShader.target = "cs_5_0";
sconfig->vertexShader.sourceFile.clear();
sconfig->hullShader.sourceFile.clear();
sconfig->domainShader.sourceFile.clear();
sconfig->geometryShader.sourceFile.clear();
sconfig->pixelShader.sourceFile.clear();
sconfig->computeShader.sourceFile.clear();
return sconfig;
}
void createDefineMacro(const std::vector< const ShaderDefineVector* >& defvec, std::vector<D3D_SHADER_MACRO>& outDefs)
{
for (int i=0; i<(int)defvec.size(); ++i) {
for(const auto& defI : *defvec[i])
{
const D3D_SHADER_MACRO def = {
defI.first.c_str(),
defI.second.c_str(),
};
outDefs.push_back(def);
}
}
const D3D_SHADER_MACRO zerodef = { 0, 0 };
outDefs.push_back(zerodef);
}
DrawConfig* DrawRegistryBase::_CreateDrawConfig( DescType const & desc, SourceConfigType const * sconfig, ID3D11Device * pd3dDevice, ID3D11InputLayout ** ppInputLayout, D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs, int numInputElements ) const
{
assert(sconfig);
bool debug_shader_build = false;
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#ifdef _DEBUG
dwShaderFlags |= D3DCOMPILE_DEBUG;
debug_shader_build = true;
#else
//dwShaderFlags |= D3DCOMPILE_OPTIMIZATION_LEVEL3;
#endif
ID3DBlob * pBlob = NULL;
Shader<ID3D11VertexShader> *vertexShader = NULL;
if (! sconfig->vertexShader.sourceFile.empty())
{
std::vector<int> config_hashes;
config_hashes.push_back(sconfig->value);
if(debug_shader_build) config_hashes.push_back(1337);
std::vector<const ShaderDefineVector *> fullDefs;
fullDefs.push_back(&sconfig->commonShader.defines);
fullDefs.push_back(&sconfig->vertexShader.defines);
std::vector<D3D_SHADER_MACRO> defs;
createDefineMacro(fullDefs,defs);
vertexShader = g_shaderManager.AddVertexShader(pd3dDevice, sconfig->vertexShader.sourceFile.c_str(), sconfig->vertexShader.entry.c_str(), sconfig->vertexShader.target.c_str(), &pBlob, &defs[0], dwShaderFlags, config_hashes);
fullDefs.clear();
assert(vertexShader->Get());
if (ppInputLayout && !*ppInputLayout) {
pd3dDevice->CreateInputLayout(pInputElementDescs, numInputElements,
pBlob->GetBufferPointer(),
pBlob->GetBufferSize(), ppInputLayout);
assert(ppInputLayout);
}
SAFE_RELEASE(pBlob);
}
Shader<ID3D11HullShader> *hullShader = NULL;
if (! sconfig->hullShader.sourceFile.empty())
{
std::vector<int> config_hashes;
config_hashes.push_back(sconfig->value);
if(debug_shader_build) config_hashes.push_back(1337);
std::vector<const ShaderDefineVector *> fullDefs;
fullDefs.push_back(&sconfig->commonShader.defines);
fullDefs.push_back(&sconfig->hullShader.defines);
std::vector<D3D_SHADER_MACRO> defs;
createDefineMacro(fullDefs,defs);
hullShader = g_shaderManager.AddHullShader(pd3dDevice, sconfig->hullShader.sourceFile.c_str(), sconfig->hullShader.entry.c_str(), sconfig->hullShader.target.c_str(),
&pBlob, &defs[0], dwShaderFlags, config_hashes);
assert(hullShader->Get());
SAFE_RELEASE(pBlob);
}
Shader<ID3D11DomainShader> *domainShader = NULL;
if (! sconfig->domainShader.sourceFile.empty())
{
std::vector<int> config_hashes;
config_hashes.push_back(sconfig->value);
if(debug_shader_build) config_hashes.push_back(1337);
std::vector<const ShaderDefineVector *> fullDefs;
fullDefs.push_back(&sconfig->commonShader.defines);
fullDefs.push_back(&sconfig->domainShader.defines);
std::vector<D3D_SHADER_MACRO> defs;
createDefineMacro(fullDefs, defs);
domainShader = g_shaderManager.AddDomainShader(pd3dDevice, sconfig->domainShader.sourceFile.c_str(), sconfig->domainShader.entry.c_str(), sconfig->domainShader.target.c_str(),
&pBlob, &defs[0], dwShaderFlags, config_hashes);
assert(domainShader->Get());
SAFE_RELEASE(pBlob);
}
Shader<ID3D11GeometryShader> *geometryShader = NULL;
if (! sconfig->geometryShader.sourceFile.empty())
{
std::vector<int> config_hashes;
config_hashes.push_back(sconfig->value);
if(debug_shader_build) config_hashes.push_back(1337);
std::vector<const ShaderDefineVector *> fullDefs;
fullDefs.push_back(&sconfig->commonShader.defines);
fullDefs.push_back(&sconfig->geometryShader.defines);
std::vector<D3D_SHADER_MACRO> defs;
createDefineMacro(fullDefs,defs);
geometryShader = g_shaderManager.AddGeometryShader(pd3dDevice, sconfig->geometryShader.sourceFile.c_str(), sconfig->geometryShader.entry.c_str(), sconfig->geometryShader.target.c_str(),
&pBlob, &defs[0], dwShaderFlags, config_hashes);
assert(geometryShader->Get());
SAFE_RELEASE(pBlob);
}
Shader<ID3D11PixelShader> *pixelShader = NULL;
if (! sconfig->pixelShader.sourceFile.empty())
{
std::vector<int> config_hashes;
config_hashes.push_back(sconfig->value);
if(debug_shader_build) config_hashes.push_back(1337);
std::vector<const ShaderDefineVector *> fullDefs;
fullDefs.push_back(&sconfig->commonShader.defines);
fullDefs.push_back(&sconfig->pixelShader.defines);
std::vector<D3D_SHADER_MACRO> defs;
createDefineMacro(fullDefs,defs);
pixelShader = g_shaderManager.AddPixelShader(pd3dDevice, sconfig->pixelShader.sourceFile.c_str(), sconfig->pixelShader.entry.c_str(), sconfig->pixelShader.target.c_str(),
&pBlob, &defs[0], dwShaderFlags, config_hashes);
assert(pixelShader);
SAFE_RELEASE(pBlob);
}
Shader<ID3D11ComputeShader> *computeShader = NULL;
if (! sconfig->computeShader.sourceFile.empty())
{
std::vector<int> config_hashes;
config_hashes.push_back(sconfig->value);
if(debug_shader_build) config_hashes.push_back(1337);
std::vector<const ShaderDefineVector *> fullDefs;
fullDefs.push_back(&sconfig->commonShader.defines);
fullDefs.push_back(&sconfig->computeShader.defines);
std::vector<D3D_SHADER_MACRO> defs;
createDefineMacro(fullDefs,defs);
computeShader = g_shaderManager.AddComputeShader(pd3dDevice, sconfig->computeShader.sourceFile.c_str(), sconfig->computeShader.entry.c_str(), sconfig->computeShader.target.c_str(),
&pBlob, &defs[0], dwShaderFlags, config_hashes);
assert(computeShader);
SAFE_RELEASE(pBlob);
}
DrawConfig * config = _NewDrawConfig();
config->srcConfig = const_cast<DrawSourceConfig*>(sconfig);
config->vertexShader = vertexShader;
config->hullShader = hullShader;
config->domainShader = domainShader;
config->geometryShader = geometryShader;
config->pixelShader = pixelShader;
config->computeShader = computeShader;
return config;
}

View File

@@ -0,0 +1,595 @@
#pragma once
//#include <DXUT.h>
//#include <SDKMisc.h>
#include <d3d11.h>
#include <wrl.h>
#include <vector>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <string>
#include <map>
#include <set>
#define COMPILED_SHADER_DIR "compiled/"
#ifndef V
#define V(x) { hr = (x); }
#endif
#ifndef V_RETURN
#define V_RETURN(x) { hr = (x); if( FAILED(hr) ) { return hr; } }
#endif
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if (p) { delete (p); (p)=NULL; } }
#endif
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p)=NULL; } }
#endif
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
#endif
enum SHADERTYPE {
VERTEX_SHADER = 1,
HULL_SHADER = 2,
DOMAIN_SHADER = 4,
GEOMETRY_SHADER = 8,
PIXEL_SHADER = 16,
COMPUTE_SHADER = 32,
};
static ULARGE_INTEGER GetFileChangeTime(char* name) {
HANDLE hFile = CreateFile(
name,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
ULARGE_INTEGER create, access, write;
GetFileTime(
hFile,
LPFILETIME(&create),
LPFILETIME(&access),
LPFILETIME(&write)
);
CloseHandle(hFile);
return write;
}
static bool GetAndSetFileChange(char* name, ULARGE_INTEGER& lastWrite) {
ULARGE_INTEGER write = GetFileChangeTime(name);
if ( write.QuadPart > lastWrite.QuadPart ) {
lastWrite = write;
return true;
}
lastWrite = write;
return false;
}
static bool GetFileChange(char* name, ULARGE_INTEGER lastWrite) {
return GetFileChangeTime(name).QuadPart > lastWrite.QuadPart;
}
__forceinline std::string GetFileExt(const std::string& file)
{
size_t found = file.find_last_of(".");
return file.substr(found+1);
}
__forceinline std::string ReplaceFileExtension(const std::string& file, const std::string& ext)
{
size_t found = file.find_last_of(".");
return file.substr(0,found) + ext;
}
__forceinline std::string ExtractPath(const std::string& fname)
{
size_t pos = fname.find_last_of("\\/");
return (std::string::npos == pos) ? "" : fname.substr(0, pos);
}
// custom include handle
class CShaderInclude : public ID3DInclude {
public:
CShaderInclude(const char* shaderDir, const char* systemDir = "");
HRESULT __stdcall Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes);
HRESULT __stdcall Close(LPCVOID pData);
const std::set<std::string>& GetIncludes() const {return m_includeFiles;}
private:
std::string m_ShaderDir;
std::string m_SystemDir;
std::set<std::string> m_includeFiles;
};
//template <typename T> HRESULT createShader(T* tmpShader, ID3DBlob* pBlob, T** shader )
template <typename T> HRESULT CreateShader(ID3D11Device* pd3dDevice, T** shader, ID3DBlob* pBlob)
{
return S_FALSE;
};
template <typename T> HRESULT CreateShaderStreamOutput(ID3D11Device* pd3dDevice, T** shader, ID3DBlob* pBlob, D3D11_SO_DECLARATION_ENTRY *pSODeclaration = NULL, UINT numSOEntries = 0, UINT* pSOStrides = NULL, UINT numSOStrides = 0, UINT rasterizerStream = D3D11_SO_NO_RASTERIZED_STREAM)
{
return S_FALSE;
};
template <typename T>
class Shader
{
public:
// TODO checkme: copy macros and stream output array data as data pointed to may be deleted
Shader(ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, SHADERTYPE shaderType, ID3DBlob** ppBlobOut, std::string& compiledFileName, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, ID3D11ClassLinkage* pClassLinkage = NULL)
{
//HRESULT hr;
/* V( DXUTFindDXSDKMediaFileCch( m_fileNameSrc, MAX_PATH, szFileName ) );
if(FAILED(hr))
{
std::wcout << "cannot find file " << szFileName << std::endl;
return;
}*/
m_fileNameSrcString = szFileName;
wcscpy_s( m_fileNameSrc, std::wstring(m_fileNameSrcString.begin(), m_fileNameSrcString.end()).c_str());
init(szEntryPoint, szShaderModel, shaderType,
compiledFileName, pDefines, compilerFlags,
NULL, 0, NULL, 0, D3D11_SO_NO_RASTERIZED_STREAM,
pClassLinkage);
//m_lastChange.QuadPart = 0;
//GetAndSetFileChange(m_fileNameSrc, m_lastChange);
//m_fileNameSrc;
g_shaderManager.AddIncludeFile(m_fileNameSrcString);
m_compiledInvalid = false;
HANDLE hFindCompiled = FindFirstFile(m_fileNameCompiled.c_str(), &m_lastChangeCompiled);
if(hFindCompiled == INVALID_HANDLE_VALUE) m_compiledInvalid = true;
CompileShader(pd3dDevice, ppBlobOut);
}
// with stream out support
Shader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, SHADERTYPE shaderType, ID3DBlob** ppBlobOut,
std::string& compiledFileName, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0,
D3D11_SO_DECLARATION_ENTRY *pSODeclaration = NULL, UINT numSOEntries = 0, UINT* pSOStrides = NULL, UINT numSOStrides = 0, UINT rasterizerStream = D3D11_SO_NO_RASTERIZED_STREAM,
ID3D11ClassLinkage* pClassLinkage = NULL)
{
//HRESULT hr;
//V( DXUTFindDXSDKMediaFileCch( m_fileNameSrc, MAX_PATH, szFileName ) );
//if(FAILED(hr))
//{
// std::wcout << "cannot find file " << szFileName << std::endl;
// return;
//}
m_fileNameSrcString = szFileName;
wcscpy_s( m_fileNameSrc, std::wstring(m_fileNameSrcString.begin(), m_fileNameSrcString.end()).c_str());
//g_shaderManager->AddIncludeFile(szFileName);
init(szEntryPoint, szShaderModel, shaderType,
compiledFileName, pDefines, compilerFlags,
pSODeclaration, numSOEntries, pSOStrides, numSOStrides, rasterizerStream,
pClassLinkage);
//m_lastChange.QuadPart = 0;
//GetAndSetFileChange(m_fileNameSrc, m_lastChange);
g_shaderManager.AddIncludeFile(m_fileNameSrcString);
m_compiledInvalid = false;
HANDLE hFindCompiled = FindFirstFile(m_fileNameCompiled.c_str(), &m_lastChangeCompiled);
if(hFindCompiled == INVALID_HANDLE_VALUE) m_compiledInvalid = true;
CompileShader(pd3dDevice, ppBlobOut);
}
void init( LPCSTR szEntryPoint, LPCSTR szShaderModel, SHADERTYPE shaderType,
std::string& compiledFileName, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0,
D3D11_SO_DECLARATION_ENTRY *pSODeclaration = NULL, UINT numSOEntries = 0, UINT* pSOStrides = NULL, UINT numSOStrides = 0, UINT rasterizerStream = D3D11_SO_NO_RASTERIZED_STREAM,
ID3D11ClassLinkage* pClassLinkage = NULL)
{
m_shader = NULL;
m_entryPoint = szEntryPoint;
m_shaderModel = szShaderModel;
m_type = shaderType;
m_fileNameCompiled = compiledFileName;
m_pDefines = NULL;
m_classLinkage = pClassLinkage;
m_compilerFlags = compilerFlags;
m_SODeclarationArray = pSODeclaration;
m_SONumEntries = numSOEntries;
m_SOStridesArray = pSOStrides;
m_SONumStrides = numSOStrides;
m_rasterizerStream = rasterizerStream;
m_firstLoad = true;
// copy macros to local for shader reloading
if(pDefines)
{
// count macros
int numDefs = 0;
for(numDefs = 0; pDefines[numDefs].Name != NULL; ++numDefs);
m_pDefines = new D3D_SHADER_MACRO[numDefs+1];
for(int i=0; i < numDefs; ++i)
{
size_t sizeName = strlen(pDefines[i].Name)+1;
size_t sizeDef = strlen(pDefines[i].Definition)+1;
m_pDefines[i].Name = new char[sizeName];
m_pDefines[i].Definition = new char[sizeDef];
memcpy((void*)&(m_pDefines[i].Name[0]), (void*)&(pDefines[i].Name[0]), sizeName);
memcpy((void*)&(m_pDefines[i].Definition[0]), (void*)&(pDefines[i].Definition[0]), sizeDef);
}
m_pDefines[numDefs].Name = NULL;
m_pDefines[numDefs].Definition = NULL;
//for(int i = 0; m_pDefines[i].Name != NULL; ++i)
//{
// std::cout << i << ": " << m_pDefines[i].Name << " " << m_pDefines[i].Definition << std::endl;
//}
}
// TODO copy SO Declaration Array and SOStride Array to local
}
Shader()
{
m_shader = NULL;
}
T* Get() const { return m_shader; }
operator T*() const { return Get(); }
~Shader()
{
Destroy();
}
void Destroy();
HRESULT CheckAndReload(ID3D11Device* pd3dDevice);
private:
HRESULT CompileShader(ID3D11Device* pd3dDevice, ID3DBlob** ppBlobOut);
SHADERTYPE m_type;
wchar_t m_fileNameSrc[MAX_PATH];
std::string m_fileNameSrcString;
std::string m_fileNameCompiled;
LPCSTR m_entryPoint;
LPCSTR m_shaderModel;
D3D_SHADER_MACRO* m_pDefines;
ID3D11ClassLinkage* m_classLinkage;
DWORD m_compilerFlags;
//bool m_isChanged;
//ULARGE_INTEGER m_lastChange;
WIN32_FIND_DATA m_lastChangeCompiled;
// Stream Output Support
D3D11_SO_DECLARATION_ENTRY* m_SODeclarationArray;
UINT m_SONumEntries;
UINT* m_SOStridesArray;
UINT m_SONumStrides;
UINT m_rasterizerStream;
std::unordered_set<std::string> m_includes;
bool m_firstLoad;
bool m_compiledInvalid;
T* m_shader;
};
template <typename T>
class ShaderWrapper {
public:
ShaderWrapper(Shader<T>* shader) : m_shader(shader) {}
operator T*() const { return m_shader->Get(); }
private:
Shader<T>* m_shader;
};
template <typename T>
HRESULT Shader<T>::CheckAndReload(ID3D11Device* pd3dDevice)
{
HRESULT hr;
// return if not changed
//if (!GetAndSetFileChange(m_fileNameSrc, m_lastChange))
// return S_OK;
// is changed, reload
ID3DBlob* pBlob = NULL;
hr = CompileShader(pd3dDevice, &pBlob);
SAFE_RELEASE(pBlob);
if(FAILED(hr))
{
if(m_type == VERTEX_SHADER)
std::cerr << "vertex shader failed" << std::endl;
else if(m_type == DOMAIN_SHADER)
std::cerr << "domain shader failed" << std::endl;
else if(m_type == HULL_SHADER)
std::cerr << "hull shader failed" << std::endl;
else if(m_type == GEOMETRY_SHADER)
std::cerr << "geometry shader failed" << std::endl;
else if(m_type == PIXEL_SHADER)
std::cerr << "pixel shader failed" << std::endl;
else if(m_type == COMPUTE_SHADER)
std::cerr << "compute shader failed" << std::endl;
}
return hr;
}
template <typename T>
void Shader<T>::Destroy()
{
SAFE_RELEASE(m_shader);
if(m_pDefines)
{
for(int i = 0; m_pDefines[i].Name != NULL; ++i)
{
SAFE_DELETE_ARRAY(m_pDefines[i].Name);
SAFE_DELETE_ARRAY(m_pDefines[i].Definition);
}
}
SAFE_DELETE_ARRAY(m_pDefines);
}
struct EffectCommonConfig{
int common_render_hash;
EffectCommonConfig()
{
common_render_hash = 0;
}
};
typedef std::pair< std::string, std::string > ShaderDefine;
typedef std::vector< ShaderDefine > ShaderDefineVector;
struct DrawShaderSource {
//typedef std::pair< std::string, std::string > Define;
//typedef std::vector< Define > DefineVector;
void AddDefine(std::string const & name, std::string const & value = "1")
{
defines.push_back( ShaderDefine(name, value) );
}
std::string sourceFile;
std::string version;
std::string target;
std::string entry;
ShaderDefineVector defines;
};
struct DrawSourceConfig {
int value;
DrawSourceConfig()
{
value = 0;
}
DrawShaderSource commonShader;
DrawShaderSource vertexShader;
DrawShaderSource hullShader;
DrawShaderSource domainShader;
DrawShaderSource geometryShader;
DrawShaderSource pixelShader;
DrawShaderSource computeShader;
// config hashes for shader precompile names
EffectCommonConfig commonConfig;
virtual ~DrawSourceConfig();
};
struct DrawConfig {
DrawConfig() :
vertexShader(0), hullShader(0), domainShader(0),
geometryShader(0), pixelShader(0), computeShader(0), srcConfig(0) {}
virtual ~DrawConfig() {
if (srcConfig)
delete srcConfig;
srcConfig = NULL;
}
Shader<ID3D11VertexShader>* vertexShader;
Shader<ID3D11HullShader>* hullShader;
Shader<ID3D11DomainShader>* domainShader;
Shader<ID3D11GeometryShader>* geometryShader;
Shader<ID3D11PixelShader>* pixelShader;
Shader<ID3D11ComputeShader>* computeShader;
DrawSourceConfig* srcConfig;
};
class DrawRegistryBase {
public:
typedef int DescType;
typedef DrawConfig ConfigType;
typedef DrawSourceConfig SourceConfigType;
virtual ~DrawRegistryBase(){};
protected:
virtual ConfigType * _NewDrawConfig() const { return new ConfigType(); }
virtual ConfigType * _CreateDrawConfig( DescType const & desc,
SourceConfigType const * sconfig,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements) const;
virtual SourceConfigType * _NewDrawSourceConfig() const { return new SourceConfigType(); }
virtual SourceConfigType *_CreateDrawSourceConfig(DescType const & desc, ID3D11Device * pd3dDevice) const;
};
template < class DESC_TYPE = Effect,
class CONFIG_TYPE = DrawConfig,
class SOURCE_CONFIG_TYPE = DrawSourceConfig >
class TEffectDrawRegistry : public DrawRegistryBase {
public:
typedef DESC_TYPE DescType;
typedef CONFIG_TYPE ConfigType;
typedef SOURCE_CONFIG_TYPE SourceConfigType;
typedef std::map<DescType, ConfigType *> ConfigMap;
public:
virtual ~TEffectDrawRegistry()
{
Reset();
}
void Reset()
{
//for (typename ConfigMap::iterator i = _configMap.begin(); i != _configMap.end(); ++i)
//{
// delete i->second;
//}
if(_configMap.size() > 0)
{
for(auto i : _configMap)
{
if(i.second) delete i.second;
}
_configMap.clear();
}
}
// fetch shader config
ConfigType * GetDrawConfig(DescType const & desc, ID3D11Device * pd3dDevice, ID3D11InputLayout ** ppInputLayout = NULL, D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs = NULL, int numInputElements = 0)
{
typename ConfigMap::iterator it = _configMap.find(desc);
if (it != _configMap.end())
{
return it->second;
}
else
{
auto* srcConfig = _CreateDrawSourceConfig(desc, pd3dDevice);
ConfigType * config = _CreateDrawConfig(desc, srcConfig, pd3dDevice, ppInputLayout, pInputElementDescs, numInputElements);
_configMap[desc] = config;
return config;
}
}
protected:
virtual ConfigType * _NewDrawConfig() const { return new ConfigType(); }
virtual ConfigType * _CreateDrawConfig( DescType const & desc,
SourceConfigType const * sconfig,
ID3D11Device * pd3dDevice,
ID3D11InputLayout ** ppInputLayout,
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
int numInputElements) const { return NULL; }
virtual SourceConfigType * _NewDrawSourceConfig() const { return new SourceConfigType(); }
virtual SourceConfigType * _CreateDrawSourceConfig(DescType const & desc, ID3D11Device * pd3dDevice) const { return NULL; }
private:
ConfigMap _configMap;
};
class WatchedFile
{
public:
WatchedFile(const std::string& includeFileName);
~WatchedFile();
bool CheckIsModified();
WIN32_FIND_DATA& getLastWrite() { return m_lastWrite;}
private:
WIN32_FIND_DATA m_lastWrite;
std::string m_fileName;
};
class ShaderManager{
public:
ShaderManager();
~ShaderManager();
Shader<ID3D11VertexShader>* AddVertexShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0,const std::vector<int>& configHashes = std::vector<int>(), ID3D11ClassLinkage* pClassLinkage = NULL);
Shader<ID3D11HullShader>* AddHullShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0,const std::vector<int>& configHashes = std::vector<int>(), ID3D11ClassLinkage* pClassLinkage = NULL);
Shader<ID3D11DomainShader>* AddDomainShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0,const std::vector<int>& configHashes = std::vector<int>(), ID3D11ClassLinkage* pClassLinkage = NULL);
Shader<ID3D11GeometryShader>* AddGeometryShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0,const std::vector<int>& configHashes = std::vector<int>(), ID3D11ClassLinkage* pClassLinkage = NULL);
Shader<ID3D11GeometryShader>* AddGeometryShaderSO(ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0,
D3D11_SO_DECLARATION_ENTRY *pSODeclaration = NULL, UINT numSOEntries = 0, UINT* pSOStrides = NULL, UINT numSOStrides = 0, UINT rasterizerStream = D3D11_SO_NO_RASTERIZED_STREAM,
ID3D11ClassLinkage* pClassLinkage = NULL);
Shader<ID3D11PixelShader>* AddPixelShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, const std::vector<int>& configHashes = std::vector<int>(), ID3D11ClassLinkage* pClassLinkage = NULL);
Shader<ID3D11ComputeShader>* AddComputeShader( ID3D11Device* pd3dDevice, const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, const std::vector<int>& configHashes = std::vector<int>(), ID3D11ClassLinkage* pClassLinkage = NULL);
// with support for compiled names from config hashes
//Shader<ID3D11VertexShader>* AddVertexShader( const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, const std::vector<int>& configHashes, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, ID3D11ClassLinkage* pClassLinkage = NULL);
//Shader<ID3D11HullShader>* AddHullShader( const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, const std::vector<int>& configHashes = std::vector<int>(), D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, ID3D11ClassLinkage* pClassLinkage = NULL);
//Shader<ID3D11DomainShader>* AddDomainShader( const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, const std::vector<int>& configHashes = std::vector<int>(), D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, ID3D11ClassLinkage* pClassLinkage = NULL);
//Shader<ID3D11GeometryShader>* AddGeometryShader( const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, const std::vector<int>& configHashes = std::vector<int>(), D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, ID3D11ClassLinkage* pClassLinkage = NULL);
// Shader<ID3D11GeometryShader>* AddGeometryShaderSO(const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, const std::vector<int>& configHashes = std::vector<int>(), D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0,
// D3D11_SO_DECLARATION_ENTRY *pSODeclaration = NULL, UINT numSOEntries = 0, UINT* pSOStrides = NULL, UINT numSOStrides = 0, UINT rasterizerStream = D3D11_SO_NO_RASTERIZED_STREAM,
// ID3D11ClassLinkage* pClassLinkage = NULL);
// Shader<ID3D11PixelShader>* AddPixelShader( const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, const std::vector<int>& configHashes = std::vector<int>(),D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, ID3D11ClassLinkage* pClassLinkage = NULL);
// Shader<ID3D11ComputeShader>* AddComputeShader( const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut, const std::vector<int>& configHashes = std::vector<int>(),D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, ID3D11ClassLinkage* pClassLinkage = NULL);
HRESULT CheckAndReload(ID3D11Device* pd3dDevice);
void Destroy();
WatchedFile* AddIncludeFile(std::string includeFileName);
const std::unordered_map<std::string, WatchedFile*>& GetIncludes() const { return m_includeFiles; }
bool UsePrecompiledShaders() const { return m_precompiledShadersEnabled; }
void SetPrecompiledShaders(bool enabled) { m_precompiledShadersEnabled = enabled; }
private:
void CheckIncludes();
std::string CreateCompiledFileName(const char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, D3D_SHADER_MACRO* pDefines = NULL, DWORD compilerFlags = 0, const std::vector<int>& config_hashes = std::vector<int>());
std::unordered_map<std::string, Shader<ID3D11VertexShader>* > m_vertexShaders;
std::unordered_map<std::string, Shader<ID3D11HullShader>* > m_hullShaders;
std::unordered_map<std::string, Shader<ID3D11DomainShader>* > m_domainShaders;
std::unordered_map<std::string, Shader<ID3D11GeometryShader>* > m_geometryShaders;
std::unordered_map<std::string, Shader<ID3D11PixelShader>* > m_pixelShaders;
std::unordered_map<std::string, Shader<ID3D11ComputeShader>* > m_computeShaders;
std::string m_compiledShaderDirectory;
std::vector<WatchedFile> m_includes;
std::unordered_map<std::string, WatchedFile*> m_includeFiles;
std::unordered_map<std::string, bool> m_changedIncludeFiles;
bool m_precompiledShadersEnabled; // for nsight debugging
};
extern ShaderManager g_shaderManager;

View File

@@ -0,0 +1,16 @@
Build started 05.08.2014 16:04:35.
1>Project "E:\blu-flame.org\hgplus\obliterator\C\framework-dx11.vcxproj" on node 2 (Build target(s)).
1>FxCompile:
C:\Program Files (x86)\Windows Kits\8.1\bin\x86\fxc.exe /nologo /E"csFXAA" /T cs_5_0 /Fo "E:\blu-flame.org\hgplus\obliterator\C\Debug\postprocessing.cso" /Od /Zi postprocessing.hlsl
1>E:\blu-flame.org\hgplus\obliterator\C\fxaa311.hlsl(938,25): warning X4000: use of potentially uninitialized variable (FxaaPixelShader)
compilation object save succeeded; see E:\blu-flame.org\hgplus\obliterator\C\Debug\postprocessing.cso
C:\Program Files (x86)\Windows Kits\8.1\bin\x86\fxc.exe /nologo /E"csRun" /T cs_5_0 /Fo "E:\blu-flame.org\hgplus\obliterator\C\Debug\rt.cso" /Od /Zi rt.hlsl
1>FXC : error X3501: 'csRun': entrypoint not found
compilation failed; no code produced
1>Done Building Project "E:\blu-flame.org\hgplus\obliterator\C\framework-dx11.vcxproj" (Build target(s)) -- FAILED.
Build FAILED.
Time Elapsed 00:00:00.36

View File

@@ -0,0 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit
Debug|Win32|E:\blu-flame.org\hgplus\obliterator\C\|

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,24 @@
Build started 07.08.2014 16:37:58.
1>Project "E:\blu-flame.org\hgplus\obliterator\C\framework-dx11.vcxproj" on node 2 (Build target(s)).
1>FxCompile:
C:\Program Files (x86)\Windows Kits\8.1\bin\x86\fxc.exe /nologo /E"_0" /T cs_5_0 /Fo "E:\blu-flame.org\hgplus\obliterator\C\Release\b288.cso" ..\gpu\b288.inc
1>E:\blu-flame.org\hgplus\obliterator\gpu\b288.inc(1,278-329): warning X3081: potentially unintended use of a comma expression in a return statement
1>E:\blu-flame.org\hgplus\obliterator\gpu\b288.inc(1,1249-1288): warning X3583: race condition writing to shared resource detected, note that threads will be writing the same value, but performance may be diminished due to contention.
1>E:\blu-flame.org\hgplus\obliterator\gpu\b288.inc(1,1635-1647): warning X3583: warning location reached from this location
compilation object save succeeded; see E:\blu-flame.org\hgplus\obliterator\C\Release\b288.cso
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /Zi /nologo /W3 /WX- /O2 /Oi /Oy- /GL /D WIN32 /D NDEBUG /D _CONSOLE /D _LIB /Gm- /MD /GS- /Gy /fp:fast /Zc:wchar_t /Zc:forScope /Fo"Release\\" /Fd"Release\vc120.pdb" /Gd /TP /analyze- /errorReport:prompt main.cpp
main.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xlocale(337): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
Link:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"E:\blu-flame.org\hgplus\obliterator\C\Release\framework-dx11.exe" /INCREMENTAL:NO /NOLOGO kernel32.lib user32.lib gdi32.lib d3d11.lib d3dcompiler.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"E:\blu-flame.org\hgplus\obliterator\C\Release\framework-dx11.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"E:\blu-flame.org\hgplus\obliterator\C\Release\framework-dx11.lib" /MACHINE:X86 /SAFESEH Release\DXShaderManager.obj
Release\main.obj
Generating code
Finished generating code
framework-dx11.vcxproj -> E:\blu-flame.org\hgplus\obliterator\C\Release\framework-dx11.exe
1>Done Building Project "E:\blu-flame.org\hgplus\obliterator\C\framework-dx11.vcxproj" (Build target(s)).
Build succeeded.
Time Elapsed 00:00:03.02

Binary file not shown.

View File

@@ -0,0 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit
Release|Win32|E:\blu-flame.org\hgplus\obliterator\C\|

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,140 @@
#include <DirectXMath.h>
#include <fstream>
class Camera {
public:
Camera() {
reset();
}
~Camera() {
}
void reset() {
m_cameraViewUp = DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f);
m_cameraViewDirection = DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f);
m_cameraViewPosition = DirectX::XMFLOAT3(0.0f, 0.0f, 3.0f);
}
void translate(float us, float vs, float ws) {
// RHS coordinate system U, V, W
DirectX::XMVECTOR w = DirectX::XMVectorScale(DirectX::XMLoadFloat3(&m_cameraViewDirection), -1.0f);
DirectX::XMVECTOR v = DirectX::XMLoadFloat3(&m_cameraViewUp);
DirectX::XMVECTOR u = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w));
DirectX::XMVECTOR p = XMLoadFloat3(&m_cameraViewPosition);
DirectX::XMVECTOR wScaled = DirectX::XMVectorScale(u, us);
DirectX::XMVECTOR vScaled = DirectX::XMVectorScale(v, vs);
DirectX::XMVECTOR uScaled = DirectX::XMVectorScale(w, ws);
DirectX::XMStoreFloat3(&m_cameraViewPosition, DirectX::XMVectorAdd(p, DirectX::XMVectorAdd(uScaled, DirectX::XMVectorAdd(vScaled, wScaled))));
}
void rotateAroundU(float theta) {
// RHS coordinate system U, V, W
DirectX::XMVECTOR w = DirectX::XMVectorScale(DirectX::XMLoadFloat3(&m_cameraViewDirection), -1.0f);
DirectX::XMVECTOR v = DirectX::XMLoadFloat3(&m_cameraViewUp);
DirectX::XMVECTOR u = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w));
float cosTheta = std::cos(theta);
float sinTheta = std::sin(theta);
// Rodriguez rotation of W around U
DirectX::XMVECTOR wNew = DirectX::XMVectorAdd(
DirectX::XMVectorScale(w, cosTheta),
DirectX::XMVectorScale(DirectX::XMVector3Normalize(DirectX::XMVector3Cross(u, w)), sinTheta));
// Rodriguez rotation of V around U
DirectX::XMVECTOR vNew = DirectX::XMVectorAdd(
DirectX::XMVectorScale(v, cosTheta),
DirectX::XMVectorScale(DirectX::XMVector3Normalize(DirectX::XMVector3Cross(u, v)), sinTheta));
// Compute and store new view direction (-W)
DirectX::XMStoreFloat3(&m_cameraViewDirection, DirectX::XMVectorScale(wNew, -1.0f));
// Store new up vector
DirectX::XMStoreFloat3(&m_cameraViewUp, vNew);
}
void rotateAroundV(float theta) {
// RHS coordinate system U, V, W
DirectX::XMVECTOR w = DirectX::XMVectorScale(DirectX::XMLoadFloat3(&m_cameraViewDirection), -1.0f);
DirectX::XMVECTOR v = DirectX::XMLoadFloat3(&m_cameraViewUp);
DirectX::XMVECTOR u = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w));
float cosTheta = std::cos(theta);
float sinTheta = std::sin(theta);
// Rodriguez rotation of W around V
DirectX::XMVECTOR wNew = DirectX::XMVectorAdd(
DirectX::XMVectorScale(w, cosTheta),
DirectX::XMVectorScale(DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w)), sinTheta));
// Compute and store new view direction (-W)
DirectX::XMStoreFloat3(&m_cameraViewDirection, DirectX::XMVectorScale(wNew, -1.0f));
}
void rotateAroundW(float theta) {
// RHS coordinate system U, V, W
DirectX::XMVECTOR w = DirectX::XMVectorScale(DirectX::XMLoadFloat3(&m_cameraViewDirection), -1.0f);
DirectX::XMVECTOR v = DirectX::XMLoadFloat3(&m_cameraViewUp);
DirectX::XMVECTOR u = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w));
float cosTheta = std::cos(theta);
float sinTheta = std::sin(theta);
// Rodriguez rotation of V around W
DirectX::XMVECTOR vNew = DirectX::XMVectorAdd(
DirectX::XMVectorScale(v, cosTheta),
DirectX::XMVectorScale(DirectX::XMVector3Normalize(DirectX::XMVector3Cross(w, v)), sinTheta));
// Store new up vector
DirectX::XMStoreFloat3(&m_cameraViewUp, vNew);
}
const DirectX::XMFLOAT3& getViewUp() {
return m_cameraViewUp;
}
const DirectX::XMFLOAT3& getViewPosition() {
return m_cameraViewPosition;
}
const DirectX::XMFLOAT3& getViewDirection() {
return m_cameraViewDirection;
}
void storeCamera(std::string cameraFilename) {
std::ofstream outfile(cameraFilename.c_str(), std::ios::out | std::ios::binary);
outfile.write(reinterpret_cast<char*>(&m_cameraViewUp), sizeof(DirectX::XMFLOAT3));
outfile.write(reinterpret_cast<char*>(&m_cameraViewDirection), sizeof(DirectX::XMFLOAT3));
outfile.write(reinterpret_cast<char*>(&m_cameraViewPosition), sizeof(DirectX::XMFLOAT3));
outfile.close();
}
void loadCamera(std::string cameraFilename) {
std::ifstream infile(cameraFilename.c_str(), std::ios::out | std::ios::binary);
infile.read(reinterpret_cast<char*>(&m_cameraViewUp), sizeof(DirectX::XMFLOAT3));
infile.read(reinterpret_cast<char*>(&m_cameraViewDirection), sizeof(DirectX::XMFLOAT3));
infile.read(reinterpret_cast<char*>(&m_cameraViewPosition), sizeof(DirectX::XMFLOAT3));
infile.close();
}
protected:
DirectX::XMFLOAT3 m_cameraViewUp; // Y
DirectX::XMFLOAT3 m_cameraViewDirection; // -Z
DirectX::XMFLOAT3 m_cameraViewPosition; // P
float m_fovY;
};

Binary file not shown.

View File

@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "framework-dx11", "framework-dx11.vcxproj", "{5D25DE85-C37F-4D88-B675-E000CF62FD9F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5D25DE85-C37F-4D88-B675-E000CF62FD9F}.Debug|Win32.ActiveCfg = Debug|Win32
{5D25DE85-C37F-4D88-B675-E000CF62FD9F}.Debug|Win32.Build.0 = Debug|Win32
{5D25DE85-C37F-4D88-B675-E000CF62FD9F}.Release|Win32.ActiveCfg = Release|Win32
{5D25DE85-C37F-4D88-B675-E000CF62FD9F}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Binary file not shown.

View File

@@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" 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">
<ProjectGuid>{5D25DE85-C37F-4D88-B675-E000CF62FD9F}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>frameworkdx11</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</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" />
</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" />
</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>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;d3d11.lib;d3dcompiler.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FloatingPointModel>Fast</FloatingPointModel>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;d3d11.lib;d3dcompiler.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="DXShaderManager.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<FxCompile Include="..\gpu\b288.hlsl">
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_0</EntryPointName>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_0</EntryPointName>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">DEBUG_SHADER_ID=0</PreprocessorDefinitions>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</FxCompile>
<FxCompile Include="..\gpu\b288.inc">
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_0</EntryPointName>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_0</EntryPointName>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
</FxCompile>
<FxCompile Include="fxaa311.hlsl">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</FxCompile>
<FxCompile Include="lighting.hlsl">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</FxCompile>
<FxCompile Include="material.hlsl">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</FxCompile>
<FxCompile Include="postprocessing.hlsl">
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">csFXAA</EntryPointName>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">csFXAA</EntryPointName>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
</FxCompile>
<FxCompile Include="rt.hlsl">
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">csRT</EntryPointName>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">csRT</EntryPointName>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</FxCompile>
<FxCompile Include="sdf.hlsl">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</FxCompile>
<FxCompile Include="utils.hlsl">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</FxCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="camera.h" />
<ClInclude Include="DXShaderManager.h" />
<ClInclude Include="ogl2dx.hlsl">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClInclude>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Resource Files\include">
<UniqueIdentifier>{37260c7f-9e50-41b8-b7e5-1746733300de}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DXShaderManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<FxCompile Include="rt.hlsl">
<Filter>Resource Files</Filter>
</FxCompile>
<FxCompile Include="lighting.hlsl">
<Filter>Resource Files\include</Filter>
</FxCompile>
<FxCompile Include="material.hlsl">
<Filter>Resource Files\include</Filter>
</FxCompile>
<FxCompile Include="sdf.hlsl">
<Filter>Resource Files\include</Filter>
</FxCompile>
<FxCompile Include="utils.hlsl">
<Filter>Resource Files\include</Filter>
</FxCompile>
<FxCompile Include="fxaa311.hlsl">
<Filter>Resource Files\include</Filter>
</FxCompile>
<FxCompile Include="postprocessing.hlsl">
<Filter>Resource Files</Filter>
</FxCompile>
<FxCompile Include="..\gpu\b288.hlsl">
<Filter>Resource Files</Filter>
</FxCompile>
<FxCompile Include="..\gpu\b288.inc">
<Filter>Resource Files</Filter>
</FxCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="DXShaderManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="camera.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ogl2dx.hlsl">
<Filter>Resource Files\include</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
#ifndef LIGHTING
#define LIGHTING
#include "utils.hlsl"
float ggx(float dotNH, float roughness) {
float r2 = roughness*roughness;
float r4 = r2*r2;
float dotNH2 = dotNH * dotNH;
float d = abs(dotNH2 * r4 - dotNH2 + 1);
return r4 / (PI*d*d + 0.00000001);
}
float geometricShadowing(float dotNV, float dotNL, float roughness) {
float r = roughness + 1;
float k = r*r / 8;
float ik = 1 - k;
return 1 / (4 * (dotNV * ik + k) * (dotNL * ik + k));
}
float fresnel(float dotNV, float f0) {
float p = (-5.55473 * dotNV - 6.98316) * dotNV;
return f0 + (1 - f0) * exp2(p);
}
float transmittance(float3 i, float3 n, float eta1, float eta2) {
float eta = eta1 / eta2;
float cosI = -dot(n, i);
float sinT2 = eta * eta * (1.0 - cosI * cosI);
if (sinT2 > 1.0) return 1.0;
float cosT = sqrt(1.0 - sinT2);
float rOrth = (eta1 * cosI - eta2 * cosT) / (eta1 * cosI + eta2 * cosT);
float rPar = (eta2 * cosI - eta1 * cosT) / (eta2 * cosI + eta1 * cosT);
return 1.0 - (rOrth * rOrth + rPar * rPar) / 2.0;
}
float brdfSpecular(float dotNV,float dotNL,float dotNH,float dotVH,float roughness, float f0) {
return ggx(dotNH, roughness) *
fresnel(dotNV, f0) *
geometricShadowing(dotNV, dotNL, roughness);
}
float brdfLambert() {
return 1/PI;
}
// n, v, l: assumed to be normalized
float3 brdf(float3 n, float3 v, float3 l,
float3 albedo, float3 specular,
float roughness, float f0) {
roughness = clamp(roughness, 0.05, 1.0);
//roughness = 0.4;
float3 h = normalize(v + l);
float dotNV = max(0, dot(n, v));
float dotNL = max(0, dot(n, l));
float dotNH = max(0, dot(n, h));
float dotVH = max(0, dot(v, h));
float3 color =
albedo * brdfLambert() +
specular* brdfSpecular(dotNV, dotNL, dotNH, dotVH, roughness, f0);
color *= dotNL;
return color;
}
float3 brdfSphereLight(float3 p, float3 n, float3 v,
float3 reflected, float3 lightPosition, float lightRadius,
float3 albedo, float3 specular, float roughness, float f0) {
float3 toLightCenter = lightPosition - p;
float3 centerToRay = toLightCenter - dot(toLightCenter, reflected) * reflected;
float3 closestPoint = toLightCenter - centerToRay * saturate(lightRadius / length(centerToRay));
float3 l = normalize(closestPoint);
return brdf(n, v, l, albedo, specular, roughness, f0);
}
#endif

View File

@@ -0,0 +1,670 @@
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <cstdlib>
#define D3D11_NO_HELPERS
#include <d3d11.h>
#include <dxgi.h>
#include <d3dcompiler.h>
#define ATOM_EDIT 0xC018
#define ATOM_STATIC 0xC019
#define WIDTH (1280)
#define HEIGHT (720)
#define _USE_PERFORMANCE_QUERIES
//#define CAMERA_FILENAME "convex.cam"
//#define CAMERA_FILENAME "city.cam"
#define CAMERA_FILENAME "jewels.cam"
#define _FULLSCREEN
#ifndef USE_PERFORMANCE_QUERIES
#define USE_POSTPROCESSING
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include "DXShaderManager.h"
#include "camera.h"
#define REGISTER_SHADER(F,E,P) g_shaderManager.AddComputeShader(device, F, E, P, &blob, NULL, D3DCOMPILE_OPTIMIZATION_LEVEL3)
#define REGISTER_SHADER_WITH_DEFINES(F,E,P,D) g_shaderManager.AddComputeShader(device, F, E, P, &blob, D, D3DCOMPILE_OPTIMIZATION_LEVEL3)
//#define REGISTER_SHADER_WITH_DEFINES g_shaderMangaer.A
#define CHECK_AND_RELOAD_SHADERS() \
if (S_OK != g_shaderManager.CheckAndReload(device)) { \
Sleep(500); \
continue; \
}
HWND hWnd;
typedef struct {
// DXGI_MODE_DESC BufferDesc;
UINT Width;
UINT Height;
//DXGI_RATIONAL RefreshRate;
UINT Numerator;
UINT Denominator;
DXGI_FORMAT Format;
DXGI_MODE_SCANLINE_ORDER ScanlineOrdering;
DXGI_MODE_SCALING Scaling;
// DXGI_SAMPLE_DESC SampleDesc;
UINT Count;
UINT Quality;
DXGI_USAGE BufferUsage;
UINT BufferCount;
HWND OutputWindow;
BOOL Windowed;
DXGI_SWAP_EFFECT SwapEffect;
UINT Flags;
} HG_DXGI_SWAP_CHAIN_DESC;
#ifdef FULLSCREEN
HG_DXGI_SWAP_CHAIN_DESC swapChainDesc = {
WIDTH, HEIGHT, 0, 1, DXGI_FORMAT_R8G8B8A8_UNORM, //DXGI_FORMAT_R16G16B16A16_FLOAT,
DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, DXGI_MODE_SCALING_UNSPECIFIED,
1, 0, DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS | DXGI_USAGE_SHADER_INPUT, 1, 0, 0, DXGI_SWAP_EFFECT_DISCARD, 0
};
#else
HG_DXGI_SWAP_CHAIN_DESC swapChainDesc = {
WIDTH, HEIGHT, 0, 1, DXGI_FORMAT_R8G8B8A8_UNORM, //DXGI_FORMAT_R8G8B8A8_UNORM,// DXGI_FORMAT_R16G16B16A16_FLOAT
DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, DXGI_MODE_SCALING_UNSPECIFIED,
1, 0, DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS | DXGI_USAGE_SHADER_INPUT, 1, 0, -1, DXGI_SWAP_EFFECT_DISCARD, 0
};
#endif
static bool keys[256];
static bool leftMouseButtonDown = false;
static bool leftMouseButtonDownInit = false;
static POINT mouseCursorPosition;
static float translationSpeed = 1.0f;
ID3D11Device* device;
ID3D11DeviceContext* context;
IDXGISwapChain* swapChain;
ID3D11Texture2D* backBufferTexture;
ID3D11UnorderedAccessView* backBufferUAV;
#ifdef USE_PERFORMANCE_QUERIES
ID3D11Query* disjointQuery;
ID3D11Query* beginFrameQuery;
ID3D11Query* endFrameQuery;
ID3D11Query* traceQuery;
ID3D11Query* postprocessingQuery;
void setupQueries() {
D3D11_QUERY_DESC queryDescDisjoint = { D3D11_QUERY_TIMESTAMP_DISJOINT, 0 };
D3D11_QUERY_DESC queryDesc = { D3D11_QUERY_TIMESTAMP, 0 };
device->CreateQuery(&queryDescDisjoint, &disjointQuery);
device->CreateQuery(&queryDesc, &beginFrameQuery);
device->CreateQuery(&queryDesc, &endFrameQuery);
device->CreateQuery(&queryDesc, &traceQuery);
device->CreateQuery(&queryDesc, &postprocessingQuery);
}
void getPerformanceData() {
while (context->GetData(disjointQuery, NULL, 0, 0)) {
Sleep(1);
}
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timestampDisjoint;
context->GetData(disjointQuery, &timestampDisjoint, sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT), 0);
if (timestampDisjoint.Disjoint)
return;
UINT64 timestampBeginFrame, timestampEndFrame;
context->GetData(beginFrameQuery, &timestampBeginFrame, sizeof(UINT64), 0);
context->GetData(endFrameQuery, &timestampEndFrame, sizeof(UINT64), 0);
double msFrame = (double(timestampEndFrame - timestampBeginFrame) / double(timestampDisjoint.Frequency)) * 1000.0f;
static int i = 0;
if (i++ % 256 == 0) {
std::cout << msFrame << " ms - "<< (1000.0f / msFrame) << " Hz" << std::endl;
}
}
#endif
struct TEXTURE_2D_SRV_UAV_RTV {
ID3D11Texture2D* TEX;
ID3D11ShaderResourceView* SRV;
ID3D11UnorderedAccessView* UAV;
ID3D11RenderTargetView* RTV;
};
struct CONSTANT_BUFFER_STRUCT {
float time;
float d0, d1, d2;
DirectX::XMFLOAT3 viewPosition;
float d3;
DirectX::XMFLOAT3 viewDirection;
float d4;
DirectX::XMFLOAT3 viewUp;
float d5;
};
void createSRVUAVRTV(TEXTURE_2D_SRV_UAV_RTV* tex, int width, int height) {
D3D11_TEXTURE2D_DESC texDesc = {
width, height, 0, 1, DXGI_FORMAT_R16G16B16A16_FLOAT,
{1, 0}, D3D11_USAGE_DEFAULT,
D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS,
0, D3D11_RESOURCE_MISC_GENERATE_MIPS
};
device->CreateTexture2D(&texDesc, NULL, &tex->TEX);
device->CreateShaderResourceView(tex->TEX, NULL, &tex->SRV);
device->CreateUnorderedAccessView(tex->TEX, NULL, &tex->UAV);
device->CreateRenderTargetView(tex->TEX, NULL, &tex->RTV);
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_KEYDOWN:
if (wParam == VK_ESCAPE) {
//ExitProcess(0);
PostQuitMessage(0);
} else {
if (wParam < 256) keys[wParam] = true;
}
break;
case WM_KEYUP:
if (wParam < 256) keys[wParam] = false;
break;
case WM_LBUTTONDOWN:
if (!leftMouseButtonDownInit) leftMouseButtonDownInit = true;
leftMouseButtonDown = true;
break;
case WM_LBUTTONUP:
leftMouseButtonDownInit = false;
leftMouseButtonDown = false;
break;
case WM_MOUSEMOVE:
mouseCursorPosition.x = LOWORD(lParam);
mouseCursorPosition.y = HIWORD(lParam);
break;
case WM_MOUSEWHEEL:
translationSpeed *= pow(2.f, short(HIWORD(wParam)) / WHEEL_DELTA);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void setNullUAVSRV() {
ID3D11UnorderedAccessView* nullUAV[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
ID3D11ShaderResourceView* nullSRV[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
context->CSSetUnorderedAccessViews(0, 8, nullUAV, NULL);
context->CSSetShaderResources(0, 8, nullSRV);
}
int main(int argc, char** argv) {
HINSTANCE hInstance = GetModuleHandle(0);
LPSTR wndName = "Window";
WNDCLASSEXA wc;
wc.cbSize = sizeof(WNDCLASSEXA);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
wc.hbrBackground = 0;
wc.lpszMenuName = 0;
wc.lpszClassName = wndName;
wc.hIconSm = 0;
if (!RegisterClassExA(&wc))
return EXIT_FAILURE;
#ifdef FULLSCREEN
HWND hWnd = CreateWindowA(wndName, wndName, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE,
CW_USEDEFAULT, CW_USEDEFAULT,
WIDTH,
HEIGHT,
NULL, NULL, hInstance, NULL);
//ShowCursor(FALSE);
#else
RECT wndRect = {0, 0, WIDTH, HEIGHT};
AdjustWindowRect(&wndRect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX, FALSE);
HWND hWnd = CreateWindowExA(0*WS_EX_TOPMOST, wndName, wndName, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT,
wndRect.right - wndRect.left,
wndRect.bottom - wndRect.top,
NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, 1);
UpdateWindow(hWnd);
#endif
swapChainDesc.OutputWindow = hWnd;
D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, NULL, 0, D3D11_SDK_VERSION, (DXGI_SWAP_CHAIN_DESC*)&swapChainDesc, &swapChain, &device, NULL, &context);
swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);
device->CreateUnorderedAccessView(backBufferTexture, NULL, &backBufferUAV);
if (1) {
ID3D11Debug* debug;
device->QueryInterface(__uuidof(ID3D11Debug), (void**)&debug);
ID3D11InfoQueue* infoQueue;
device->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&infoQueue);
infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_INFO, true);
infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_MESSAGE, true);
infoQueue->Release();
debug->Release();
}
#define NUM_INDIRECT_DISPATCHES 14
int initialData[4 * NUM_INDIRECT_DISPATCHES] = {
1, 1, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0 };
D3D11_BUFFER_DESC indirectDispatchBufferDesc = { sizeof(initialData), D3D11_USAGE_DEFAULT, D3D11_BIND_UNORDERED_ACCESS, 0, D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS, 16 };
D3D11_UNORDERED_ACCESS_VIEW_DESC indirectDispatchBufferUAVDesc = { DXGI_FORMAT_R32G32B32A32_UINT, D3D11_UAV_DIMENSION_BUFFER, 0, sizeof(initialData)/16, 0 };
D3D11_SUBRESOURCE_DATA indirectDispatchBufferSubresourceData= { initialData, 0, 0 };
ID3D11Buffer* indirectDispatchBuffer;
ID3D11UnorderedAccessView* indirectDispatchBufferUAV;
device->CreateBuffer(&indirectDispatchBufferDesc, &indirectDispatchBufferSubresourceData, &indirectDispatchBuffer);
device->CreateUnorderedAccessView(indirectDispatchBuffer, &indirectDispatchBufferUAVDesc, &indirectDispatchBufferUAV);
ID3DBlob *blob;
//ShaderWrapper<ID3D11ComputeShader> csRT = REGISTER_SHADER("test.hlsl", "csTestSOR", "cs_5_0");
//ShaderWrapper<ID3D11ComputeShader> csRT = REGISTER_SHADER("rt.hlsl", "csTrace", "cs_5_0");
ShaderWrapper<ID3D11ComputeShader> csRT = REGISTER_SHADER("rt.hlsl", "csRT", "cs_5_0");
D3D_SHADER_MACRO mcpID[] = { { "DEBUG_SHADER_ID", "0" }, { 0 } };
D3D_SHADER_MACRO blurVID[] = { { "DEBUG_SHADER_ID", "1" }, { 0 } };
D3D_SHADER_MACRO blurHID[] = { { "DEBUG_SHADER_ID", "2" }, { 0 } };
D3D_SHADER_MACRO streaksID[] = { { "DEBUG_SHADER_ID", "3" }, { 0 } };
D3D_SHADER_MACRO mergeID[] = { { "DEBUG_SHADER_ID", "4" }, { 0 } };
ShaderWrapper<ID3D11ComputeShader> csMCP = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", mcpID);
ShaderWrapper<ID3D11ComputeShader> csBlurV = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", blurVID);
ShaderWrapper<ID3D11ComputeShader> csBlurH = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", blurHID);
ShaderWrapper<ID3D11ComputeShader> csStreaks = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", streaksID);
ShaderWrapper<ID3D11ComputeShader> csMerge = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", mergeID);
D3D_SHADER_MACRO scene0ID[] = { { "DEBUG_SHADER_ID", "5" }, { 0 } };
D3D_SHADER_MACRO scene1ID[] = { { "DEBUG_SHADER_ID", "6" }, { 0 } };
D3D_SHADER_MACRO scene2ID[] = { { "DEBUG_SHADER_ID", "7" }, { 0 } };
D3D_SHADER_MACRO scene3ID[] = { { "DEBUG_SHADER_ID", "8" }, { 0 } };
D3D_SHADER_MACRO scene4ID[] = { { "DEBUG_SHADER_ID", "9" }, { 0 } };
ShaderWrapper<ID3D11ComputeShader> csScene0 = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", scene0ID);
ShaderWrapper<ID3D11ComputeShader> csScene1 = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", scene1ID);
ShaderWrapper<ID3D11ComputeShader> csScene2 = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", scene2ID);
ShaderWrapper<ID3D11ComputeShader> csScene3 = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", scene3ID);
ShaderWrapper<ID3D11ComputeShader> csScene4 = REGISTER_SHADER_WITH_DEFINES("..\\gpu\\b288.hlsl", "_0", "cs_5_0", scene4ID);
//ShaderWrapper<ID3D11ComputeShader> csBlurV = REGISTER_SHADER("postprocessing.hlsl", "csBlurV", "cs_5_0");
//ShaderWrapper<ID3D11ComputeShader> csBlurH = REGISTER_SHADER("postprocessing.hlsl", "csBlurH", "cs_5_0");
//ShaderWrapper<ID3D11ComputeShader> csStreaks = REGISTER_SHADER("postprocessing.hlsl", "csStreaks", "cs_5_0");
//ShaderWrapper<ID3D11ComputeShader> csMerge = REGISTER_SHADER("postprocessing.hlsl", "csMerge", "cs_5_0");
//ShaderWrapper<ID3D11ComputeShader> csDistortChroma = REGISTER_SHADER("postprocessing.hlsl", "csDistortChroma", "cs_5_0");
//ShaderWrapper<ID3D11ComputeShader> csRadialBlur = REGISTER_SHADER("postprocessing.hlsl", "csRadialBlur", "cs_5_0");
//ShaderWrapper<ID3D11ComputeShader> csCircumferentialBlur = REGISTER_SHADER("postprocessing.hlsl", "csCircumferentialBlur", "cs_5_0");
//ShaderWrapper<ID3D11ComputeShader> csLensDirt = REGISTER_SHADER("postprocessing.hlsl", "csLensDirt", "cs_5_0");
//ShaderWrapper<ID3D11ComputeShader> csGhosts = REGISTER_SHADER("postprocessing.hlsl", "csGhosts", "cs_5_0");
ShaderWrapper<ID3D11ComputeShader> csFXAA = REGISTER_SHADER("postprocessing.hlsl", "csFXAA", "cs_5_0");
D3D11_SAMPLER_DESC samplerDesc = {
D3D11_FILTER_MIN_MAG_MIP_LINEAR, //D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_FILTER_ANISOTROPIC, D3D11_FILTER_MIN_MAG_MIP_POINT
D3D11_TEXTURE_ADDRESS_CLAMP,
D3D11_TEXTURE_ADDRESS_CLAMP,
D3D11_TEXTURE_ADDRESS_CLAMP,
0.0f,
1,
D3D11_COMPARISON_ALWAYS,
{0,0,0,0},
0,
D3D11_FLOAT32_MAX
};
ID3D11SamplerState* sampler;
device->CreateSamplerState(&samplerDesc, &sampler);
context->CSSetSamplers(0, 1, &sampler);
TEXTURE_2D_SRV_UAV_RTV tex0;
createSRVUAVRTV(&tex0, WIDTH, HEIGHT);
TEXTURE_2D_SRV_UAV_RTV streaksTex4;
createSRVUAVRTV(&streaksTex4, WIDTH/4, HEIGHT/4);
TEXTURE_2D_SRV_UAV_RTV tmpTex1;
TEXTURE_2D_SRV_UAV_RTV blurTex1;
createSRVUAVRTV(&tmpTex1, WIDTH, HEIGHT);
createSRVUAVRTV(&blurTex1, WIDTH, HEIGHT);
TEXTURE_2D_SRV_UAV_RTV tmpTex8;
TEXTURE_2D_SRV_UAV_RTV blurTex8;
createSRVUAVRTV(&tmpTex8, WIDTH/8, HEIGHT/8);
createSRVUAVRTV(&blurTex8, WIDTH/8, HEIGHT/8);
TEXTURE_2D_SRV_UAV_RTV tmpTex32;
TEXTURE_2D_SRV_UAV_RTV blurTex32;
createSRVUAVRTV(&tmpTex32, WIDTH/32, HEIGHT/32);
createSRVUAVRTV(&blurTex32, WIDTH/32, HEIGHT/32);
ID3D11Buffer* constantBuffer;
D3D11_BUFFER_DESC constantBufferDesc = {
sizeof(CONSTANT_BUFFER_STRUCT),
D3D11_USAGE_DYNAMIC,
D3D11_BIND_CONSTANT_BUFFER,
D3D11_CPU_ACCESS_WRITE,
0,
0
};
device->CreateBuffer(&constantBufferDesc, NULL, &constantBuffer);
//OPENFILE
//BOOL success = GetOpenFileName()
#ifdef USE_PERFORMANCE_QUERIES
setupQueries();
#endif
Camera camera;
//camera.loadCamera(CAMERA_FILENAME);
float prevX = 0.0f;
float prevY = 0.0f;
int startTime = GetTickCount();
int previousTime = startTime;
MSG msg = {0};
while (msg.message != WM_QUIT) {
if (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
continue;
}
#ifndef USE_PERFORMANCE_QUERIES
CHECK_AND_RELOAD_SHADERS();
#endif
int currentTime = GetTickCount() - startTime;
//if (currentTime / 1000 > 2) ExitProcess(0);
{
float timeDelta = (currentTime - previousTime) / 1000.0f;
float translateDelta = translationSpeed * timeDelta * 10.0f;
float rotationAngle = 2.0f * timeDelta * translationSpeed;
if (keys['R']) { camera.reset(); translationSpeed = 1.0f;};
if (keys['W']) camera.translate(0.0f, 0.0f, -translateDelta);
if (keys['S']) camera.translate(0.0f, 0.0f, +translateDelta);
if (keys['A']) camera.translate(-translateDelta, 0.0f, 0.0f);
if (keys['D']) camera.translate(+translateDelta, 0.0f, 0.0f);
if (keys['Q']) camera.translate(0.0f, -translateDelta, 0.0f);
if (keys['E']) camera.translate(0.0f, +translateDelta, 0.0f);
if (keys[VK_OEM_COMMA]) camera.rotateAroundW(+rotationAngle);
if (keys[VK_OEM_PERIOD]) camera.rotateAroundW(-rotationAngle);
if (keys[VK_LEFT]) camera.rotateAroundV(+rotationAngle);
if (keys[VK_RIGHT]) camera.rotateAroundV(-rotationAngle);
if (keys[VK_UP]) camera.rotateAroundU(+rotationAngle);
if (keys[VK_DOWN]) camera.rotateAroundU(-rotationAngle);
if (keys['G']) camera.storeCamera(CAMERA_FILENAME);
if (keys['H']) camera.loadCamera(CAMERA_FILENAME);
if (keys['J']) CHECK_AND_RELOAD_SHADERS();
if (leftMouseButtonDown) {
float x = -(((mouseCursorPosition.x + 0.5f) / WIDTH) - 0.5f);
float y = -(((mouseCursorPosition.y + 0.5f) / HEIGHT) - 0.5f);
float thetaX = float(M_PI) * (x - prevX) * (float(HEIGHT)/float(WIDTH));
float thetaY = float(M_PI) * (y - prevY) * 1.0f;
if (!leftMouseButtonDownInit) {
if (thetaX != 0.0f) camera.rotateAroundV(thetaX);
if (thetaY != 0.0f) camera.rotateAroundU(thetaY);
} else {
leftMouseButtonDownInit = false;
}
prevX = x;
prevY = y;
}
}
#ifdef USE_PERFORMANCE_QUERIES
context->Begin(disjointQuery);
context->End(beginFrameQuery);
#endif
D3D11_MAPPED_SUBRESOURCE mappedResource;
context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
CONSTANT_BUFFER_STRUCT* cb = (CONSTANT_BUFFER_STRUCT*)mappedResource.pData;
cb->time = currentTime / 1000.0f;
cb->viewPosition = camera.getViewPosition();
cb->viewDirection = camera.getViewDirection();
cb->viewUp = camera.getViewUp();
context->Unmap(constantBuffer, 0);
context->CSSetConstantBuffers(0, 1, &constantBuffer);
int DISPATCH = 0;
ID3D11UnorderedAccessView* UAVs[] = { tex0.UAV, indirectDispatchBufferUAV };
// CALL MCP
context->CSSetUnorderedAccessViews(0, 2, UAVs, NULL);
context->CSSetShader(csMCP, NULL, 0);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
// SCENE 0
//context->CSSetUnorderedAccessViews(0, 1, &tex0.UAV, NULL);
context->CSSetShader(csScene0, NULL, 0);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
// SCENE 1
context->CSSetShader(csScene1, NULL, 0);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
// SCENE 2
context->CSSetShader(csScene2, NULL, 0);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
// SCENE 3
context->CSSetShader(csScene3, NULL, 0);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
// SCENE 4
context->CSSetShader(csScene4, NULL, 0);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
//context->CSSetShader(csRT, NULL, 0);
//context->Dispatch(80, 45, 1);
// PIPELINE:
/*
Standard shader:
0 - MCP
1 - Blur V
2 - Blur H
3 - Steaks
4 - Merge
5 - Scene0
6 - Scene1
7 - Scene2
8 - Scene3
9 - Scene4
MCP (1, 1, 1) Dispatch, writes to indirectDispatchBuffer
-- MCP SWITCH CASE VIA DISPATCH-- SCENE0 RESOLUTION/1
-- MCP SWITCH CASE VIA DISPATCH-- SCENE1 RESOLUTION/1
-- MCP SWITCH CASE VIA DISPATCH-- SCENE2 RESOLUTION/1
-- MCP SWITCH CASE VIA DISPATCH-- SCENE3 RESOLUTION/1
-- MCP SWITCH CASE VIA DISPATCH-- SCENE4 RESOLUTION/1
-> MipMap
Streaks RESOLUTION/4
BLURV RESOLUTION/1
BLURH RESOLUTION/1
-> MipMap
BLURV RESOLUTION/8
BLURH RESOLUTION/8
-> MipMap
BLURV RESOLUTION/32
BLURH RESOLUTION/32
-> MipMap
MERGE RESOLUTION/1
Dispatches in the indirect dispatch buffer:
0 -> MCP
1 -> scene1
2 -> scene2
3 -> scene3
4 -> scene4
5 -> scene5
6 -> streaks
7 -> blurh
8 -> blurv
9 -> blurh
10 -> blurv
11 -> blurh
12 -> blurv
13 -> merge
*/
context->GenerateMips(tex0.SRV);
// Streaks
context->CSSetUnorderedAccessViews(0, 1, &streaksTex4.UAV, NULL);
context->CSSetShaderResources(0, 1, &tex0.SRV);
context->CSSetShader(csStreaks, NULL, 0);
//context->Dispatch(20, 12, 1);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
// BlurV (1/1)
context->CSSetUnorderedAccessViews(0, 1, &tmpTex1.UAV, NULL);
context->CSSetShaderResources(0, 1, &tex0.SRV);
context->CSSetShader(csBlurV, NULL, 0);
//context->Dispatch(80, 45, 1);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
// BlurH (1/1) -> blurTex1
context->CSSetUnorderedAccessViews(0, 1, &blurTex1.UAV, NULL);
context->CSSetShaderResources(0, 1, &tmpTex1.SRV);
context->CSSetShader(csBlurH, NULL, 0);
//context->Dispatch(80, 45, 1);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
context->GenerateMips(blurTex1.SRV);
// BlurV (1/8)
context->CSSetUnorderedAccessViews(0, 1, &tmpTex8.UAV, NULL);
context->CSSetShaderResources(0, 1, &blurTex1.SRV);
context->CSSetShader(csBlurV, NULL, 0);
//context->Dispatch(10, 6, 1);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
// BlurH (1/8) -> blurTex8 -> merge / ghosts
context->CSSetUnorderedAccessViews(0, 1, &blurTex8.UAV, NULL);
context->CSSetShaderResources(0, 1, &tmpTex8.SRV);
context->CSSetShader(csBlurH, NULL, 0);
//context->Dispatch(10, 6, 1);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
context->GenerateMips(blurTex8.SRV);
// BlurV (1/32)
context->CSSetUnorderedAccessViews(0, 1, &tmpTex32.UAV, NULL);
context->CSSetShaderResources(0, 1, &blurTex8.SRV);
context->CSSetShader(csBlurV, NULL, 0);
//context->Dispatch(3, 2, 1);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
// BlurH (1/32) -> blurTex32 -> merge / lensDirt / smallDirt / ghosts
context->CSSetUnorderedAccessViews(0, 1, &blurTex32.UAV, NULL);
context->CSSetShaderResources(0, 1, &tmpTex32.SRV);
context->CSSetShader(csBlurV, NULL, 0);
//context->Dispatch(3, 2, 1);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
DISPATCH += 16;
setNullUAVSRV();
// Merge
ID3D11ShaderResourceView* mergeSRV[] = { tex0.SRV, blurTex1.SRV, blurTex8.SRV, blurTex32.SRV, streaksTex4.SRV };
context->CSSetUnorderedAccessViews(0, 1, &backBufferUAV, NULL);
context->CSSetShaderResources(0, 5, mergeSRV);
context->CSSetShader(csMerge, NULL, 0);
//context->Dispatch(80, 45, 1);
context->DispatchIndirect(indirectDispatchBuffer, DISPATCH);
//DISPATCH += 16;
//context->CSSetUnorderedAccessViews(0, 1, &tmpTex1.UAV, NULL);
//context->CSSetShaderResources(0, 5, mergeSRV);
//context->CSSetShader(csMerge, NULL, 0);
//context->Dispatch(80, 45, 1);
//context->CSSetUnorderedAccessViews(0, 1, &backBufferUAV, NULL);
//context->CSSetShaderResources(0, 1, &tmpTex1.SRV);
//context->CSSetShader(csFXAA, NULL, 0);
//context->Dispatch(80, 45, 1);
setNullUAVSRV();
swapChain->Present(1, 0);
//Sleep(100);
#ifdef USE_PERFORMANCE_QUERIES
context->End(endFrameQuery);
context->End(disjointQuery);
getPerformanceData();
#endif
previousTime = currentTime;
}
ExitProcess(0);
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,193 @@
#ifndef MATERIAL
#define MATERIAL
#include "utils.hlsl"
struct Material {
float3 color;
float roughness;
// refraction attenuation, w = 0 -> not reflective/transmissive, w = 0.5 -> reflective, w = 1 -> reflective and transmissive
float4 attenuation;
float eta;
float3 emissive;
float metallic;
};
static Material material;
void setMaterial(Material objectMaterial) {
material = objectMaterial;
}
void setMaterial(bool evaluateMaterial, Material objectMaterial) {
if (evaluateMaterial)
setMaterial(objectMaterial);
}
void minMaterial(inout float currentDistance, float objectDistance, bool evaluateMaterial, Material objectMaterial) {
if (objectDistance < currentDistance) {
currentDistance = objectDistance;
if (evaluateMaterial) {
setMaterial(objectMaterial);
}
}
}
void maxMaterial(inout float currentDistance, float objectDistance, bool evaluateMaterial, Material objectMaterial) {
if (objectDistance > currentDistance) {
currentDistance = objectDistance;
if (evaluateMaterial) {
setMaterial(objectMaterial);
}
}
}
void minMaterialTransmissive(inout float currentDistance, float objectDistance, bool evaluateMaterial, Material objectMaterial) {
minMaterial(currentDistance, abs(objectDistance), evaluateMaterial, objectMaterial);
currentDistance *= objectDistance < 0 ? -1 : +1;
}
bool isReflectiveMaterial(Material m) {
return m.attenuation.w >= 0.5;
}
bool isRefractiveMaterial(Material m) {
return m.attenuation.w == 1;
}
Material makeSpecularMaterial(float3 color) {
Material m;
m.color = color;
m.metallic = 0.0;
m.roughness = 0.0;
m.emissive = 0.0;
m.attenuation = 0.0;
return m;
}
Material makeDiffuseMaterial(float3 color) {
Material m;
m.color = color;
m.metallic = 0.0;
m.roughness = 1.0;
m.emissive = 0.0;
m.attenuation = 0.0;
return m;
}
Material makeEmissiveMaterial(float3 emissive) {
Material m;
m.color = 0;
m.metallic = 0;
m.roughness = 0;
m.emissive = emissive;
m.attenuation = 0.0;
return m;
}
Material makeWaterMaterial(float3 attenuation, float eta = 1.1, float roughness = 0.3) {
Material m;
m.color = 0.3;
m.emissive = 0;
m.metallic = 1;
m.roughness = roughness;
m.attenuation = float4(attenuation, 1);
m.eta = eta;
return m;
}
Material makeStrangeMaterial(float3 p, int seed) {
float3 p1 = p + (0.009999999776 * fpn(p*1114.949951));
float3 p2 = p1 + (0.05000000075 * fpn(p1*228.9993286));
float3 p3 = p2 + (13.84500122 * fpn(p2*12.5));
float black = fpn(p3*16.49999237) * 0.5 + 0.5;
const float3 colors[3] = {
float3(1,0.2,0.0),
float3(0.5,0.8,0.1),
float3(1.0,1.0,1.0)
};
float3 color = lerp(
colors[(2+seed)%3],
lerp(
colors[(0+seed)%3],
colors[(1+seed)%3], fpn((p3+p2)*15) * 0.5 + 0.5
), fpn(p3*10) * 0.5 + 0.5
);
Material marble;
marble.emissive = 0;
marble.color = color * black;
marble.metallic = 1.0;
marble.roughness = saturate(black * -0.55 + 0.5);
marble.attenuation = float4(3 * saturate(1 - color), 1);
marble.eta = 1.2;
return marble;
}
Material makeMarbleMaterial(float3 p, int seed) {
float3 p1 = p + (0.009999999776 * fpn(p*1114.949951));
float3 p2 = p1 + (0.05000000075 * fpn(p1*228.9993286));
float3 p3 = p2 + (13.84500122 * fpn(p2*12.5));
float black = fpn(p3*16.49999237) * 0.5 + 0.5;
const float3 colors[3] = {
float3(1,0.2,0.0),
float3(0.5,0.8,0.1),
float3(1.0,1.0,1.0)
};
float3 color = lerp(
colors[(2+seed)%3],
lerp(
colors[(0+seed)%3],
colors[(1+seed)%3], fpn((p3+p2)*15) * 0.5 + 0.5
), fpn(p3*10) * 0.5 + 0.5
);
Material marble;
marble.emissive = 0;
marble.color = color * black;
marble.metallic = 0;
marble.roughness = saturate(black * -0.55 + 0.5);
marble.attenuation = 0;
return marble;
}
Material makeErrorTestMaterial(float3 p) {
int seed = 0;
float3 p1 = p + (0.009999999776 * fpn(p*1114.949951));
float3 p2 = p1 + (0.05000000075 * fpn(p1*228.9993286));
float3 p3 = p2 + (13.84500122 * fpn(p2*12.5));
float black = fpn(p3*16.49999237) * 0.5 + 0.5;
const float3 colors[3] = {
float3(1,0.2,0.0),
float3(0.5,0.8,0.1),
float3(1.0,1.0,1.0)
};
float3 color = lerp(
colors[(2+seed)%3],
lerp(
colors[(0+seed)%3],
colors[(1+seed)%3], fpn((p3+p2)*15) * 0.5 + 0.5
), fpn(p3*10) * 0.5 + 0.5
);
Material marble;
marble.emissive = 0;
marble.color = sin(p.z)*0.5 + 0.5;//color * black;
marble.metallic = 0;
marble.roughness = 0.3;//saturate(black * -0.55 + 0.5);
marble.attenuation = 0;
return marble;
}
#endif

View File

@@ -0,0 +1,25 @@
#ifndef OGL2DX
#define OGL2DX
#define vec4 float4
#define vec3 float3
#define vec2 float2
#define ivec4 int4
#define ivec3 int3
#define ivec2 int2
#define uvec4 uint4
#define uvec3 uint3
#define uvec2 uint2
float atan(float y, float x) {
return atan2(y, x);
}
#define mix lerp
#define fract frac
#include "utils.hlsl"
#endif

View File

@@ -0,0 +1,395 @@
cbuffer cb0 : register(b0) {
float time;
float dummy0, dummy1, dummy2;
float3 viewPosition;
float dummy3;
float3 viewDirection;
float dummy4;
float3 viewUp;
float dummy5;
}
#define FXAA_PC 1
#define FXAA_HLSL_5 1
#define FXAA_QUALITY__PRESET 39
//12
#include "fxaa311.hlsl"
#include "utils.hlsl"
RWTexture2D<float4> out0:register(u0);
SamplerState sampler0 : register(s0);
Texture2D tex0: register(t0);
Texture2D tex1: register(t1);
Texture2D tex2: register(t2);
Texture2D tex3: register(t3);
Texture2D tex4: register(t4);
Texture2D tex5: register(t5);
Texture2D tex6: register(t6);
Texture2D tex7: register(t7);
[numthreads(16, 16, 1)] void csFXAA(int3 id:SV_DispatchThreadID) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 tc = (id.xy + 0.5) / resolution;
FxaaTex tex = {sampler0 , tex0};
out0[id.xy] = FxaaPixelShader(tc, float4(0, 0, 0, 0), tex, tex, tex,
1.0/resolution, float4(0, 0, 0, 0), float4(0, 0, 0, 0), float4(0, 0, 0, 0),
0.75, 0.125, 0.0625, 0, 0, 0, 0);
}
//---
// Radial and circumferential blur
//---
static const float rcfMipmapFactor = 1.5;
static const float rcfStepFactor = 5;
static const float rcfStrengthRadial = 0*10;
static const float rcfStrengthCircumferential = 0*10;
static const float rcfRadius = 15;
static const float2 rcfCenter = {0.5, 0.5};
float rcfRadialFalloff(float radius, float amount) {
return radius * (1 + amount*radius*0.01);
}
float4 rcfBlur(float2 tc, float2 resolution, float strength, float circumFerentialStrength) {
// Direction from rcfCenter to the current tc, aspect ratio corrected
float2 d = (tc - rcfCenter) * float2(resolution.x/resolution.y, 1);
// Compute convolution step size
float delta = length(d);
float distortedDelta = rcfRadialFalloff(delta, strength);
float stepSize = abs(delta - distortedDelta) * rcfStepFactor;
float radius = rcfRadius;
// Circumferential blur
if (circumFerentialStrength > 0) {
d = float2(d.y, -d.x);
stepSize *= circumFerentialStrength;
radius = floor(rcfRadius * circumFerentialStrength);
}
// Early exit
if (radius <= 0.5) {// || stepSize <= 1/resolution.x) {
return tex0.SampleLevel(sampler0, tc, 0);
}
// Adjust direction
d = normalize(d) * stepSize / resolution;
// Convolution
float mipLevel = sqrt(stepSize) * rcfMipmapFactor;
float sigma = radius/2;
float twoSigmaSquared = 2 * sigma * sigma;
float4 a = 0;
for (float i = -radius; i <= radius; ++i) {
float weight = exp(-i*i/twoSigmaSquared);
a += tex0.SampleLevel(sampler0, i * d + tc, mipLevel) * weight;
}
return a / sqrt(twoSigmaSquared * PI);
}
[numthreads(16, 16, 1)] void csRadialBlur(int3 id:SV_DispatchThreadID) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 tc = (id.xy + 0.5) / resolution;
out0[id.xy] = rcfBlur(tc, resolution, rcfStrengthRadial, 0);
}
[numthreads(16, 16, 1)] void csCircumferentialBlur(int3 id:SV_DispatchThreadID) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 tc = (id.xy + 0.5) / resolution;
out0[id.xy] = rcfBlur(tc, resolution, rcfStrengthCircumferential, 1);
}
//---
// Sensor dirt
//---
[numthreads(16, 16, 1)] void csSensorDirt(int3 id:SV_DispatchThreadID) {
float2 tc = id.xy + .5;
}
//---
// Lens dirt
//---
static const float ldMinRadius = 0.025;
static const float ldMaxRadius = 0.075;
static const float ldCellWidth = 3*ldMaxRadius;
static const float ldBorderWidthHalf = 0.00125;
static const float ldSeed = 3;
static const float ldNumLayers = 4;
[numthreads(16, 16, 1)] void csLensDirt(int3 id:SV_DispatchThreadID) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 tc = (id.xy + 0.5) / resolution;
tc *= float2(resolution.x/resolution.y, 1);
//float2 tc = id.xy + .5;
rndSeed = ldSeed;
float4 a = 0;
for (int i = 0; i < ldNumLayers; ++i) {
// Modulo repeat, find cell
float2 p = mod(tc, ldCellWidth) - ldCellWidth / 2;
float2 c = floor(tc / ldCellWidth);
// Backup seed
uint seedBackup = rndSeed;
// Modifiy seed with cell coordinates
rndSeed += (c.x + c.y*ldCellWidth + i*ldCellWidth*ldCellWidth) * resolution.x;
// Determine radius and jitter
float r = lerp(ldMinRadius, ldMaxRadius, rnd());
p += float2(srnd(), srnd()) * (ldCellWidth / 2 - r);
// Shapes
// Hexagon
//p = abs(p);
//float d = max(p.y + p.x*0.57735, p.x*1.1547);
// Circle
//float d = length(p);
// Pentagon
//float phi = 0.145;
//float2 n[] = {
// { sin(0*PI/5 + phi), cos(0*PI/5 + phi) },
// { sin(2*PI/5 + phi), cos(2*PI/5 + phi) },
// { sin(4*PI/5 + phi), cos(4*PI/5 + phi) },
// { sin(6*PI/5 + phi), cos(6*PI/5 + phi) },
// { sin(8*PI/5 + phi), cos(8*PI/5 + phi) }
//};
//// Difference between circumcircle and incircle radii
//float delta = r - (1 + sqrt(5)) / 4 * r;
//float d = max(max(max(max(dot(p, n[0]), dot(p, n[1])), dot(p, n[2])), dot(p, n[3])), dot(p, n[4]));
//// Mix between sphere and pentagon
//d = lerp(length(p), d+ delta, 0.5);
float d = length(p);
// Random color
a += (float4(rnd(), rnd(), rnd(), 1) + 0.5) * (smoothstep(r, r - ldBorderWidthHalf * 2, d) + 0.25 * smoothstep(ldBorderWidthHalf, 0, abs(d - r + ldBorderWidthHalf * 2)));
//a += float4(c, 0, 1)*0.1;
// Restore seed
rndSeed = seedBackup;
// Displace grid
tc += ldCellWidth / ldNumLayers;
}
//out0[id.xy] = float4(a.xyz / ldNumLayers, 1);
out0[id.xy] = float4(a.xyz / ldNumLayers, 1);
}
//---
// Blur
//---
static const float bRadius = 160;
static const float bSigma = bRadius / 3.5;
static const float bTwoSigmaSquared = 2 * bSigma * bSigma;
void bBlur(int3 id, float2 direction) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 sourceResolution;
tex0.GetDimensions(sourceResolution.x, sourceResolution.y);
float mipLevel = log2(sourceResolution.x / resolution.x);
float2 tc = (id.xy + 0.5) / resolution;
float2 d = direction / resolution;
float4 a = 0;
for (float i = -bRadius; i <= bRadius; ++i) {
float weight = exp(-i*i/bTwoSigmaSquared);
a += tex0.SampleLevel(sampler0, i * d + tc, mipLevel) * weight;
}
out0[id.xy] = a / sqrt(bTwoSigmaSquared * PI);
}
[numthreads(16, 16, 1)] void csBlurH(int3 id:SV_DispatchThreadID) { bBlur(id, float2(1,0)); }
[numthreads(16, 16, 1)] void csBlurV(int3 id:SV_DispatchThreadID) { bBlur(id, float2(0,1)); }
//---
// Streaks
//---
static const float stRadius = 160;
[numthreads(16, 16, 1)] void csStreaks(int3 id:SV_DispatchThreadID) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 sourceResolution;
tex0.GetDimensions(sourceResolution.x, sourceResolution.y);
float mipLevel = log2(sourceResolution.x / resolution.x);
float2 tc = (id.xy + 0.5) / resolution;
float2 d = float2(1, 0) / resolution;
// Convolution with parabolic tent filter
float4 a = 0;
for (float i = -stRadius+1; i < stRadius; ++i) {
float weight = (stRadius - abs(i)) * (stRadius - abs(i));
a += tex0.SampleLevel(sampler0, i * d + tc, mipLevel) * weight;
}
out0[id.xy] = a * 1.5 / (stRadius * stRadius * stRadius);
}
//---
// Distort Chroma
//---
static const float dcStrength = 0.0;
static const float2 dcCenter = {0.5, 0.5};
static const int dcSamples = 24;
float dcRadialFalloff(float radius, float amount) {
return radius * (1 + amount*radius*0.01);
}
float4 dcSample(float2 tc, float amount, float2 resolution) {
// Direction from cdCenter to the current tc, aspect ratio corrected
float2 d = (tc - dcCenter) * float2(resolution.x/resolution.y, 1);
float radius = length(d);
d /= radius == 0 ? d : radius;
return tex0.SampleLevel(sampler0, dcCenter + d * dcRadialFalloff(radius, amount) / float2(resolution.x/resolution.y, 1), 0);
}
[numthreads(16, 16, 1)] void csDistortChroma(int3 id:SV_DispatchThreadID) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 tc = (id.xy + 0.5) / resolution;
float4 original = tex0.SampleLevel(sampler0, tc, 0);
if (dcStrength == 0) {
out0[id.xy] = original;
return;
}
// Accumulate along spectrum
float4 a = 0;
for (int i = 1; i <= dcSamples; ++i) {
float lambda = 0.4f * (i/float(dcSamples+1)) + 0.35f;
float4 w = float4(pulse(0.65, 0.1, lambda), pulse(0.55, 0.1, lambda), pulse(0.45, 0.1, lambda), 0.25) * 4.0;
a += w * dcSample(tc, -(i-1)/float(dcSamples) * dcStrength , resolution);
}
a /= dcSamples;
out0[id.xy] = lerp(original, a, saturate(dcStrength));
}
//---
// Ghosts
//---
float4 ghRainbow(float angle) {
return float4(sin(angle), sin(angle + 3.1415*2.0/3.0), sin(angle + 3.1415*4.0/3.0), 1) * 0.5 + 0.5;
}
[numthreads(16, 16, 1)] void csGhosts(int3 id:SV_DispatchThreadID) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 tc = (id.xy + 0.5) / resolution;
tc = 1 - tc;
float2 texelSize = 1 / resolution;
float2 aspectCorrection = float2(resolution.x/resolution.y, 1);
float2 direction = (0.5 - tc) * 2;
float4 a = 0;
for (int i = 0; i < 5; ++i) {
float2 sc0 = 1 - frac(tc + direction * i * 0.2);
float2 sc1 = 1 - frac(tc + direction * i * 0.1999);
float r = length((sc0 - 0.5) * aspectCorrection);
a += max(0, tex0.SampleLevel(sampler0, sc0, 0) - 0.125) * lerp(1, ghRainbow(r*20), 1.5*r);
a += max(0, tex1.SampleLevel(sampler0, sc0, 0) - 0.125) * lerp(1, ghRainbow(r*15+i), 1.5*r);
}
out0[id.xy] = float4(a.xyz/5, 1);
}
//---
// Merge
//---
float3 saturation(float3 color, float saturation) {
return lerp(dot(color, float3(0.2126, 0.7152, 0.0722)), color, saturation);
}
float3 liftGammaGain(float3 color, float3 lift, float3 gamma, float3 gain) {
return pow(saturate(gain*color + lift*(-gain*color + 1)), 1/gamma);
}
[numthreads(16, 16, 1)] void csMerge(int3 id:SV_DispatchThreadID) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 tc = (id.xy + 0.5) / resolution;
rndSeed = (id.y * 720 + id.x) * int(time * 1000);
float3 rndNoiseXYT = float3(rnd(), rnd(), rnd());
rndSeed = id.y;
float3 rndNoiseY = float3(rnd(), rnd(), rnd());
float3 base = tex0.SampleLevel(sampler0, tc, 0).xyz;
float3 blur1 = tex1.SampleLevel(sampler0, tc, 0).xyz;
float3 blur8 = tex2.SampleLevel(sampler0, tc, 0).xyz;
float3 blur32 = tex3.SampleLevel(sampler0, tc, 0).xyz;
float3 streaks = tex4.SampleLevel(sampler0, tc, 0).xyz;
//float3 lensDirt = tex5.SampleLevel(sampler0, tc, 0).xyz;
//float3 ghosts = tex6.SampleLevel(sampler0, tc, 0).xyz;
float3 color = base.xyz;
color += blur1 * 0.025;
color += blur8 * 0.025;
color += blur32 * 0.025;
// Streaks
color += streaks * (lerp(1, rndNoiseY.x, 0.25)) * 0.25;// * rnd();
// Lens dirt
//color += lensDirt * 0.25 * max(0, dot(tex2.SampleLevel(sampler0, frac(1-tc), 0).xyz, float3(0.299, 0.587, 0.114)) - 1.0);
// Ghosts
//color += ghosts * 0.125;// * ghosts * 0.25;
// Grain
//color *= lerp(1, rndNoiseXYT, 0.35);
//color = base;
// Tonemapping
color = max(0, uncharted2ToneMappingCompact(max(0, color*0.5)));
//color *= color;
color = liftGammaGain(color, float3(0, 0, 0), float3(1, 1, 1), float3(1, 1, 1));
//color = saturation(color, 1.5);
color = pow(color, 1/2.2);
float4 result = float4(color, dot(color, float3(0.299, 0.587, 0.114)));
out0[id.xy] = result;
}

View File

@@ -0,0 +1,581 @@
cbuffer cb0 : register(b0) {
float time;
float dummy0, dummy1, dummy2;
float3 viewPosition;
float dummy3;
float3 viewDirection;
float dummy4;
float3 viewUp;
float dummy5;
}
//#include "ogl2dx.hlsl"
#include "utils.hlsl"
#include "lighting.hlsl"
#include "material.hlsl"
#include "sdf.hlsl"
RWTexture2D<float4> out0:register(u0);
SamplerState sampler0:register(s0);
Texture2D tex0:register(t0);
//---
// Settings
//---
#define NUM_ST_ITERATIONS 80
#define NUM_ST_ITERATIONS_REFLECTIONS 80
#define NUM_ST_ITERATIONS_REFRACTIONS 80
#define USE_SOR
#define SOR_OMEGA 1.3
#define USE_ERROR_SMOOTHING
#define NUM_ERROR_SMOOTHING_ITERATIONS 3
#define _USE_ERROR_SMOOTHING_ALONG_NORMAL
#define NUM_REFRACTIONS 8
#define NUM_REFLECTIONS 2
//#define NUM_REFRACTIONS 0
//#define NUM_REFLECTIONS 0
#define FOV 45
static const float3 lightPosition = float3(-0.5,5.5,5);
static const float lightSize = 0.75;
static const float3 lightColor = 10*float3(1,0.8,0.7);
#define GRADIENT_EPSILON_THRESHOLD 0.00045
#define GRADIENT_EPSILON_MINIMUM 0.0004
#define POSITION_EPSILON_THRESHOLD 0.0045
#define POSITION_EPSILON_MINIMUM 0.004
float FJewels(float3 p, bool evaluateMaterial, bool evaluateGradient) {
float dGround = p.y + 1.65;
float dOuterSphere = -fSphere(p, 10);
float w = 2 * PI/3;
float wo = 0*time*0.3;
float3 pLasBlob = p - 1.85 * float3(sin(w*2+wo), 0, cos(w*2+wo));
float3 pIcosahedron = p - 1.85 * float3(sin(w*1+wo), 0.1, cos(w*1+wo));
float3 pCrystal = mul(rotX(0.6+0.05), mul(rotX(-PI/5), (p - 2 * float3(sin(w*3+wo), 0, cos(w*3+wo))).xzy).zyx);
//pLasBlob = mul(rotX(time*0.25 + pLasBlob.x*sin(time)*0.125), pLasBlob);
float dLasBlob = (fLasBlob(pLasBlob));
//if (abs(dLasBlob) < 0.02)
// dLasBlob += fpn(p*150)*0.0045;
//dLasBlob *= evaluateGradient ? 1 : 0.67;
float dIcosahedron = fIcosahedron(pIcosahedron, 1.4, 30);
dIcosahedron *= (evaluateGradient ? 1.025 : 1);
float dCrystal = fCrystal(pCrystal, 1);
float dCrystalSoft = fCrystal(pCrystal, 1, 40);
dCrystalSoft *= (evaluateGradient ? 1.025 : 1);
dCrystal = lerp(dCrystal, dCrystalSoft, 0.4);
float d = INFINITY;
minMaterial(d, dGround, evaluateMaterial, makeDiffuseMaterial(float3(0.5,0.5,0.5)));
minMaterial(d, dOuterSphere, evaluateMaterial, makeDiffuseMaterial(float3(0.5,0.5,0.5)));
minMaterial(d, dCrystalSoft, evaluateMaterial, makeWaterMaterial(float3(0.1, 1.9, 0.5), 1.5, 0.0));
minMaterial(d, dLasBlob, evaluateMaterial, makeWaterMaterial(float3(0.1, 0.5, 1.9), 1.1, 0.2));
minMaterial(d, dIcosahedron, evaluateMaterial, makeWaterMaterial(float3(1.9, 0.5, 0.1), 1.3));
return d;
}
float fLaserEmitter(float3 p, float dScene, bool evaluateMaterial){
float radius = length(p.xz);
float h = radius - 1.5;
h = max(h, p.y);
if (h > 0.1)
return h;
float shaft = radius - 1;
shaft = max(shaft, 0.8-radius);
shaft = fOpDivideD(shaft, -p.y, 0.05);
//shaft = max(shaft, p.y);
float angle = 2*3.1415926/12;
float angle2 = 2*3.1415926/48;
float at = atan2f(p.z,p.x);
float a = at + angle*0.5;
float a2 = at + angle2*0.5;
a = mod(a, angle) - angle*0.5;
a2 = mod(a2, angle2) - angle2*0.5;
p.xz = float2(cos(a), sin(a)) * radius;
float3 p2 = float3(cos(a2) * radius, p.y , sin(a2) * radius);
float3 q = p;
p += float3(-0.9, 0.3, 0.0);
p.z = abs(p.z);
p.x -= 0.2;
p.z -= 0.3;
shaft = max(shaft, 0.2 - length(p.xz));
q += float3(-1, 10+2, 0);
float ring = fBox(q, float3(0.35, 10+0.2, 0.4));
ring = fOpCombineD(ring, fBox(q,float3(0.5, 10+0.3, 0.2)), 0.05);
//ring = min(ring, fBox(q,float3(0.5, 10+0.3, 0.2)));
q.x -= 0.1;
p2.x -= 0.8;
shaft = max(shaft, 0.03 - length(p2.xz));
shaft = min(shaft, ring);
p += float3(-0.2, 0.6, 0.25);
//if (p.x < p.y*2.5)
// fOpR45(p.xy);//p.xy = p.yx;
p = fOpBend(p.yxz, -PI/4, 0, 0, 0.25).yxz;
float pipe = length(p.xz) - 0.047;
pipe = max(pipe,-0.2 - q.x);
minMaterial(dScene, shaft, evaluateMaterial, makeDiffuseMaterial(float3(0.8, 0.9, 1)));
//shaft = fOpCombineD(shaft, pipe, 0.01);
//shaft = min(shaft, pipe);
minMaterialTransmissive(shaft, pipe, evaluateMaterial, makeWaterMaterial(8*float3(0.1, 0.5, 1.9), 1.3, 0.25));
return shaft;// * (evaluateGradient ? 1 : 0.9);
}
float FScreenSpaceMetric(float3 p, bool evaluateMaterial, bool evaluateGradient) {
float dGround = p.y + 2.05;
float dOuterSphere = -fSphere(p, 20);
float dLasBlob = fLasBlob(p) * (evaluateGradient ? 1 : 0.67);
//float dSphere = fSphere(p, 1);
float dBox = fBox(p - float3(0,0,0), float3(1,1,1)) - 0.0;
float dSchale = max(max(fSphere(p - float3(0, 1, 0), 2), -fSphere(p - float3(0, 1.1, 0), 1.95)), p.y - 1.7) * (evaluateGradient ? 1 : 0.9);
float dIcosahedron = fIcosahedron(p, 1.4, 30) * (evaluateGradient ? 1 : 0.9);
float dStar = fStar(p, 1);
float d = INFINITY;
minMaterial(d, dGround, evaluateMaterial, makeDiffuseMaterial(3*float3(0.5,0.5,0.5)));
minMaterial(d, dOuterSphere, evaluateMaterial, makeDiffuseMaterial(3*float3(0.5,0.5,0.5)));
minMaterial(d, dSchale, evaluateMaterial, makeErrorTestMaterial(p*float3(0.25,0.25,200)));
return d;
}
float FPinkBlob(float3 p, bool evaluateMaterial, bool evaluateGradient) {
float dGround = p.y + 2.05;
float dOuterSphere = -fSphere(p, 10);
float dLasBlob = fLasBlob(p);
//if (abs(dLasBlob) < 0.02)
// dLasBlob += fpn(p*150)*0.0045;
//dLasBlob *= evaluateGradient ? 1 : 1;
float d = INFINITY;
minMaterial(d, dGround, evaluateMaterial, makeDiffuseMaterial(float3(0.5,0.5,0.5)));
minMaterial(d, dOuterSphere, evaluateMaterial, makeDiffuseMaterial(float3(0.5,0.5,0.5)));
minMaterial(d, dLasBlob, evaluateMaterial, makeWaterMaterial(float3(0.1, 1.9, 0.5), 1.1));
return d;
}
float F(float3 p, bool evaluateMaterial, bool evaluateGradient) {
//return FSmoothErrorMaterial(p, evaluateMaterial, evaluateGradient);
//return FSmoothErrorSphere(p, evaluateMaterial, evaluateGradient);
//return FScreenSpaceMetric(p, evaluateMaterial, evaluateGradient);
//return FJewels(p, evaluateMaterial, evaluateGradient);
//return FPinkBlob(p, evaluateMaterial, evaluateGradient);
//return FCity(p, evaluateMaterial, evaluateGradient);
//if (!evaluateGradient)
// p = fOpVoxelize(p, 0.015);
float d = INFINITY;
float dOuterBox = -fBoxNonEuclidean(p, float3(10, 10, 10));
minMaterial(d, dOuterBox, evaluateMaterial, makeDiffuseMaterial(float3(0.5, 0.5, 0.5)));
//p = fOpBend(p.yzx, PI / 4 * sin(0.1 * time * PI), 0, -0.5, 0.5).zxy;
//p = fOpBend(p.yxz, PI / 4 * cos(0.1 * time * PI), 0, -0.5, 0.5).yxz;
//float dHG = fAkleman(p, 1, 13, 17);// fHG(p);
// float dHG = fHexagon(p, float2(1, 1));// = fSphere(p, 2);//fPentagonalTrapezohedron(p, 1, 20);//
//p = fOpBend(p.yzx, PI / 4 * sin(0.1 * time * PI), 0, -0.5, 0.5).zxy;
//float dX = fHelix(p.yxz + float3(0*0.5*time, 0, 0), 0.6, 0.6) - 0.2;
float dHG = fLasBlob(p);
minMaterialTransmissive(d, dHG, evaluateMaterial, makeWaterMaterial(1 * float3(0.0, 0.3333, 1.0), 1.1));
//float omega = 2*PI/8;
//float theta = atan2f(p.z,p.x);
//float phi = mod(omega*0.5 + theta, omega) - omega*0.5;
//p.xz = float2(cos(phi), sin(phi)) * length(p.xz);
//p.x -= 3;
//p = fOpBend(p.yxz, PI/3, -2, -2, 2).yxz;
//
//float dSpiralA = fHelix(p.yxz + float3(0*0.5*time, 0, 0), 0.6, 0.6);//fGlass(p);
//dSpiralA = dSpiralA - 0.175;//max(dSpiralA - 0.175, -dSpiralA + 0.125);
//float dCylinder = fCylinder(p, 0.4);//fSpiral(p.yxz + float3(0.5, 0, 0), 0.5, 0.5) - 0.05;
//
//float phi = atan2f(p.x, p.z) + PI;
//float x = abs(frac(12*phi/(2*PI) - p.y*5) - 0.5);
//x = smoothstep(0.24, 0.26, x) * 0.5 + 0.5;
//
//minMaterial(d, dCylinder, evaluateMaterial, makeEmissiveMaterial(100 * x * float3(1, 0.1, 0.01)));
//if (abs(dSpiralA) < 0.0025)
// dSpiralA += fpn(p*500) * 0.000625;
//minMaterialTransmissive(d, dSpiralA + 0.1, evaluateMaterial, makeWaterMaterial(2*float3(8, 8., 1.), 1/1.1));
//minMaterialTransmissive(d, dSpiralA, evaluateMaterial, makeWaterMaterial(10*float3(0.1, 0.1, 0.1), 1.1));
return d;
}
float fMaterial(float3 p) {
return F(p, true, false);
}
float fGradient(float3 p) {
return F(p, false, true);
}
float f(float3 p) {
return F(p, false, false);
}
float3 gradient(float3 p, float epsilon) {
const float3 e[] = {
{+epsilon, 0, 0}, {-epsilon, 0, 0},
{0, +epsilon, 0}, {0, -epsilon, 0},
{0, 0, +epsilon}, {0, 0, -epsilon}
};
float g[6];
for (int i = 0; i < 6; ++i)
g[i] = fGradient(p + e[i]);
return float3(g[0]-g[1], g[2]-g[3], g[4]-g[5]);
}
float hessianSample(float3 p, float3 e, float h) {
return (f(p + h*e) - 2 * f(p) + f(p - h*e)) / (h*h);
}
float hessianSample(float3 p, float3 ei, float3 ej, float h) {
return (f(p + h*ei + h*ej) - f(p + h*ei - h*ej) + f(p - h*ei - h*ej) - f(p - h*ei + h*ej)) / (4*h*h);
}
float3x3 hessian(float3 p, float epsilon) {
float3 X = float3(1, 0, 0);
float3 Y = float3(0, 1, 0);
float3 Z = float3(0, 0, 1);
float3 D = float3(
hessianSample(p, X, epsilon),
hessianSample(p, Y, epsilon),
hessianSample(p, Z, epsilon)
);
float3 O = float3(
hessianSample(p, X, Y, epsilon),
hessianSample(p, Y, Z, epsilon),
hessianSample(p, Z, X, epsilon)
);
return float3x3(
D.x, O.x, O.z,
O.x, D.y, O.y,
O.z, O.y, D.z
);
}
float gaussianCurvature(float3 p, float3 gradient, float epsilon) {
float3x3 H = hessian(p, epsilon);
return dot(mul(cofactorMatrix(H), gradient), gradient);
}
float meanCurvature(float3 p, float3 gradient, float epsilon) {
float3x3 H = hessian(p, epsilon);
float traceH = H[0][0] + H[1][1] + H[2][2];
return -dot(mul(H, gradient), gradient) + traceH;
}
float specularOcclusion(float3 p, float3 d, float dotNV, float stepSize, float numSteps) {
float a = 1, e = 1;
for (float i = 1; i <= numSteps; ++i)
a -= (i * dotNV * stepSize - abs(f(p + d * i * stepSize)))/(e*=2);
return saturate(a);
}
float ambientOcclusion(float3 p, float3 d, float stepSize, float numSteps) {
float a = 1, e = 1;
for (float i = 1; i <= numSteps; ++i)
a -= (i * stepSize - abs(f(p + d * i * stepSize)))/(e*=2);
return saturate(a);
}
float3 computeMaterialColor(float3 p, float3 d, float3 n, float gradientError) {
float ao = ambientOcclusion(p, n, 0.3, 4);
float3 r = reflect(d, n);
float dotNV = saturate(-dot(n, d));
float so = specularOcclusion(p, r, dotNV, 0.1, 4); so *= so;
float roughness = saturate(max(material.roughness, gradientError));
float metallic = material.metallic;
float f0 = lerp(0.04, 1.0, metallic);
float3 specular = lerp(1, material.color, metallic) * lerp(1, ao, roughness) * so;
float3 albedo = lerp(material.color, 0, metallic) * ao;
float3 color = brdfSphereLight(p, n, -d, r, lightPosition, lightSize, albedo, specular, roughness, f0) * lightColor;
color += material.emissive;
return color;
}
float3 getNormalAndGradientError(float3 p, float error, out float gradientError) {
float gradientEpsilon = max(abs(error), GRADIENT_EPSILON_MINIMUM);
float3 g = gradient(p, gradientEpsilon);
float gradientLength = length(g);
gradientError = (1-saturate((gradientLength/(2*gradientEpsilon))));
return g / gradientLength;
}
void smoothErrorAlongDirection(float3 o, float3 d, float functionSign, float pixelRadius, inout float3 p, inout float error) {
for (int i = 0; i < NUM_ERROR_SMOOTHING_ITERATIONS; ++i) {
p -= functionSign * d * (error - f(p));
error = pixelRadius * functionSign * distance(o, p);
}
}
void smoothErrorAlongNormal(float3 o, float3 n, float functionSign, float pixelRadius, inout float3 p, inout float error) {
for (int i = 0; i < NUM_ERROR_SMOOTHING_ITERATIONS; ++i) {
p += n * (error - f(p));
error = pixelRadius * functionSign * distance(o, p);
}
}
#define ST_T(X) (X).x
#define ST_SIGN(X) ((X).y < 0 ? -1 : +1)
#define ST_ABS_RADIUS(X) abs((X).y)
#define ST_RADIUS(X) (X).y
#define ST_HIT(X) ((X).x != INFINITY)
float2 sphereTrace(float3 o, float3 d, float tmax, float pixelRadius, int numIterations, bool forceHit) {
float tmin = 0.0001;
float omega = SOR_OMEGA, t = tmin, previousRadius = 0, stepLength = 0;
float functionSign = f(o) < 0 ? -1 : +1;
float2 intersection = {0, INFINITY};
for (int i = 0; i < numIterations; ++i) {
float signedRadius = functionSign * f(d*t + o);
float radius = abs(signedRadius);
#ifdef USE_SOR
bool sorFail = omega > 1 && radius + previousRadius < stepLength;
if (sorFail) {
stepLength = stepLength - omega * stepLength;
omega = 1;
} else {
stepLength = signedRadius * omega;
}
#else
stepLength = signedRadius;
#endif
previousRadius = radius;
float screenSpaceError = radius / t;
#ifdef USE_SOR
if (!sorFail && screenSpaceError < intersection.y)
intersection = float2(t, screenSpaceError);
if (!sorFail && screenSpaceError < pixelRadius || t > tmax)
break;
#else
if (screenSpaceError < intersection.y)
intersection = float2(t, screenSpaceError);
if (screenSpaceError < pixelRadius || t > tmax)
break;
#endif
t += stepLength;
}
return float2((t > tmax || intersection.y > pixelRadius) && !forceHit ? INFINITY : intersection.x,
functionSign * max(intersection.x * intersection.y, POSITION_EPSILON_MINIMUM));
}
float3 traceReflections(float3 o, float3 d, float3 n, float2 h, float pixelRadius) {
bool reflective = true;
float3 pathThroughput = 1;
float3 a = 0;
[fastopt] for (int i = 0; i < NUM_REFLECTIONS && reflective; ++i) {
pathThroughput *= saturate(1 - transmittance(d, n, 1, material.eta));
d = reflect(d, n);
o += n * ST_ABS_RADIUS(h);
h = sphereTrace(o, d, 30, pixelRadius, NUM_ST_ITERATIONS_REFLECTIONS, true);
if (!ST_HIT(h))
break;
float3 p = d * ST_T(h) + o;
float error = pixelRadius * ST_SIGN(h) * ST_T(h);
#if defined(USE_ERROR_SMOOTHING) && !defined(USE_ERROR_SMOOTHING_ALONG_NORMAL)
smoothErrorAlongDirection(o, d, ST_SIGN(h), pixelRadius, p, error);
#endif
float gradientError;
n = getNormalAndGradientError(p, error, gradientError);
#if defined(USE_ERROR_SMOOTHING) && defined(USE_ERROR_SMOOTHING_ALONG_NORMAL)
smoothErrorAlongNormal(o, n, ST_SIGN(h), pixelRadius, p, error);
#endif
ST_RADIUS(h) = ST_SIGN(h) * max(abs(fMaterial(p)), POSITION_EPSILON_MINIMUM);
reflective = isReflectiveMaterial(material);
n *= ST_SIGN(h);
if (!reflective)
a = pathThroughput * computeMaterialColor(p, d, n, gradientError);
o = p;
}
return a;
}
float3 traceRefractions(float3 o, float3 d, float3 n, float2 h, float pixelRadius) {
bool refractive = true;
float3 pathThroughput = 1;
float3 a = 0;
[fastopt] for (int i = 0; i < NUM_REFRACTIONS && refractive; ++i) {
float eta1 = 1.0, eta2 = material.eta;
if (ST_SIGN(h) < 0)
eta1 = material.eta, eta2 = 1.0;
pathThroughput *= saturate(transmittance(d, n, eta1, eta2));
float3 nd = refract(d, n, eta1/eta2);
bool tir = abs(dot(nd, nd)) == 0;
d = tir ? reflect(d, n) : nd;
o -= 2 * n * (tir ? -1 : 1) * ST_ABS_RADIUS(h);
//if (tir) return float3(1,0,0);
h = sphereTrace(o, d, 30, pixelRadius, NUM_ST_ITERATIONS_REFRACTIONS, true);
if (!ST_HIT(h))
break;
float3 p = d * ST_T(h) + o;
float error = pixelRadius * ST_SIGN(h) * ST_T(h);
#if defined(USE_ERROR_SMOOTHING) && !defined(USE_ERROR_SMOOTHING_ALONG_NORMAL)
smoothErrorAlongDirection(o, d, ST_SIGN(h), pixelRadius, p, error);
#endif
float gradientError;
n = getNormalAndGradientError(p, abs(error), gradientError);
if (ST_SIGN(h) < 0)
pathThroughput *= exp(-ST_T(h) * material.attenuation.xyz);
#if defined(USE_ERROR_SMOOTHING) && defined(USE_ERROR_SMOOTHING_ALONG_NORMAL)
smoothErrorAlongNormal(o, n, ST_SIGN(h), pixelRadius, p, error);
#endif
//if (isnan(dot(pathThroughput, pathThroughput)) && isinf(dot(pathThroughput, pathThroughput)))
// return float3(1, 0, 1);
ST_RADIUS(h) = ST_SIGN(h) * max(abs(fMaterial(p)), POSITION_EPSILON_MINIMUM);
refractive = isRefractiveMaterial(material);
n = dot(d, n) > 0 ? -n : +n;
if (!refractive || (refractive && i <= 1)) {
a += computeMaterialColor(p, d, n, gradientError) * pathThroughput;
}
o = p;
}
return a;
}
float3 trace(float3 o, float3 d, float pixelRadius) {
float2 h = sphereTrace(o, d, 30, pixelRadius, NUM_ST_ITERATIONS, true);
float3 p = d * ST_T(h) + o;
//if (ST_T(h) == INFINITY)
// return float3(0, 1, 1);
float error = pixelRadius * ST_SIGN(h) * ST_T(h);
#if defined(USE_ERROR_SMOOTHING) && !defined(USE_ERROR_SMOOTHING_ALONG_NORMAL)
smoothErrorAlongDirection(o, d, ST_SIGN(h), pixelRadius, p, error);
#endif
float gradientError;
float3 n = getNormalAndGradientError(p, error, gradientError) * ST_SIGN(h);
#if defined(USE_ERROR_SMOOTHING) && defined(USE_ERROR_SMOOTHING_ALONG_NORMAL)
smoothErrorAlongNormal(o, n, ST_SIGN(h), pixelRadius, p, error);
#endif
ST_RADIUS(h) = ST_SIGN(h) * max(abs(fMaterial(p)), POSITION_EPSILON_MINIMUM);
float3 color = computeMaterialColor(p, d, n, gradientError);
Material backupMaterial = material;
if (isRefractiveMaterial(backupMaterial)) {
color += traceRefractions(p, d, dot(d, n) > 0 ? -n : +n, h, pixelRadius);
}
if (isReflectiveMaterial(backupMaterial)) {
color += traceReflections(p, d, n, h, pixelRadius);
}
if (ST_SIGN(h) < 0)
color *= exp(-ST_T(h) * backupMaterial.attenuation.xyz);
//float gradientEpsilon = thresholdedIdentity(abs(error), GRADIENT_EPSILON_THRESHOLD, GRADIENT_EPSILON_MINIMUM);
//float gCurvature = gaussianCurvature(p, n, gradientEpsilon * 2);
//float mCurvature = meanCurvature(p, n, gradientEpsilon * 2);
//
//float k1 = mCurvature + sqrt(mCurvature * mCurvature - gCurvature);
//float k2 = 2 * mCurvature - k1;
//float curvature = k2;
//color = abs(curvature) * (curvature < 0 ? float3(1, 0, 0) : float3(0, 1, 0));
//color = normalize(n) * 0.5 + 0.5;
//color = abs(gradientError);
return color;
}
[numthreads(16, 16, 1)] void csRT(int3 id:SV_DispatchThreadID) {
float2 resolution;
out0.GetDimensions(resolution.x, resolution.y);
float2 tc = (id.xy + 0.5) / resolution;
float2 sc = (tc*2 - 1) * float2(resolution.x/resolution.y, -1.0);
float3 u = cross(viewDirection, viewUp);
float3 v = viewUp;
float3 w = -viewDirection;
float3 o = viewPosition;
float3 d = normalize(mul(transpose(float3x3(u, v, w)), float3(sc/2, -0.5/tan((.5*3.1415)*FOV/180.))));
float pixelRadius = tan((.5*3.1415)*FOV/180.)/resolution.y;
float3 color = trace(o, d, pixelRadius);
float4 result = float4(color, 1);
if (isnan(dot(result, result)) || isinf(dot(result, result))) {
out0[id.xy] = float4(0,1,0,1);
return;
}
out0[id.xy] = result;
}

View File

@@ -0,0 +1,463 @@
#ifndef SDF
#define SDF
#include "utils.hlsl"
static const float3 fAklemanVectors_[19] = {
{1.000, 0.000, 0.000},
{0.000, 1.000, 0.000},
{0.000, 0.000, 1.000},
{0.577, 0.577, 0.577},
{-0.577, 0.577, 0.577},
{0.577, -0.577, 0.577},
{0.577, 0.577, -0.577},
{0.000, 0.357, 0.934},
{0.000, -0.357, 0.934},
{0.934, 0.000, 0.357},
{-0.934, 0.000, 0.357},
{0.357, 0.934, 0.000},
{-0.357, 0.934, 0.000},
{0.000, 0.851, 0.526},
{0.000, -0.851, 0.526},
{0.526, 0.000, 0.851},
{-0.526, 0.000, 0.851},
{0.851, 0.526, 0.000},
{-0.851, 0.526, 0.000}
};
static const float3 fAklemanVectors[19] = {
normalize(float3(1, 0, 0)),
normalize(float3(0, 1, 0)),
normalize(float3(0, 0, 1)),
normalize(float3(1, 1, 1 )),
normalize(float3(-1, 1, 1)),
normalize(float3(1, -1, 1)),
normalize(float3(1, 1, -1)),
normalize(float3(0, 1, PHI+1)),
normalize(float3(0, -1, PHI+1)),
normalize(float3(PHI+1, 0, 1)),
normalize(float3(-PHI-1, 0, 1)),
normalize(float3(1, PHI+1, 0)),
normalize(float3(-1, PHI+1, 0)),
normalize(float3(0, PHI, 1)),
normalize(float3(0, -PHI, 1)),
normalize(float3(1, 0, PHI)),
normalize(float3(-1, 0, PHI)),
normalize(float3(PHI, 1, 0)),
normalize(float3(-PHI, 1, 0))
};
float3 fOpBend(float3 p) {
if (p.y > 0) {
p.xy = float2(length(p.xy), atan2f(p.y, p.x));
} else if (p.x < 0) {
p.xy *= -1;
p.y += 2 * asin(1);
}
return p;
}
float3 fOpBend(float3 p, float k, float s0) {
if (abs(k) < 0.01)
return p;
float sk = sign(k);
float r = 1/k;
float2 d = sk * float2(p.x - s0, r - p.y);
float a = atan2f(d.x, d.y);
return float3(a*r + s0, -length(d)*sk + r, p.z);
}
float3 fOpBend(float3 p, float angle, float s0, float sBegin, float sEnd) {
float k = angle / (sEnd - sBegin);
if (abs(k) < 0.0001)
return p;
float sk = sign(k);
float ak = abs(k);
float r = 1/k;
float2 d = sk * float2(p.x - s0, r - p.y);
float a = atan2f(d.x, d.y);
float2 boundary = (float2(sBegin, sEnd) - s0) * k;
float b = clamp(a, min(boundary.x, boundary.y), max(boundary.x, boundary.y));
float s = b*r + s0;
if (abs(a - b) > 0) {
float2 c = float2(cos(b), sin(b));
return float3(-sk * (c * d.x * float2(-1,1) + c.yx * d.y) + float2(s, r), p.z);
}
return float3(s, -length(d)*sk + r, p.z);
}
#define fOpR45(p) p = 0.7071 * p + 0.7071 * float2(p.y, -p.x)
float fOpIntersectD(float d1, float d2, float r) {
return (-d1 < r) && (-d2 < r) ? (d1 + r + d2) * sqrt(0.5) : max(d1,d2);
}
float fOpDivideD(float d1, float d2, float r) {
return fOpIntersectD(d1, -d2, r);
}
float fOpCombineD(float d1, float d2, float r) {
return (d1 < r) && (d2 < r) ? (d1 - r + d2) * sqrt(0.5) : min(d1,d2);
}
float3 fOpVoxelize(float3 p, float s) {
return floor(p/s + 0.5) * s;
}
float fTooth(float3 p) {
// x^4 + y^4 + z^4 - x^2 + y^2 + z^2
float d = dot(pow(p, 4), 1) - dot(pow(p, 2), 1);
// d/dx = 4x^3 - 2x
// d/dy = 4y^3 - 2y
// d/dy = 4z^3 - 2z
float3 g = 4*p*p*p - 2*p;
return d / length(g);
}
float fTeardrop(float3 p) {
float d = p.y*p.y*p.y*p.y + p.y*p.y*p.y + p.x*p.x + p.z*p.z;
float3 g = float3(2*p.x, -4*p.y*p.y*p.y - 3*p.y*p.y, 2*p.z);
return d / length(g);
}
float fKusnerSchmitt(float3 p) {
float d = (p.x*p.x + 3) * (p.y*p.y + 3) * (p.z*p.z + 3) - 32 * (p.x*p.y*p.z + 1);
// d/dx = 2 x (y^2+3) (z^2+3) - 32yz
// d/dy = 2 y (x^2+3) (z^2+3) - 32xz
// d/dy = 2 z (x^2+3) (y^2+3) - 32xy
float3 g = 2 * p.xyz * (p.yxx * p.yxx + 3) * (p.zzy * p.zzy + 3) - 32 * p.yxx * p.zzy;
return d / length(g);
}
float fSteinerRoman(float3 p) {
//x^2 + y^2 + z^2 - 1)^2 - ((z - 1)^2 - 2*x^2)*((z + 1)^2 - 2*y^2)
float d = (p.x*p.x + p.y*p.y + p.z*p.z - 1) * (p.x*p.x + p.y*p.y + p.z*p.z - 1) -
((p.z - 1) * (p.z - 1) - 2*p.x*p.x) * ((p.z + 1) * (p.z + 1) - 2*p.y*p.y);
float3 g = 4 * float3(p.x, p.y, 1) *
float3(
p.x*p.x - p.y*p.y + 2*p.z*(p.z + 1),
-p.x*p.x + p.y*p.y + 2*p.z*(p.z - 1),
p.x*p.x*(2*p.z + 1) + p.y*p.y*(2*p.z - 1)
);
return d / length(g);
}
float fTetrahedralSymmetry(float3 p) {
float d = (p.x*p.x + p.y*p.y + p.z*p.z) * (p.x*p.x + p.y*p.y + p.z*p.z) +
8*p.x*p.y*p.z - 10*(p.x*p.x + p.y*p.y + p.z*p.z) + 25;
float3 g = 4 * float3(
p.x*p.x*p.x + p.x*(p.y*p.y + p.z*p.z - 5) + 2*p.y*p.z,
p.y*(p.x*p.x + p.z*p.z - 5) + 2*p.x*p.z + p.y*p.y*p.y,
p.x*p.x*p.z + 2*p.x*p.y + p.z*(p.y*p.y + p.z*p.z - 5)
);
return d / max(16, length(g));
}
float fHyperbolicOctahedron(float3 p) {
float3 p23 = pow(p*p, 1.0/3.0);
float d = p23.x + p23.y + p23.z - 1;
float3 g = 2*p / (3*p23*p23);
return d / max(3, length(g));
}
float fMcMullenK3(float3 p) {
float d = (p.x*p.x + 1) * (p.y*p.y + 1) * (p.z*p.z + 1) +
8*p.x*p.y*p.z - 2;
float3 g = 2*p*(p.yxx*p.yxx + 1)*(p.zzy*p.zzy + 1) +
8*p.yxx*p.zzy;
return d / max(1, length(g));
}
float fAkleman(float3 p, float r, float e, int begin, int end) {
float d = 0;
[unroll] for (int i = begin; i <= end; ++i)
d += pow(abs(dot(p, fAklemanVectors[i])), e);
return pow(d, 1/e) - r;
}
float fAkleman(float3 p, float r, int begin, int end) {
float d = 0;
[unroll] for (int i = begin; i <= end; ++i)
d = max(d, abs(dot(p, fAklemanVectors[i])));
return d - r;
}
float fPowAkleman(float3 p, float e, int begin, int end) {
float d = 0;
[unroll] for (int i = begin; i <= end; ++i)
d += pow(abs(dot(p, fAklemanVectors[i])), e);
return d;
}
float fPyramid(float3 p, float r, float e) {
float d = 0;
[unroll] for (int i = 3; i <= 6; ++i)
d += pow(abs(dot(p, fAklemanVectors[i])), e);
d += pow(max(0, -dot(p - float3(0,0.95,0), float3(0,1,0))), e);
return pow(d, 1/e) - r;
}
float fCrystal(float3 p, float r, float e) {
float d = 0;
[unroll] for (int i = 0; i < 6; ++i) {
float w0 = (PI/3 * i), w1 = w0 + PI/6;
d += pow(max(0, -dot(p, normalize(float3(cos(w0), 0.75, sin(w0))))), e);
d += pow(max(0, +dot(p, normalize(float3(cos(w1), 1.5, sin(w1))))), e);
}
d += pow(max(0, dot(p + float3(0, 0.5, 0), float3(0,1,0))), e);
return pow(d, 1/e) - r;
}
float fCrystal(float3 p, float r) {
float d = 0;
[unroll] for (int i = 0; i < 6; ++i) {
float w0 = (PI/3 * i), w1 = w0 + PI/6;
d = max(d, -dot(p, normalize(float3(cos(w0), 0.75, sin(w0)))));
d = max(d, dot(p, normalize(float3(cos(w1), 1.5, sin(w1)))));
}
d = max(d, dot(p + float3(0, 0.5, 0), float3(0,1,0)));
return d - r;
}
float fPentagonalTrapezohedron(float3 p, float r, float e) {
float w = 2 * PI / 5;
float3 v[] = {
normalize((float3(sin(w * 0), 0.85, cos(w * 0)))),
normalize((float3(sin(w * 1), 0.85, cos(w * 1)))),
normalize((float3(sin(w * 2), 0.85, cos(w * 2)))),
normalize((float3(sin(w * 3), 0.85, cos(w * 3)))),
normalize((float3(sin(w * 4), 0.85, cos(w * 4)))),
};
float d = 0;
[unroll] for (int i = 0; i < 5; ++i)
d += pow(abs(dot(p, v[i])), e);
return pow(d, 1/e) - r;
}
float fPentagonalTrapezohedron(float3 p, float r) {
float w = 2 * PI / 5;
float3 v[] = {
normalize((float3(sin(w * 0), 0.85, cos(w * 0)))),
normalize((float3(sin(w * 1), 0.85, cos(w * 1)))),
normalize((float3(sin(w * 2), 0.85, cos(w * 2)))),
normalize((float3(sin(w * 3), 0.85, cos(w * 3)))),
normalize((float3(sin(w * 4), 0.85, cos(w * 4)))),
};
float d = 0;
[unroll] for (int i = 0; i < 5; ++i)
d = max(d, abs(dot(p, v[i])));
return d - r;
}
float fDodecahedron(float3 p, float r, float e) {
return fAkleman(p, r, e, 13, 18);
}
float fOctahedron(float3 p, float r, float e) {
return fAkleman(p, r, e, 3, 6);
}
float fIcosahedron(float3 p, float r, float e) {
return fAkleman(p, r, e, 3, 12);
}
float fTruncatedOctahedron(float3 p, float r, float e) {
return fAkleman(p, r, e, 0, 6);
}
float fTruncatedIcosahedron(float3 p, float r, float e) {
return fAkleman(p, r, e, 3, 18);
}
float fOctahedron(float3 p, float r) {
return fAkleman(p, r, 3, 6);
}
float fDodecahedron(float3 p, float r) {
return fAkleman(p, r, 13, 18);
}
float fIcosahedron(float3 p, float r) {
return fAkleman(p, r, 3, 12);
}
float fTruncatedOctahedron(float3 p, float r) {
return fAkleman(p, r, 0, 6);
}
float fTruncatedIcosahedron(float3 p, float r) {
return fAkleman(p, r, 3, 18);
}
float fBox(float3 p, float3 b){
float3 d = abs(p) - b;
return length(max(d, 0)) + min(max(max(d.x, d.y), d.z), 0);
}
float fBoxNonEuclidean(float3 p, float3 b) {
float3 d = abs(p) - b;
return max(max(d.x, d.y), d.z);
}
float fCylinder(float3 p, float r) {
return length(p.xz) - r;
}
float fLineSegment(float3 p, float3 a, float3 b) {
float3 ab = b - a;
float t = saturate(dot(p - a, ab) / dot(ab, ab));
return length((ab*t + a) - p);
}
float fTorus(float3 p, float rInner, float rOuter) {
return length(float2(length(p.xz) - rInner, p.y)) - rOuter;
}
float fCircle(float3 p, float r) {
float l = length(p.xz) - r;
return length(float2(p.y, l));
}
float fDisc(float3 p, float r) {
float l = length(p.xz) - r;
return l < 0 ? abs(p.y) : length(float2(p.y, l));
}
float fCone(float3 p, float2 d) {
return dot(d, float2(length(p.xz), p.y));
}
float fHexagon(float3 p, float2 h) {
float3 q = abs(p);
return max(q.y - h.y, max(q.z*0.866025 + q.x*0.5, q.x) - h.x);
}
float fHelix(float3 p, float f, float r) {
float s = 0.5 * f / PI;
float x = PI * s;
float a = atan2f(p.z, p.y) * s;
float b = mod(p.x, 2*x);
a = abs(a-b);
a = a > x ? 2*x - a : a;
return length(float2(length(p.yz) - r, a));
}
float fDiscNonEuclidean(float3 p, float r) {
return max(length(p.xz) - r, abs(p.y));
}
float fSphere(float3 p, float r) {
return length(p) - r;
}
float fStar(float3 p, float r) {
float3 n0 = normalize(float3(-PHI, PHI-1, 1));
float3 n1 = normalize(float3(1, -PHI, PHI+1));
p = abs(p);
p -= 2 * max(0, dot(p, n0)) * n0;
p -= 2 * max(0, dot(p, n1)) * n1;
p = abs(p);
p -= 2 * max(0, dot(p, n0)) * n0;
p -= 2 * max(0, dot(p, n1)) * n1;
return p.y - r;
}
float fLasBlob(float3 p) {
p = abs(p);
if (p.x < max(p.y, p.z)) p = p.yzx;
if (p.x < max(p.y, p.z)) p = p.yzx;
float b = max(max(max(
dot(p, normalize(float3(1, 1, 1))),
dot(p.xz, normalize(float2(PHI+1, 1)))),
dot(p.yx, normalize(float2(1, PHI)))),
dot(p.xz, normalize(float2(1, PHI))));
float l = length(p);
return l - 1.6125 + 0.25 * (smoothstepQuintic(0.0, 0.343, sin(acos(b/l-0.0075))));
//return l - 1.5 + 1.5 * saturate(1-b/l); // Bluming
return l - 1.5 - 0.2 * (1.5 / 2)* cos(min(sqrt(1.01 - b / l)*(PI / 0.25), PI));
}
float fHG(float3 p, float depthFactor = 0.5) {
float hgUnit = 1.0 / 8.0;
float depth = hgUnit * depthFactor;
float d = INFINITY;
d = min(d, fBox(p - float3(0, 0, 0), float3(hgUnit * 4, hgUnit, depth)));
d = min(d, fBox(p - float3(0, -hgUnit * 2.5, 0), float3(hgUnit, hgUnit * 3.5, depth)));
p.x = abs(p.x);
d = min(d, fBox(p - float3(hgUnit * 7.5, 0, 0), float3(hgUnit * 0.5, hgUnit * 8, depth)));
d = min(d, fBox(p - float3(hgUnit * 3, hgUnit * 2.5, 0), float3(hgUnit, hgUnit * 3.5, depth)));
p.y = abs(p.y);
d = min(d, fBox(p - float3(0, hgUnit * 7.5, 0), float3(hgUnit * 8, hgUnit * 0.5, depth)));
d = min(d, fBox(p - float3(0, hgUnit * 3, 0), float3(hgUnit * 4, hgUnit, depth)));
return d;
}
float fGlass(float3 p) {
float l = length(p.xz);
float3 q = float3(l, p.y, 0);
q = fOpBend(q.yxz, PI/3, -0.25, -0.25, 0.0).yxz;
q = fOpBend(q.yxz, -PI/2, 0.0, 0.0, 1.5).yxz;
q = fOpBend(q.yxz, -PI/2, -0.75, -0.75, -1.5).yxz;
return fBox(q, float3(0.05-abs(q.y)*0.02, 1.5, 0.1)) * 0.8;
}
float fGummibaer(float3 p) {
if (length(p) > 1.41)
return length(p) - 1.4;
const float4 data[] = {
// Koerper
float4(1.0, 0.0, 0.0, 2.5),
float4(-1.0, 0.0, 0.0, 2.5),
float4(1.0, 2.0, 0.0, 2.5),
float4(-1.0, 2.0, 0.0, 2.5),
float4(1.0, 4.0, 0.0, 1.0),
float4(-1.0, 4.0, 0.0, 1.0),
// Arme / Beine
float4(1.5, -0.0, 1.5, 1.2),
float4(-1.5, -0.0, 1.5, 1.2),
float4(1.55, 2.0, 1.5, 0.0),
float4(-1.5, 2.0, 1.5, 0.0),
// Ohren
float4(1.3, 4.8, -0.2, 0.3),
float4(-1.3, 4.8, -0.2, 0.3),
// Gesicht
float4(-0.0, 4.0, 1.0, 0.0)
};
float globalScale = 0.1;
p /= globalScale;
p.y += 4.8 / 2;
float b = 0;
for (int i = 0; i < 13; ++i)
b += 0.5 - atan(length(p - 3 * data[i].xyz) - data[i].w) / PI;
return ((tan((-clamp(b, 0.0001, 0.78) - 0.5) * PI) + 1)) * globalScale;
}
#endif

View File

@@ -0,0 +1,202 @@
#ifndef UTILS
#define UTILS
#define USE_ATAN2_APPROXIMATION
#define PI 3.14159265
#define INFINITY 1000.0
#define PHI (sqrt(5)*0.5 + 0.5)
float3x3 rotX(float a) {
return float3x3 (1, 0, 0, 0, cos(a), -sin(a), 0, sin(a), cos(a));
}
float3x3 rotY(float a) {
return float3x3 (cos(a), 0, sin(a), 0, 1, 0, -sin(a), 0, cos(a));
}
float3x3 rotZ(float a) {
return float3x3 (cos(a), -sin(a), 0, sin(a), cos(a), 0, 0, 0, 1);
}
static uint rndSeed = 0;
void setRndSeed(uint seed) {
rndSeed = seed;
}
uint hash(uint x) {
x += x << 10, x ^= x >> 6, x += x << 3, x ^= x >> 11, x += x << 15;
return x;
}
float rnd() {
return asfloat((rndSeed = hash(rndSeed) & 0x007fffff) | 0x3f800000) - 1;
}
float srnd() {
return asfloat((rndSeed = hash(rndSeed) & 0x007fffff) | 0x40000000) - 3;
}
float rnd(uint s) {
return asfloat((s & 0x007fffff) | 0x3f800000) - 1;
}
float srnd(uint s) {
return asfloat((s & 0x007fffff) | 0x40000000) - 3;
}
float expf(float x) {
return asfloat(int(12102203 * x + 1064866805));
}
#ifdef USE_ATAN2_APPROXIMATION
float atan2f(float y, float x) {
float c0 = PI * 0.25;
float c1 = PI * 0.75;
float absY = abs(y);
float s = (x < 0 ? -1 : +1);
float r = (-absY*s + x) / (x*s + absY);
//float phi = -c0*r + (x < 0 ? c1 : c0);
float phi = (0.1963*r*r - 0.9817)*r + (x < 0 ? c1 : c0);
return phi * (y < 0 ? -1 : +1);
}
#else
#define atan2f atan2
#endif
float3x3 cofactorMatrix(float3x3 M) {
float3x3 R = {
M[1][1]*M[2][2] - M[1][2]*M[2][1], M[0][2]*M[2][1] - M[0][1]*M[2][2], M[0][1]*M[1][2] - M[0][2]*M[1][1],
M[1][2]*M[2][0] - M[1][0]*M[2][2], M[0][0]*M[2][2] - M[0][2]*M[2][0], M[0][2]*M[1][0] - M[0][0]*M[1][2],
M[1][0]*M[2][1] - M[1][1]*M[2][0], M[0][1]*M[2][0] - M[0][0]*M[2][1], M[0][0]*M[1][1] - M[0][1]*M[1][0]
};
return R;
}
float3x3 inverse(float3x3 M) {
return cofactorMatrix(M) / determinant(M);
}
float mod(float x, float y) {
return x - y * floor(x / y);
}
float2 mod(float2 x, float2 y) {
return x - y * floor(x / y);
}
float3 mod(float3 x, float3 y) {
return x - y * floor(x / y);
}
float2 mod(float2 x, float y) {
return x - y * floor(x / y);
}
float3 mod(float3 x, float y) {
return x - y * floor(x / y);
}
float thresholdedIdentity(float x, float threshold, float value) {
if (x > threshold) return x;
float u = x/threshold;
return ((2*value - threshold) * u + 2*threshold - 3*value) * u * u + value;
}
float smoothstepQuintic(float edge0, float edge1, float x) {
x = saturate((x - edge0) / (edge1 - edge0));
return x*x*x*(x*(x*6 - 15) + 10);
}
float3 smoothstepQuintic(float3 edge0, float3 edge1, float3 x) {
x = saturate((x - edge0) / (edge1 - edge0));
return x*x*x*(x*(x*6 - 15) + 10);
}
float pulse(float center, float width, float x) {
float t = abs(x - center);
if (t > width) return 0;
t /= width;
return 1 - t*t*(3 - 2 * t);
}
float3 hsv(float h, float s, float v) {
return lerp(1, saturate(abs(frac(h+float3(3, 2, 1)/3)*6 - 3) - 1), s) * v;
}
float3 hsvSmooth(float h, float s, float v) {
return lerp(1, smoothstep(0, 1, saturate(abs(frac(h + float3(3, 2, 1)/3)*6 - 3) - 1)), s) * v;
}
float3 fusion(float x) {
float t = saturate(x);
return saturate(float3(sqrt(t), t*t*t, max(sin(3.1415*1.75*t), pow(t, 12.0))));
}
float3 uncharted2ToneMapping(float3 c) {
float A = 0.15;
float B = 0.50;
float C = 0.10;
float D = 0.20;
float E = 0.02;
float F = 0.30;
float W = 11.2;
c = ((c * (A * c + C * B) + D * E) / (c * (A * c + B) + D * F)) - E / F;
float white = ((W * (A * W + C * B) + D * E) / (W * (A * W + B) + D * F)) - E / F;
return c / white;
}
float3 uncharted2ToneMappingCompact(float3 c) {
return c * (c*1.28713 + 0.153229) / (c*(c + 3.33333) + 0.4);
}
float4 hgTexture(float2 tc) {
float4 orange = float4(1, 0.111, 0, 1);
uint d[] = {
0x818180ff,
0x8f818f8f,
0x8f8f8c8f,
0xff808c8c
};
int2 c = floor(tc * 16);
if (c.x < 0 || c.x > 15 || c.y < 0 || c.y > 15)
return float4(0, 0, 0, 0);
if ((d[c.y / 4u] >> ((c.y % 4u) * 8u + uint(abs(c.x - 7.5)) % 8u)) & 1u)
return float4(1, 1, 1, 1);
return orange;
}
float fn(float3 p) {
float4 a = dot(floor(p), float3(1,57,21)) + float4(0,57,21,78);
p = smoothstep(0,1,frac(p));
//p = cos(frac(p)*acos(-1.))*(-.5) + .5;
a=lerp(sin(cos(a*a)), sin(cos(a*a + 2*a + 1)), p.x);
a.xy=lerp(a.xz,a.yw,p.y);
return lerp(a.x,a.y,p.z);
}
float pn(float3 p) {
float3 i = floor(p);
float4 a = (i.x + i.y * 57 + i.z * 21); a.yzw += float3(57, 21, 78);
float3 f = frac(p); f = f * f * (-2*f + 3);
a = lerp(sin(cos(a) * a), sin(cos(1+a) * (1+a)), f.x);
a.xy = lerp(a.xz, a.yw, f.y);
return lerp(a.x, a.y, f.z);
}
float fpn(float3 p) {
float r = pn(p * 0.06125) * 0.5;
p.xy = cos(1) * p.xy + float2(-sin(1), sin(1)) * p.yx;
r += pn(p * 0.125) * 0.25;
p.zy = cos(1) * p.zy + float2(-sin(1), sin(1)) * p.yz;
r += pn(p * 0.25) * 0.125;
return r * (1 / (0.5 + 0.25 + 0.125));
}
#endif