traced scene texture atlas
This commit is contained in:
@@ -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_
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user