traced scene texture atlas

This commit is contained in:
turanszkij
2018-06-20 17:17:20 +01:00
parent 22f3a66adc
commit 71d03f917f
7 changed files with 192 additions and 43 deletions
@@ -24,5 +24,23 @@ struct TracedRenderingStoredRay
float2 bary;
};
struct TracedRenderingMaterial
{
float4 baseColor;
float4 texMulAdd;
float roughness;
float reflectance;
float metalness;
float emissive;
float refractionIndex;
float subsurfaceScattering;
float normalMapStrength;
float parallaxOcclusionMapping;
float4 baseColorAtlasMulAdd;
float4 surfaceMapAtlasMulAdd;
float4 normalMapAtlasMulAdd;
};
#endif // _SHADERINTEROP_TRACEDRENDERING_H_
+1 -1
View File
@@ -21,7 +21,7 @@ RWSTRUCTUREDBUFFER(clusterOffsetBuffer, uint2, 4); // offset, count
RWSTRUCTUREDBUFFER(clusterAABBBuffer, BVHAABB, 5);
// if defined, triangles will be grouped into clusters, else every triangle will be its own cluster:
//#define CLUSTER_GROUP
#define CLUSTER_GROUP
#ifdef CLUSTER_GROUP
static const uint clusterTriangleCapacity = 4;
+14 -7
View File
@@ -5,7 +5,7 @@
RWTEXTURE2D(resultTexture, float4, 0);
STRUCTUREDBUFFER(materialBuffer, Material, TEXSLOT_ONDEMAND0);
STRUCTUREDBUFFER(materialBuffer, TracedRenderingMaterial, TEXSLOT_ONDEMAND0);
STRUCTUREDBUFFER(triangleBuffer, BVHMeshTriangle, TEXSLOT_ONDEMAND1);
RAWBUFFER(clusterCounterBuffer, TEXSLOT_ONDEMAND2);
STRUCTUREDBUFFER(clusterIndexBuffer, uint, TEXSLOT_ONDEMAND3);
@@ -14,6 +14,8 @@ STRUCTUREDBUFFER(clusterConeBuffer, ClusterCone, TEXSLOT_ONDEMAND5);
STRUCTUREDBUFFER(bvhNodeBuffer, BVHNode, TEXSLOT_ONDEMAND6);
STRUCTUREDBUFFER(bvhAABBBuffer, BVHAABB, TEXSLOT_ONDEMAND7);
TEXTURE2D(materialTextureAtlas, float4, TEXSLOT_ONDEMAND8);
RAWBUFFER(counterBuffer_READ, TEXSLOT_UNIQUE0);
STRUCTUREDBUFFER(rayBuffer_READ, TracedRenderingStoredRay, TEXSLOT_UNIQUE1);
@@ -138,18 +140,23 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
float3 P = ray.origin;
float3 N = normalize(tri.n0 * w + tri.n1 * u + tri.n2 * v);
float2 UV = tri.t0 * w + tri.t1 * u + tri.t2 * v;
float3 V = normalize(g_xFrame_MainCamera_CamPos - P);
uint materialIndex = tri.materialIndex;
Material mat = materialBuffer[materialIndex];
TracedRenderingMaterial mat = materialBuffer[materialIndex];
float4 baseColor = DEGAMMA(mat.baseColor /** baseColorMap*/);
float reflectance = mat.reflectance/* * surfaceMap.r*/;
float metalness = mat.metalness/* * surfaceMap.g*/;
float emissive = mat.emissive /** surfaceMap.b*/;
float roughness = mat.roughness/* * normalMap.a*/;
float4 baseColorMap = materialTextureAtlas.SampleLevel(sampler_linear_clamp, UV * mat.baseColorAtlasMulAdd.xy + mat.baseColorAtlasMulAdd.zw, 0);
float4 surfaceMap = materialTextureAtlas.SampleLevel(sampler_linear_clamp, UV * mat.surfaceMapAtlasMulAdd.xy + mat.surfaceMapAtlasMulAdd.zw, 0);
float4 normalMap = materialTextureAtlas.SampleLevel(sampler_linear_clamp, UV * mat.normalMapAtlasMulAdd.xy + mat.normalMapAtlasMulAdd.zw, 0);
float4 baseColor = DEGAMMA(mat.baseColor * baseColorMap);
float reflectance = mat.reflectance * surfaceMap.r;
float metalness = mat.metalness * surfaceMap.g;
float emissive = mat.emissive * surfaceMap.b;
float roughness = mat.roughness /** normalMap.a*/;
float sss = mat.subsurfaceScattering;
Surface surface = CreateSurface(P, N, V, baseColor, roughness, reflectance, metalness, emissive, sss);
+13 -14
View File
@@ -18,7 +18,7 @@ groupshared uint GroupRayCount;
groupshared uint GroupRayWriteOffset;
#endif // ADVANCED_ALLOCATION
STRUCTUREDBUFFER(materialBuffer, Material, TEXSLOT_ONDEMAND0);
STRUCTUREDBUFFER(materialBuffer, TracedRenderingMaterial, TEXSLOT_ONDEMAND0);
STRUCTUREDBUFFER(triangleBuffer, BVHMeshTriangle, TEXSLOT_ONDEMAND1);
RAWBUFFER(clusterCounterBuffer, TEXSLOT_ONDEMAND2);
STRUCTUREDBUFFER(clusterIndexBuffer, uint, TEXSLOT_ONDEMAND3);
@@ -27,9 +27,7 @@ STRUCTUREDBUFFER(clusterConeBuffer, ClusterCone, TEXSLOT_ONDEMAND5);
STRUCTUREDBUFFER(bvhNodeBuffer, BVHNode, TEXSLOT_ONDEMAND6);
STRUCTUREDBUFFER(bvhAABBBuffer, BVHAABB, TEXSLOT_ONDEMAND7);
//TEXTURE2D(texture_baseColor, float4, TEXSLOT_ONDEMAND4);
//TEXTURE2D(texture_normalMap, float4, TEXSLOT_ONDEMAND5);
//TEXTURE2D(texture_surfaceMap, float4, TEXSLOT_ONDEMAND6);
TEXTURE2D(materialTextureAtlas, float4, TEXSLOT_ONDEMAND8);
RAWBUFFER(counterBuffer_READ, TEXSLOT_UNIQUE0);
STRUCTUREDBUFFER(rayBuffer_READ, TracedRenderingStoredRay, TEXSLOT_UNIQUE1);
@@ -133,19 +131,20 @@ inline float3 Shade(inout Ray ray, RayHit hit, inout float seed, in float2 pixel
float3 N = normalize(tri.n0 * w + tri.n1 * u + tri.n2 * v);
float2 UV = tri.t0 * w + tri.t1 * u + tri.t2 * v;
//float4 baseColorMap = texture_baseColor.SampleLevel(sampler_linear_wrap, UV, 0);
//float4 normalMap = texture_normalMap.SampleLevel(sampler_linear_wrap, UV, 0);
//float4 surfaceMap = texture_surfaceMap.SampleLevel(sampler_linear_wrap, UV, 0);
uint materialIndex = tri.materialIndex;
Material mat = materialBuffer[materialIndex];
TracedRenderingMaterial mat = materialBuffer[materialIndex];
float4 baseColorMap = materialTextureAtlas.SampleLevel(sampler_linear_clamp, UV * mat.baseColorAtlasMulAdd.xy + mat.baseColorAtlasMulAdd.zw, 0);
float4 surfaceMap = materialTextureAtlas.SampleLevel(sampler_linear_clamp, UV * mat.surfaceMapAtlasMulAdd.xy + mat.surfaceMapAtlasMulAdd.zw, 0);
float4 normalMap = materialTextureAtlas.SampleLevel(sampler_linear_clamp, UV * mat.normalMapAtlasMulAdd.xy + mat.normalMapAtlasMulAdd.zw, 0);
float4 baseColor = DEGAMMA(mat.baseColor /** baseColorMap*/);
float reflectance = mat.reflectance/* * surfaceMap.r*/;
float metalness = mat.metalness/* * surfaceMap.g*/;
float3 emissive = baseColor.rgb * mat.emissive /** surfaceMap.b*/;
float roughness = mat.roughness/* * normalMap.a*/;
float4 baseColor = DEGAMMA(mat.baseColor * baseColorMap);
float reflectance = mat.reflectance * surfaceMap.r;
float metalness = mat.metalness * surfaceMap.g;
float3 emissive = baseColor.rgb * mat.emissive * surfaceMap.b;
float roughness = mat.roughness /** normalMap.a*/;
float sss = mat.subsurfaceScattering;
float3 albedo = ComputeAlbedo(baseColor, reflectance, metalness);
float3 specular = ComputeF0(baseColor, reflectance, metalness);
-14
View File
@@ -11,20 +11,6 @@ static const float INFINITE_RAYHIT = 1000000;
static const float EPSILON = 0.0001f;
struct Material
{
float4 baseColor;
float4 texMulAdd;
float roughness;
float reflectance;
float metalness;
float emissive;
float refractionIndex;
float subsurfaceScattering;
float normalMapStrength;
float parallaxOcclusionMapping;
};
//struct Sphere
//{
// float3 position;
+143 -4
View File
@@ -6780,7 +6780,107 @@ void wiRenderer::DrawTracedScene(Camera* camera, wiGraphicsTypes::Texture2D* res
assert(SUCCEEDED(hr));
}
static MaterialCB materialArray[1000] = {}; // todo realloc!
// Traced Scene Texture Atlas:
static Texture2D* atlasTexture = nullptr;
using namespace wiRectPacker;
static std::set<Texture2D*> sceneTextures;
static std::map<Texture2D*, rect_xywhf> storedTextures;
for (Model* model : GetScene().models)
{
for (auto& iter : model->objects)
{
Object* object = iter;
Mesh* mesh = object->mesh;
for (auto& subset : mesh->subsets)
{
Material* mat = subset.material;
if (mat != nullptr)
{
sceneTextures.insert(mat->GetBaseColorMap());
sceneTextures.insert(mat->GetSurfaceMap());
sceneTextures.insert(mat->GetNormalMap());
}
}
}
}
bool repackAtlas = false;
for (Texture2D* tex : sceneTextures)
{
if (tex == nullptr)
{
continue;
}
if (storedTextures.find(tex) == storedTextures.end())
{
// we need to pack this decal texture into the atlas
rect_xywhf newRect = rect_xywhf(0, 0, tex->GetDesc().Width, tex->GetDesc().Height);
storedTextures[tex] = newRect;
repackAtlas = true;
}
}
if (repackAtlas)
{
rect_xywhf** out_rects = new rect_xywhf*[storedTextures.size()];
int i = 0;
for (auto& it : storedTextures)
{
out_rects[i] = &it.second;
i++;
}
std::vector<bin> bins;
if (pack(out_rects, (int)storedTextures.size(), 16384, bins))
{
assert(bins.size() == 1 && "Tracing atlas packing into single texture failed!");
SAFE_DELETE(atlasTexture);
TextureDesc desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = (UINT)bins[0].size.w;
desc.Height = (UINT)bins[0].size.h;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = USAGE_DEFAULT;
desc.BindFlags = BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
device->CreateTexture2D(&desc, nullptr, &atlasTexture);
for (UINT mip = 0; mip < atlasTexture->GetDesc().MipLevels; ++mip)
{
for (auto& it : storedTextures)
{
if (mip < it.first->GetDesc().MipLevels)
{
device->CopyTexture2D_Region(atlasTexture, mip, it.second.x >> mip, it.second.y >> mip, it.first, mip, threadID);
}
}
}
}
else
{
wiBackLog::post("Tracing atlas packing failed!");
}
SAFE_DELETE_ARRAY(out_rects);
}
static TracedRenderingMaterial materialArray[1000] = {}; // todo realloc!
static GPUBuffer* materialBuffer = nullptr;
if (materialBuffer == nullptr)
@@ -6792,7 +6892,7 @@ void wiRenderer::DrawTracedScene(Camera* camera, wiGraphicsTypes::Texture2D* res
materialBuffer = new GPUBuffer;
desc.BindFlags = BIND_SHADER_RESOURCE;
desc.StructureByteStride = sizeof(MaterialCB);
desc.StructureByteStride = sizeof(TracedRenderingMaterial);
desc.ByteWidth = desc.StructureByteStride * ARRAYSIZE(materialArray);
desc.CPUAccessFlags = 0;
desc.Format = FORMAT_UNKNOWN;
@@ -6816,12 +6916,40 @@ void wiRenderer::DrawTracedScene(Camera* camera, wiGraphicsTypes::Texture2D* res
for (auto& subset : mesh->subsets)
{
materialArray[totalMaterials].Create(*subset.material);
MaterialCB mat;
mat.Create(*subset.material);
// Copy base params:
materialArray[totalMaterials].baseColor = mat.baseColor;
materialArray[totalMaterials].texMulAdd = mat.texMulAdd;
materialArray[totalMaterials].roughness = mat.roughness;
materialArray[totalMaterials].reflectance = mat.reflectance;
materialArray[totalMaterials].metalness = mat.metalness;
materialArray[totalMaterials].emissive = mat.emissive;
materialArray[totalMaterials].refractionIndex = mat.refractionIndex;
materialArray[totalMaterials].subsurfaceScattering = mat.subsurfaceScattering;
materialArray[totalMaterials].normalMapStrength = mat.normalMapStrength;
materialArray[totalMaterials].parallaxOcclusionMapping = mat.normalMapStrength;
// Add extended properties:
TextureDesc desc = atlasTexture->GetDesc();
rect_xywhf rect;
rect = storedTextures[subset.material->GetBaseColorMap()];
materialArray[totalMaterials].baseColorAtlasMulAdd = XMFLOAT4((float)rect.w / (float)desc.Width, (float)rect.h / (float)desc.Height, (rect.x + 0.5f) / (float)desc.Width, (rect.y + 0.5f) / (float)desc.Height);
rect = storedTextures[subset.material->GetSurfaceMap()];
materialArray[totalMaterials].surfaceMapAtlasMulAdd = XMFLOAT4((float)rect.w / (float)desc.Width, (float)rect.h / (float)desc.Height, (rect.x + 0.5f) / (float)desc.Width, (rect.y + 0.5f) / (float)desc.Height);
rect = storedTextures[subset.material->GetNormalMap()];
materialArray[totalMaterials].normalMapAtlasMulAdd = XMFLOAT4((float)rect.w / (float)desc.Width, (float)rect.h / (float)desc.Height, (rect.x + 0.5f) / (float)desc.Width, (rect.y + 0.5f) / (float)desc.Height);
totalMaterials++;
}
}
}
device->UpdateBuffer(materialBuffer, materialArray, threadID, sizeof(MaterialCB) * totalMaterials);
device->UpdateBuffer(materialBuffer, materialArray, threadID, sizeof(TracedRenderingMaterial) * totalMaterials);
// Begin raytrace
@@ -6890,6 +7018,15 @@ void wiRenderer::DrawTracedScene(Camera* camera, wiGraphicsTypes::Texture2D* res
};
device->BindResources(CS, res, TEXSLOT_ONDEMAND0, ARRAYSIZE(res), threadID);
if (atlasTexture != nullptr)
{
device->BindResource(CS, atlasTexture, TEXSLOT_ONDEMAND8, threadID);
}
else
{
device->BindResource(CS, wiTextureHelper::getInstance()->getWhite(), TEXSLOT_ONDEMAND8, threadID);
}
for (int bounce = 0; bounce < 8; ++bounce)
{
const int __readBufferID = bounce % 2;
@@ -7113,6 +7250,8 @@ void wiRenderer::ManageDecalAtlas(GRAPHICSTHREAD threadID)
{
wiBackLog::post("Decal atlas packing failed!");
}
SAFE_DELETE_ARRAY(out_rects);
}
rect_xywhf rect = storedTextures[decal->texture];
+3 -3
View File
@@ -186,14 +186,14 @@ Texture2D* wiTextureHelper::wiTextureHelperInstance::getColor(const wiColor& col
unsigned char* data = new unsigned char[dataLength];
for (int i = 0; i < dataLength; i += 4)
{
data[i] = color.r;
data[i] = color.b;
data[i + 1] = color.g;
data[i + 2] = color.b;
data[i + 2] = color.r;
data[i + 3] = color.a;
}
Texture2D* texture = nullptr;
if (FAILED(CreateTexture(texture, data, 1, 1, 4)))
if (FAILED(CreateTexture(texture, data, 1, 1, 4, FORMAT_B8G8R8A8_UNORM)))
{
delete[] data;
return nullptr;