Skip to content

Commit

Permalink
Reduce compile times by precomputing geometry attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
szellmann committed Jun 7, 2024
1 parent d65e8e2 commit 182b9db
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 65 deletions.
28 changes: 17 additions & 11 deletions renderer/DirectLight_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct ShadeRec
float3 btng{0.f};
float3 viewDir{0.f};
float3 hitPos{0.f};
float4 attribs[5];
bool hdriMiss{false};
float eps{1e-4f};
};
Expand All @@ -89,6 +90,7 @@ bool shade(ScreenSample &ss, Ray &ray, unsigned worldID,
auto &btng = shadeRec.btng;
auto &viewDir = shadeRec.viewDir;
auto &hitPos = shadeRec.hitPos;
auto &attribs = shadeRec.attribs;
auto &hdriMiss = shadeRec.hdriMiss;
auto &eps = shadeRec.eps;

Expand Down Expand Up @@ -151,6 +153,10 @@ bool shade(ScreenSample &ss, Ray &ray, unsigned worldID,
hitPos = ray.ori + hr.t * ray.dir;
eps = epsilonFrom(hitPos, ray.dir, hr.t);

for (int i=0; i<5; ++i) {
attribs[i] = getAttribute(geom, (dco::Attribute)i, hr.prim_id, uv);
}

viewDir = -ray.dir;

getNormals(geom, hr.prim_id, hitPos, uv, gn, sn);
Expand All @@ -165,9 +171,9 @@ bool shade(ScreenSample &ss, Ray &ray, unsigned worldID,
tng = tng4.xyz();
btng = cross(sn, tng) * tng4.w;
sn = getPerturbedNormal(
mat, geom, onDevice.samplers, hr.prim_id, uv, tng, btng, sn);
mat, onDevice.samplers, attribs, hr.prim_id, tng, btng, sn);
}
color = getColor(mat, geom, onDevice.samplers, hr.prim_id, uv);
color = getColor(mat, onDevice.samplers, attribs, hr.prim_id);

result.albedo = color.xyz();
}
Expand Down Expand Up @@ -223,9 +229,9 @@ bool shade(ScreenSample &ss, Ray &ray, unsigned worldID,

if (ls.pdf > 0.f) {
shadedColor = evalMaterial(mat,
dummyGeom,
onDevice.samplers, // not used..
UINT_MAX, vec2{}, // primID and uv, not used..
nullptr, // attribs, not used..
UINT_MAX, // primID, not used..
gn, gn,
viewDir, ls.dir,
intensity);
Expand Down Expand Up @@ -258,10 +264,10 @@ bool shade(ScreenSample &ss, Ray &ray, unsigned worldID,
if (rendererState.renderMode == RenderMode::Default) {
if (ls.pdf > 0.f) {
shadedColor = evalMaterial(mat,
geom,
onDevice.samplers,
attribs,
hr.prim_id,
uv, gn, sn,
gn, sn,
viewDir,
ls.dir,
intensity);
Expand Down Expand Up @@ -291,15 +297,15 @@ bool shade(ScreenSample &ss, Ray &ray, unsigned worldID,
vec3 hsv(angle,1.f,mag);
shadedColor = hsv2rgb(hsv);
} else if (rendererState.renderMode == RenderMode::GeometryAttribute0)
shadedColor = getAttribute(geom, dco::Attribute::_0, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::_0].xyz();
else if (rendererState.renderMode == RenderMode::GeometryAttribute1)
shadedColor = getAttribute(geom, dco::Attribute::_1, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::_1].xyz();
else if (rendererState.renderMode == RenderMode::GeometryAttribute2)
shadedColor = getAttribute(geom, dco::Attribute::_2, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::_2].xyz();
else if (rendererState.renderMode == RenderMode::GeometryAttribute3)
shadedColor = getAttribute(geom, dco::Attribute::_3, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::_3].xyz();
else if (rendererState.renderMode == RenderMode::GeometryColor)
shadedColor = getAttribute(geom, dco::Attribute::Color, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::Color].xyz();

if (rendererState.renderMode == RenderMode::Default)
baseColor = color.xyz();
Expand Down
27 changes: 17 additions & 10 deletions renderer/Raycast_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ inline PixelSample renderSample(ScreenSample &ss, Ray ray, unsigned worldID,
vec3f hitPos = ray.ori + hr.t * ray.dir;
vec2f uv{hr.u,hr.v};
vec3f gn, sn;

float4 attribs[5];
for (int i=0; i<5; ++i) {
attribs[i] = getAttribute(geom, (dco::Attribute)i, hr.prim_id, uv);
}

getNormals(geom, hr.prim_id, hitPos, uv, gn, sn);

gn = inst.normalXfm * gn;
Expand All @@ -46,9 +52,9 @@ inline PixelSample renderSample(ScreenSample &ss, Ray ray, unsigned worldID,
tng = tng4.xyz();
btng = cross(sn, tng) * tng4.w;
sn = getPerturbedNormal(
mat, geom, onDevice.samplers, hr.prim_id, uv, tng, btng, sn);
mat, onDevice.samplers, attribs, hr.prim_id, tng, btng, sn);
}
vec4f color = getColor(mat, geom, onDevice.samplers, hr.prim_id, uv);
vec4f color = getColor(mat, onDevice.samplers, attribs, hr.prim_id);

// That doesn't work for instances..
float3 shadedColor{0.f};
Expand All @@ -75,10 +81,10 @@ inline PixelSample renderSample(ScreenSample &ss, Ray ray, unsigned worldID,
}

float3 brdf = evalMaterial(mat,
geom,
onDevice.samplers,
attribs,
hr.prim_id,
uv, gn, sn,
gn, sn,
viewDir,
ls.dir,
intensity);
Expand All @@ -99,17 +105,18 @@ inline PixelSample renderSample(ScreenSample &ss, Ray ray, unsigned worldID,
else if (rendererState.renderMode == RenderMode::Bitangent)
shadedColor = btng;
else if (rendererState.renderMode == RenderMode::GeometryAttribute0)
shadedColor = getAttribute(geom, dco::Attribute::_0, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::_0].xyz();
else if (rendererState.renderMode == RenderMode::GeometryAttribute1)
shadedColor = getAttribute(geom, dco::Attribute::_1, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::_1].xyz();
else if (rendererState.renderMode == RenderMode::GeometryAttribute2)
shadedColor = getAttribute(geom, dco::Attribute::_2, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::_2].xyz();
else if (rendererState.renderMode == RenderMode::GeometryAttribute3)
shadedColor = getAttribute(geom, dco::Attribute::_3, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::_3].xyz();
else if (rendererState.renderMode == RenderMode::GeometryColor)
shadedColor = getAttribute(geom, dco::Attribute::Color, hr.prim_id, uv).xyz();
shadedColor = attribs[(int)dco::Attribute::Color].xyz();


float a = getOpacity(mat, geom, onDevice.samplers, hr.prim_id, uv);
float a = getOpacity(mat, onDevice.samplers, attribs, hr.prim_id);
surfaceColor += (1.f-surfaceAlpha) * a * shadedColor;
surfaceAlpha += (1.f-surfaceAlpha) * a;

Expand Down
94 changes: 50 additions & 44 deletions renderer/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,18 +457,18 @@ inline vec4 getAttribute(

VSNRAY_FUNC
inline vec4 getSample(
const dco::Sampler &samp, const dco::Geometry geom, unsigned primID, const vec2 uv)
const dco::Sampler &samp, const float4 *attribs, unsigned primID)
{
if (samp.type == dco::Sampler::Primitive) {
const TypeInfo &info = samp.asPrimitive.typeInfo;
const auto *source = samp.asPrimitive.data
+ (primID * info.sizeInBytes) + (samp.asPrimitive.offset * info.sizeInBytes);
return toRGBA(source, info);
} else if (samp.type == dco::Sampler::Transform) {
vec4f inAttr = getAttribute(geom, samp.inAttribute, primID, uv);
vec4f inAttr = attribs[(int)samp.inAttribute];
return samp.outTransform * inAttr + samp.outOffset;
} else {
vec4f inAttr = getAttribute(geom, samp.inAttribute, primID, uv);
vec4f inAttr = attribs[(int)samp.inAttribute];

inAttr = samp.inTransform * inAttr + samp.inOffset;

Expand All @@ -487,86 +487,86 @@ inline vec4 getSample(

VSNRAY_FUNC
inline vec4 getRGBA(const dco::MaterialParamRGB &param,
const dco::Geometry &geom,
const dco::Sampler *samplers,
unsigned primID, const vec2 uv)
const float4 *attribs,
unsigned primID)
{
if (param.samplerID < UINT_MAX)
return getSample(samplers[param.samplerID], geom, primID, uv);
return getSample(samplers[param.samplerID], attribs, primID);
else if (param.attribute != dco::Attribute::None)
return getAttribute(geom, param.attribute, primID, uv);
return attribs[(int)param.attribute];
else
return vec4f(param.rgb, 1.f);
}

VSNRAY_FUNC
inline float getF(const dco::MaterialParamF &param,
const dco::Geometry &geom,
const dco::Sampler *samplers,
unsigned primID, const vec2 uv)
const float4 *attribs,
unsigned primID)
{
if (param.samplerID < UINT_MAX)
return getSample(samplers[param.samplerID], geom, primID, uv).x;
return getSample(samplers[param.samplerID], attribs, primID).x;
else if (param.attribute != dco::Attribute::None)
return getAttribute(geom, param.attribute, primID, uv).x;
return attribs[(int)param.attribute].x;
else
return param.f;
}

VSNRAY_FUNC
inline vec4 getColorMatte(const dco::Material &mat,
const dco::Geometry &geom,
const dco::Sampler *samplers,
unsigned primID, const vec2 uv)
const float4 *attribs,
unsigned primID)
{
return getRGBA(mat.asMatte.color, geom, samplers, primID, uv);
return getRGBA(mat.asMatte.color, samplers, attribs, primID);
}

VSNRAY_FUNC
inline vec4 getColorPBM(const dco::Material &mat,
const dco::Geometry &geom,
const dco::Sampler *samplers,
unsigned primID, const vec2 uv)
const float4 *attribs,
unsigned primID)
{
const float metallic = getF(
mat.asPhysicallyBased.metallic, geom, samplers, primID, uv);
vec4f color = getRGBA(mat.asPhysicallyBased.baseColor, geom, samplers, primID, uv);
mat.asPhysicallyBased.metallic, samplers, attribs, primID);
vec4f color = getRGBA(mat.asPhysicallyBased.baseColor, samplers, attribs, primID);
return lerp(color, vec4f(0.f, 0.f, 0.f, color.w), metallic);
}

VSNRAY_FUNC
inline vec4 getColor(const dco::Material &mat,
const dco::Geometry &geom,
const dco::Sampler *samplers,
unsigned primID, const vec2 uv)
const float4 *attribs,
unsigned primID)
{
vec4f color{0.f, 0.f, 0.f, 1.f};
if (mat.type == dco::Material::Matte)
color = getColorMatte(mat, geom, samplers, primID, uv);
color = getColorMatte(mat, samplers, attribs, primID);
else if (mat.type == dco::Material::PhysicallyBased) {
color = getColorPBM(mat, geom, samplers, primID, uv);
color = getColorPBM(mat, samplers, attribs, primID);
}
return color;
}

VSNRAY_FUNC
inline float getOpacity(const dco::Material &mat,
const dco::Geometry &geom,
const dco::Sampler *samplers,
unsigned primID, const vec2 uv)
const float4 *attribs,
unsigned primID)
{
float opacity = 1.f;
dco::AlphaMode mode{dco::AlphaMode::Opaque};
float cutoff = 0.5f;

if (mat.type == dco::Material::Matte) {
vec4f color = getColorMatte(mat, geom, samplers, primID, uv);
opacity = color.w * getF(mat.asMatte.opacity, geom, samplers, primID, uv);
vec4f color = getColorMatte(mat, samplers, attribs, primID);
opacity = color.w * getF(mat.asMatte.opacity, samplers, attribs, primID);
mode = mat.asMatte.alphaMode;
cutoff = mat.asMatte.alphaCutoff;
} else if (mat.type == dco::Material::PhysicallyBased) {
vec4f color = getColorPBM(mat, geom, samplers, primID, uv);
opacity = color.w * getF(mat.asPhysicallyBased.opacity, geom, samplers, primID, uv);
vec4f color = getColorPBM(mat, samplers, attribs, primID);
opacity = color.w * getF(mat.asPhysicallyBased.opacity, samplers, attribs, primID);
mode = mat.asPhysicallyBased.alphaMode;
cutoff = mat.asPhysicallyBased.alphaCutoff;
}
Expand All @@ -581,17 +581,17 @@ inline float getOpacity(const dco::Material &mat,

VSNRAY_FUNC
inline vec3 getPerturbedNormal(const dco::Material &mat,
const dco::Geometry &geom,
const dco::Sampler *samplers,
unsigned primID, const vec2 uv,
const float4 *attribs,
unsigned primID,
const vec3 T, const vec3 B, const vec3 N)
{
vec3f pn = N;

mat3 TBN(T,B,N);
if (mat.type == dco::Material::PhysicallyBased) {
const auto &samp = samplers[mat.asPhysicallyBased.normal.samplerID];
vec4 s = getSample(samp, geom, primID, uv);
vec4 s = getSample(samp, attribs, primID);
vec3 tbnN = s.xyz();
if (length(tbnN) > 0.f) {
vec3f objN = normalize(TBN * tbnN);
Expand Down Expand Up @@ -665,21 +665,21 @@ inline float V_Kelemen(float LdotH, const float EPS)

VSNRAY_FUNC
inline vec3 evalPhysicallyBasedMaterial(const dco::Material &mat,
const dco::Geometry &geom,
const dco::Sampler *samplers,
unsigned primID, const vec2 uv,
const float4 *attribs,
unsigned primID,
const vec3 Ng, const vec3 Ns,
const vec3 viewDir, const vec3 lightDir,
const vec3 lightIntensity)
{
const float metallic = getF(
mat.asPhysicallyBased.metallic, geom, samplers, primID, uv);
mat.asPhysicallyBased.metallic, samplers, attribs, primID);
const float roughness = getF(
mat.asPhysicallyBased.roughness, geom, samplers, primID, uv);
mat.asPhysicallyBased.roughness, samplers, attribs, primID);
const float clearcoat = getF(
mat.asPhysicallyBased.clearcoat, geom, samplers, primID, uv);
mat.asPhysicallyBased.clearcoat, samplers, attribs, primID);
const float clearcoatRoughness = getF(
mat.asPhysicallyBased.clearcoatRoughness, geom, samplers, primID, uv);
mat.asPhysicallyBased.clearcoatRoughness, samplers, attribs, primID);
const float ior = mat.asPhysicallyBased.ior;

const float alpha = roughness * roughness;
Expand All @@ -695,7 +695,7 @@ inline vec3 evalPhysicallyBasedMaterial(const dco::Material &mat,

// Diffuse:
vec3 diffuseColor = getRGBA(
mat.asPhysicallyBased.baseColor, geom, samplers, primID, uv).xyz();
mat.asPhysicallyBased.baseColor, samplers, attribs, primID).xyz();

// Fresnel
vec3 f0 = lerp(vec3(pow2((1.f-ior)/(1.f+ior))), diffuseColor, metallic);
Expand Down Expand Up @@ -730,16 +730,16 @@ inline vec3 evalPhysicallyBasedMaterial(const dco::Material &mat,

VSNRAY_FUNC
inline vec3 evalMaterial(const dco::Material &mat,
const dco::Geometry &geom,
const dco::Sampler *samplers,
unsigned primID, const vec2 uv,
const float4 *attribs,
unsigned primID,
const vec3 Ng, const vec3 Ns,
const vec3 viewDir, const vec3 lightDir,
const vec3 lightIntensity)
{
vec3 shadedColor{0.f, 0.f, 0.f};
if (mat.type == dco::Material::Matte) {
vec4f color = getColor(mat, geom, samplers, primID, uv);
vec4f color = getColor(mat, samplers, attribs, primID);

shade_record<float> sr;
sr.normal = Ns;
Expand All @@ -756,9 +756,9 @@ inline vec3 evalMaterial(const dco::Material &mat,
shadedColor = to_rgb(vmat.shade(sr));
} else if (mat.type == dco::Material::PhysicallyBased) {
shadedColor = evalPhysicallyBasedMaterial(mat,
geom,
samplers,
primID, uv,
attribs,
primID,
Ng, Ns,
viewDir, lightDir,
lightIntensity);
Expand Down Expand Up @@ -798,7 +798,13 @@ inline hit_record<Ray, primitive<unsigned>> intersectSurfaces(
const dco::Group &group = onDevice.groups[inst.groupID];
const dco::Geometry &geom = onDevice.geometries[group.geoms[hr.geom_id]];
const dco::Material &mat = onDevice.materials[group.materials[hr.geom_id]];
float opacity = getOpacity(mat, geom, onDevice.samplers, hr.prim_id, uv);

float4 attribs[5];
for (int i=0; i<5; ++i) {
attribs[i] = getAttribute(geom, (dco::Attribute)i, hr.prim_id, uv);
}

float opacity = getOpacity(mat, onDevice.samplers, attribs, hr.prim_id);

float r = ss.random();
if (r > opacity) {
Expand Down

0 comments on commit 182b9db

Please sign in to comment.