Skip to content

Commit

Permalink
removed remnants of e_Variable, switched to purely index based refere…
Browse files Browse the repository at this point in the history
…nces. Classes in SceneTypes depend on g_SceneData as a result
  • Loading branch information
hhergeth committed Mar 18, 2018
1 parent a0bba33 commit e6ecbdf
Show file tree
Hide file tree
Showing 17 changed files with 369 additions and 347 deletions.
26 changes: 10 additions & 16 deletions Base/Buffer.h
Expand Up @@ -49,8 +49,6 @@ template<typename H, typename D> class BufferRange
{
return num_in_iterator(*this, MINUS_ONE);
}

virtual BufferReference<H, D> translate(e_Variable<D> var) = 0;
};
template<typename T> using StreamRange = BufferRange<T, T>;

Expand Down Expand Up @@ -282,6 +280,14 @@ template<typename H, typename D> class BufferBase : public BufferRange<H, D>
__UpdateInvalidated_internal<false>(_f);
}

void memset(BufferReference<H, D> ref, char val)
{
ref.Invalidate();

Platform::SetMemory(ref.operator H *(), ref.getHostSize(), val);
cudaMemset(ref.getDevice(), (int)ref.getDeviceSize(), val);
}

template<typename CLB> void UpdateInvalidated(const CLB& f)
{
__UpdateInvalidated_internal<true>(f);
Expand Down Expand Up @@ -334,18 +340,6 @@ template<typename H, typename D> class BufferBase : public BufferRange<H, D>
}

virtual KernelBuffer<D> getKernelData(bool devicePointer = true) const = 0;

virtual BufferReference<H, D> translate(e_Variable<D> var)
{
size_t idx = var.device - device;
return BufferReference<H, D>(this, idx, 1);
}

template<typename T> BufferReference<H, D> translate(e_Variable<T> var)
{
size_t idx = (D*)var.device - device;
return BufferReference<H, D>(this, idx, (unsigned int)(sizeof(T) / sizeof(D)));
}
};

template<typename H, typename D> class BufferIterator
Expand Down Expand Up @@ -430,7 +424,7 @@ template<typename H, typename D> class Buffer : public BufferBase<H, D>
{
free(deviceMapped);
deviceMapped = (D*)::malloc(BufferBase<H, D>::m_uLength * sizeof(D));
memset(deviceMapped, 0, sizeof(D) * BufferBase<H, D>::m_uLength);
::memset(deviceMapped, 0, sizeof(D) * BufferBase<H, D>::m_uLength);
}
virtual D* getDeviceMappedData()
{
Expand All @@ -441,7 +435,7 @@ template<typename H, typename D> class Buffer : public BufferBase<H, D>
: BufferBase<H, D>(a_NumElements, a_ElementSize, true)
{
deviceMapped = (D*)::malloc(a_NumElements * sizeof(D));
memset(deviceMapped, 0, sizeof(D) * a_NumElements);
::memset(deviceMapped, 0, sizeof(D) * a_NumElements);
}
virtual ~Buffer()
{
Expand Down
10 changes: 0 additions & 10 deletions Base/Buffer_device.h
Expand Up @@ -112,16 +112,6 @@ template<typename H, typename D> class BufferReference
buf->CopyFromDevice(*this);
}

e_Variable<D> AsVar()
{
return AsVar<D>();
}

template<typename T> e_Variable<T> AsVar()
{
return e_Variable<T>((T*)(buf->getDeviceMappedData() + p), (T*)atD(p));
}

size_t getHostSize() const
{
return l * buf->m_uBlockSize;
Expand Down
49 changes: 0 additions & 49 deletions Defines.h
Expand Up @@ -207,53 +207,4 @@ template<typename T> struct CudaStaticWrapper
}
};

template<typename T> class e_Variable
{
public:
CUDA_ALIGN(16) T* host;
CUDA_ALIGN(16) T* device;
CUDA_FUNC_IN e_Variable()
{
}
/*
template<typename U, typename V> CUDA_HOST e_Variable(BufferReference<U, V> r)
{
host = (T*)r.operator->();
device = (T*)r.getDevice();
}*/
CUDA_FUNC_IN e_Variable(T* h, T* d)
: host(h), device(d)
{

}
CUDA_FUNC_IN T& operator[](unsigned int i) const
{
#ifdef ISCUDA
return device[i];
#else
return host[i];
#endif
}
CUDA_FUNC_IN T* operator->() const
{
#ifdef ISCUDA
return device;
#else
return host;
#endif
}
CUDA_FUNC_IN T* operator*() const
{
#ifdef ISCUDA
return device;
#else
return host;
#endif
}
template<typename U> CUDA_FUNC_IN e_Variable<U> As() const
{
return e_Variable<U>((U*)host, (U*)device);
}
};

}
12 changes: 6 additions & 6 deletions Engine/Material.cu
Expand Up @@ -42,7 +42,7 @@ Material::Material(const std::string& name)
initbssrdf(bssrdf);
}

CUDA_FUNC_IN void parallaxOcclusion(Vec2f& texCoord, KernelMIPMap* tex, const Vec3f& vViewTS, float HeightScale, int MinSamples, int MaxSamples)
CUDA_FUNC_IN void parallaxOcclusion(Vec2f& texCoord, const KernelMIPMap& tex, const Vec3f& vViewTS, float HeightScale, int MinSamples, int MaxSamples)
{
const Vec2f vParallaxDirection = normalize(vViewTS.getXY());
float fLength = length(vViewTS);
Expand All @@ -67,7 +67,7 @@ CUDA_FUNC_IN void parallaxOcclusion(Vec2f& texCoord, KernelMIPMap* tex, const Ve
while (StepIndex < nNumSteps)
{
TexCurrentOffset -= TexOffsetPerStep;
CurrHeight = tex->Sample(TexCurrentOffset).avg();
CurrHeight = tex.Sample(TexCurrentOffset).avg();
CurrentBound -= StepSize;
if (CurrHeight > CurrentBound)
{
Expand Down Expand Up @@ -111,12 +111,12 @@ bool Material::SampleNormalMap(DifferentialGeometry& dg, const Vec3f& wi) const
Vec2f uv = map.Map(dg);
if (enableParallaxOcclusion)
{
parallaxOcclusion(uv, HeightMap.tex.As<ImageTexture>()->tex.operator->(), dg.sys.toLocal(-wi), HeightScale, parallaxMinSamples, parallaxMaxSamples);
parallaxOcclusion(uv, HeightMap.tex.As<ImageTexture>()->getTexture(), dg.sys.toLocal(-wi), HeightScale, parallaxMinSamples, parallaxMaxSamples);
dg.uv[map.setId] = map.TransformPointInverse(uv);
}

Spectrum grad[2];
HeightMap.tex.As<ImageTexture>()->tex->evalGradient(uv, grad);
HeightMap.tex.As<ImageTexture>()->getTexture().evalGradient(uv, grad);
float dDispDu = grad[0].getLuminance();
float dDispDv = grad[1].getLuminance();
Vec3f dpdu = dg.dpdu + dg.sys.n * (
Expand Down Expand Up @@ -171,8 +171,8 @@ bool Material::AlphaTest(const Vec2f& bary, const Vec2f& uv) const
{
float alpha = FLT_MAX;
if (AlphaMap.state == AlphaBlendState::AlphaMap_Alpha)
alpha = alpha_img->tex->SampleAlpha(alpha_img->mapping.TransformPoint(uv));
else alpha = refl_img->tex->SampleAlpha(refl_uv);
alpha = alpha_img->getTexture().SampleAlpha(alpha_img->mapping.TransformPoint(uv));
else alpha = refl_img->getTexture().SampleAlpha(refl_uv);
return alpha >= AlphaMap.test_val_scalar;
}
else
Expand Down
173 changes: 173 additions & 0 deletions Engine/SceneLoader/Mitsuba/ObjectParser.cpp
Expand Up @@ -2,6 +2,7 @@
#include "ObjectParser.h"
#include <filesystem.h>
#include <miniz/miniz.h>
#include <Kernel/TraceHelper.h>

namespace CudaTracerLib {

Expand Down Expand Up @@ -202,4 +203,176 @@ ShapeParser::ShapeParseResult ShapeParser::serialized(const XMLNode& node, Parse
return obj;
}

VolumeRegion MediumParser::heterogeneous(const XMLNode& node, ParserState& S)
{
PhaseFunction f = CreateAggregate<PhaseFunction>(IsotropicPhaseFunction());
if (node.has_child_node("phase"))
f = PhaseFunctionParser::parse(node.get_child_node("phase"), S);
float scale = S.def_storage.prop_float(node, "scale", 1.0f);

struct VolData
{
bool is_constant = true;

Spectrum const_value = 0.0f;

Vec3u cell_dims;
std::vector<float> data;
AABB box;

Vec3u dims() const
{
return is_constant ? Vec3u(1) : cell_dims;
}

//pos is [0,1]^3
float eval(const Vec3f& pos) const
{
if (is_constant)
return const_value.getLuminance();

int x = int(pos.x * cell_dims.x), y = int(pos.y * cell_dims.y), z = int(pos.z * cell_dims.z);
return data[idx(x, y, z)];
}

size_t idx(int xpos, int ypos, int zpos, int chan = 0, int num_channels = 1) const
{
return ((zpos*cell_dims.y + ypos)*cell_dims.x + xpos)*num_channels + chan;
}
};

std::optional<float4x4> volume_to_world;
auto parse_volume = [&](const XMLNode& vol_node)
{
VolData dat;
if (vol_node.get_attribute("type") == "constvolume")
{
dat.is_constant = true;
dat.const_value = parseColor(vol_node.get_property("value"), S);
if (vol_node.has_property("toWorld"))
{
if (volume_to_world)
throw std::runtime_error("only one volume to world matrix allowed!");
volume_to_world = parseMatrix(vol_node.get_property("toWorld"), S);
}
}
else if (vol_node.get_attribute("type") == "gridvolume")
{
dat.is_constant = false;
auto filename = S.def_storage.prop_string(vol_node, "filename");
filename = S.map_asset_filepath(filename);
std::optional<std::tuple<Vec3f, Vec3f>> optional_aabb;
if (vol_node.has_property("toWorld") || vol_node.has_property("min"))
{
if (volume_to_world)
throw std::runtime_error("only one volume to world matrix allowed!");
if (vol_node.has_property("toWorld"))
volume_to_world = parseMatrix(vol_node.get_property("toWorld"), S);
if (vol_node.has_property("min"))//max must also exist
{
auto min_vol = parseVector(vol_node.get_property("min"), S);
auto max_vol = parseVector(vol_node.get_property("max"), S);
optional_aabb = std::make_tuple(min_vol, max_vol);
}
}

std::ifstream ser_str(filename, std::ios::binary);
enum EVolumeType {
EFloat32 = 1,
EFloat16 = 2,
EUInt8 = 3,
EQuantizedDirections = 4
};
uint8_t header[4];
ser_str.read((char*)header, 4);
if (header[0] != 'V' || header[1] != 'O' || header[2] != 'L' || header[3] != 3)
throw std::runtime_error("expected VOL3 header");
EVolumeType data_type;
ser_str.read((char*)&data_type, sizeof(data_type));
ser_str.read((char*)&dat.cell_dims, sizeof(dat.cell_dims));
uint32_t num_channels;
ser_str.read((char*)&num_channels, sizeof(num_channels));
ser_str.read((char*)&dat.box, sizeof(dat.box));

size_t N = dat.cell_dims.x * dat.cell_dims.y * dat.cell_dims.z;
dat.data.resize(N);
size_t val_size = data_type == EVolumeType::EFloat32 ? sizeof(float) : (data_type == EVolumeType::EFloat16 ? sizeof(half) : sizeof(uint8_t));
std::vector<uint8_t> buffer(N * num_channels * val_size);
ser_str.read((char*)buffer.data(), buffer.size());

for (size_t i = 0; i < N; i++)
{
float sum = 0;
for (uint32_t channel = 0; channel < num_channels; channel++)
{
uint8_t* ptr = &buffer[(i * num_channels + channel) * val_size];
if (data_type == EVolumeType::EFloat32)
{
sum += *(float*)ptr;
}
else if (data_type == EVolumeType::EFloat16)
{
sum += ((half*)ptr)->ToFloat();
}
else if (data_type == EVolumeType::EUInt8)
{
sum += (*ptr) / 255.0f;
}
else throw std::runtime_error("unsopported volume data type : " + std::to_string((int)data_type));
}

dat.data[i] = sum / num_channels;
}

if (optional_aabb)
dat.box = AABB(std::get<0>(optional_aabb.value()), std::get<1>(optional_aabb.value()));

auto vtow = volume_to_world ? volume_to_world.value() : float4x4::Identity();
if (distance(dat.box.minV, Vec3f(0)) > 1e-3f || distance(dat.box.maxV, Vec3f(1)) > 1e-3f)
volume_to_world = vtow % float4x4::Translate(dat.box.minV) % float4x4::Scale(dat.box.Size());
}
else throw std::runtime_error("invalid volume type : " + vol_node.get_attribute("type"));
return dat;
};

VolData density_data;
VolData albedo_data;

if (node.has_property("density"))
density_data = parse_volume(node.get_property("density"));
if (node.has_property("albedo"))
albedo_data = parse_volume(node.get_property("albedo"));

auto vol_to_world = volume_to_world ? volume_to_world.value() : parseMatrix_Id(S);
vol_to_world = toWorld % vol_to_world;// the order here is unclear
if (density_data.is_constant && albedo_data.is_constant)
{
Spectrum sigma_s = albedo_data.const_value * density_data.const_value * scale;
Spectrum sigma_a = density_data.const_value * scale - sigma_s;
return CreateAggregate<VolumeRegion>(HomogeneousVolumeDensity(f, vol_to_world, sigma_a, sigma_s, 0.0f));
}
else
{
auto max_dims = max(density_data.dims(), albedo_data.dims());
auto G = VolumeGrid(f, vol_to_world, S.scene.getTempBuffer(), max_dims, max_dims, Vec3u(1));
UpdateKernel(&S.scene);
G.sigAMax = G.sigSMax = 1.0f;

auto scaleF = Vec3f((float)max_dims.x, (float)max_dims.y, (float)max_dims.z);
for (unsigned int x = 0; x < max_dims.x; x++)
for (unsigned int y = 0; y < max_dims.y; y++)
for (unsigned int z = 0; z < max_dims.z; z++)
{
auto pos = Vec3f((float)x, (float)y, (float)z) / scaleF;
float density = density_data.eval(pos) * scale;
float albedo = albedo_data.eval(pos);
G.gridS.value(x, y, z) = albedo * density;
G.gridA.value(x, y, z) = density * (1.0f - albedo);
}

G.Update();
return CreateAggregate<VolumeRegion>(G);
}
}

}

0 comments on commit e6ecbdf

Please sign in to comment.