Irradiance works
This commit is contained in:
@@ -146,7 +146,6 @@ Here is the material generated from the above JSON example:
|
|||||||
```cpp
|
```cpp
|
||||||
import VERTEX_INPUT_IMPORT;
|
import VERTEX_INPUT_IMPORT;
|
||||||
import Material;
|
import Material;
|
||||||
import BRDF;
|
|
||||||
import MaterialParameter;
|
import MaterialParameter;
|
||||||
|
|
||||||
struct Placeholder: IMaterial {
|
struct Placeholder: IMaterial {
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
uint lightIndex = pLightCullingData.lightIndexList[startOffset + i];
|
uint lightIndex = pLightCullingData.lightIndexList[startOffset + i];
|
||||||
result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf);
|
result += pLightEnv.pointLights[lightIndex].illuminate(lightingParams, brdf);
|
||||||
}
|
}
|
||||||
result += brdf.evaluateAmbient();
|
result += brdf.evaluateAmbient(lightingParams.viewDir_WS);
|
||||||
return float4(result, brdf.getAlpha());
|
return float4(result, brdf.getAlpha());
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,40 @@
|
|||||||
struct VertexOutput
|
|
||||||
{
|
|
||||||
float4 svPos : SV_Position;
|
|
||||||
float3 localPos : LOCALPOS;
|
|
||||||
};
|
|
||||||
const static float3 vertices[] = {
|
const static float3 vertices[] = {
|
||||||
|
// Right
|
||||||
|
float3( 1, -1, 1),
|
||||||
|
float3( 1, 1, 1),
|
||||||
|
float3( 1, -1, -1),
|
||||||
|
|
||||||
|
float3( 1, -1, -1),
|
||||||
|
float3( 1, 1, 1),
|
||||||
|
float3( 1, 1, -1),
|
||||||
|
|
||||||
|
// Left
|
||||||
|
float3(-1, -1, -1),
|
||||||
|
float3(-1, 1, -1),
|
||||||
|
float3(-1, -1, 1),
|
||||||
|
|
||||||
|
float3(-1, -1, 1),
|
||||||
|
float3(-1, 1, -1),
|
||||||
|
float3(-1, 1, 1),
|
||||||
|
|
||||||
|
// Bottom
|
||||||
|
float3(-1, 1, 1),
|
||||||
|
float3(-1, 1, -1),
|
||||||
|
float3( 1, 1, 1),
|
||||||
|
|
||||||
|
float3( 1, 1, 1),
|
||||||
|
float3(-1, 1, -1),
|
||||||
|
float3( 1, 1, -1),
|
||||||
|
|
||||||
|
// Top
|
||||||
|
float3(-1, -1, -1),
|
||||||
|
float3(-1, -1, 1),
|
||||||
|
float3( 1, -1, -1),
|
||||||
|
|
||||||
|
float3( 1, -1, -1),
|
||||||
|
float3(-1, -1, 1),
|
||||||
|
float3( 1, -1, 1),
|
||||||
|
|
||||||
// Back
|
// Back
|
||||||
float3(-1, -1, 1),
|
float3(-1, -1, 1),
|
||||||
float3(-1, 1, 1),
|
float3(-1, 1, 1),
|
||||||
@@ -21,42 +52,6 @@ const static float3 vertices[] = {
|
|||||||
float3(-1, -1, -1),
|
float3(-1, -1, -1),
|
||||||
float3( 1, 1, -1),
|
float3( 1, 1, -1),
|
||||||
float3(-1, 1, -1),
|
float3(-1, 1, -1),
|
||||||
|
|
||||||
// Top
|
|
||||||
float3(-1, -1, -1),
|
|
||||||
float3(-1, -1, 1),
|
|
||||||
float3( 1, -1, -1),
|
|
||||||
|
|
||||||
float3( 1, -1, -1),
|
|
||||||
float3(-1, -1, 1),
|
|
||||||
float3( 1, -1, 1),
|
|
||||||
|
|
||||||
// Bottom
|
|
||||||
float3(-1, 1, 1),
|
|
||||||
float3(-1, 1, -1),
|
|
||||||
float3( 1, 1, 1),
|
|
||||||
|
|
||||||
float3( 1, 1, 1),
|
|
||||||
float3(-1, 1, -1),
|
|
||||||
float3( 1, 1, -1),
|
|
||||||
|
|
||||||
// Left
|
|
||||||
float3(-1, -1, -1),
|
|
||||||
float3(-1, 1, -1),
|
|
||||||
float3(-1, -1, 1),
|
|
||||||
|
|
||||||
float3(-1, -1, 1),
|
|
||||||
float3(-1, 1, -1),
|
|
||||||
float3(-1, 1, 1),
|
|
||||||
|
|
||||||
// Right
|
|
||||||
float3( 1, -1, 1),
|
|
||||||
float3( 1, 1, 1),
|
|
||||||
float3( 1, -1, -1),
|
|
||||||
|
|
||||||
float3( 1, -1, -1),
|
|
||||||
float3( 1, 1, 1),
|
|
||||||
float3( 1, 1, -1),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ViewParams
|
struct ViewParams
|
||||||
@@ -65,31 +60,66 @@ struct ViewParams
|
|||||||
float4x4 projection;
|
float4x4 projection;
|
||||||
Texture2D equirectangularMap;
|
Texture2D equirectangularMap;
|
||||||
SamplerState sampler;
|
SamplerState sampler;
|
||||||
|
TextureCube cubeMap;
|
||||||
};
|
};
|
||||||
ParameterBlock<ViewParams> pViewParams;
|
ParameterBlock<ViewParams> pViewParams;
|
||||||
|
struct VertexOutput
|
||||||
|
{
|
||||||
|
float4 svPos : SV_Position;
|
||||||
|
float3 localPos : LOCALPOS;
|
||||||
|
};
|
||||||
[shader("vertex")]
|
[shader("vertex")]
|
||||||
VertexOutput vertMain(uint vertexIndex : SV_VertexID, uint viewIndex : SV_ViewID)
|
VertexOutput vertMain(uint vertexIndex : SV_VertexID, uint viewIndex : SV_ViewID)
|
||||||
{
|
{
|
||||||
VertexOutput output;
|
VertexOutput output;
|
||||||
output.localPos = vertices[vertexIndex + 6 * viewIndex];
|
output.localPos = vertices[vertexIndex];
|
||||||
output.svPos = mul(pViewParams.projection, mul(pViewParams.view[viewIndex], float4(vertices[vertexIndex], 1)));
|
output.svPos = mul(pViewParams.projection, mul(pViewParams.view[viewIndex], float4(output.localPos, 1)));
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
const static float2 invAtan = float2(0.1591, 0.3183);
|
const static float2 invAtan = float2(0.1591, 0.3183);
|
||||||
float2 sampleSphericalMap(float3 v)
|
float2 sampleSphericalMap(float3 v)
|
||||||
{
|
{
|
||||||
float2 uv = float2(atan(v.z / v.x), asin(v.y));
|
float2 uv = float2(atan2(v.z, v.x), asin(v.y));
|
||||||
uv *= invAtan;
|
uv *= invAtan;
|
||||||
uv += 0.5;
|
uv += 0.5;
|
||||||
return uv;
|
return uv;
|
||||||
}
|
}
|
||||||
|
|
||||||
[shader("fragment")]
|
[shader("pixel")]
|
||||||
float4 fragMain(float3 localPos : LOCALPOS) : SV_Target
|
float4 computeCubemap(float3 localPos : LOCALPOS) : SV_Target
|
||||||
{
|
{
|
||||||
float2 uv = sampleSphericalMap(normalize(localPos));
|
float2 uv = sampleSphericalMap(normalize(localPos));
|
||||||
float3 color = pViewParams.equirectangularMap.Sample(pViewParams.sampler, uv).rgb;
|
float3 color = pViewParams.equirectangularMap.Sample(pViewParams.sampler, uv).rgb;
|
||||||
return float4(color, 1);
|
return float4(color, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const float PI = 3.14159265359;
|
||||||
|
[shader("pixel")]
|
||||||
|
float4 convolveCubemap(float3 localPos : LOCALPOS) : SV_Target
|
||||||
|
{
|
||||||
|
float3 normal = normalize(localPos);
|
||||||
|
|
||||||
|
float3 irradiance = float3(0);
|
||||||
|
|
||||||
|
float3 up = float3(0, 1, 0);
|
||||||
|
float3 right = normalize(cross(up, normal));
|
||||||
|
up = normalize(cross(normal, right));
|
||||||
|
|
||||||
|
float sampleDelta = 0.025;
|
||||||
|
float nrSamples = 0.0f;
|
||||||
|
for(float phi = 0; phi < 2.0 * PI; phi += sampleDelta)
|
||||||
|
{
|
||||||
|
for(float theta = 0; theta < 0.5 * PI; theta += sampleDelta)
|
||||||
|
{
|
||||||
|
float3 tangentSample = float3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
|
||||||
|
float3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * normal;
|
||||||
|
|
||||||
|
irradiance += pViewParams.cubeMap.Sample(pViewParams.sampler, sampleVec).rgb * cos(theta) * sin(theta);
|
||||||
|
nrSamples++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
irradiance = PI * irradiance * (1.0 / nrSamples);
|
||||||
|
|
||||||
|
return float4(irradiance, 1);
|
||||||
}
|
}
|
||||||
@@ -1,291 +0,0 @@
|
|||||||
import Common;
|
|
||||||
|
|
||||||
interface IBRDF
|
|
||||||
{
|
|
||||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor);
|
|
||||||
[mutating] void transformNormal(float3x3 tangentToWorld);
|
|
||||||
float3 getNormal();
|
|
||||||
float3 getBaseColor();
|
|
||||||
float3 evaluateAmbient();
|
|
||||||
float getAlpha();
|
|
||||||
float3 getEmissive();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Phong : IBRDF
|
|
||||||
{
|
|
||||||
float3 baseColor;
|
|
||||||
float alpha;
|
|
||||||
float3 specular;
|
|
||||||
float3 normal;
|
|
||||||
float3 ambient;
|
|
||||||
float shininess;
|
|
||||||
float3 emissive;
|
|
||||||
|
|
||||||
__init()
|
|
||||||
{
|
|
||||||
baseColor = float3(0, 0, 0);
|
|
||||||
alpha = 1;
|
|
||||||
specular = float3(0, 0, 0);
|
|
||||||
normal = float3(0, 0, 1);
|
|
||||||
ambient = float3(0, 0, 0);
|
|
||||||
shininess = 0;
|
|
||||||
emissive = float3(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
|
||||||
{
|
|
||||||
float3 normal_WS = normal;
|
|
||||||
float3 nDotL = dot(normal_WS, lightDir_WS);
|
|
||||||
float3 r = 2 * (nDotL) * normal_WS - lightDir_WS;
|
|
||||||
float rDotV = dot(r, viewDir_WS);
|
|
||||||
|
|
||||||
return lightColor * (baseColor * max(nDotL, 0.0)) + specular * pow(max(rDotV, 0.0), max(shininess, 1));
|
|
||||||
}
|
|
||||||
[mutating]
|
|
||||||
void transformNormal(float3x3 tangentToWorld)
|
|
||||||
{
|
|
||||||
normal = normalize(mul(tangentToWorld, normal));
|
|
||||||
}
|
|
||||||
float3 getNormal()
|
|
||||||
{
|
|
||||||
return normal;
|
|
||||||
}
|
|
||||||
float3 getBaseColor()
|
|
||||||
{
|
|
||||||
return baseColor;
|
|
||||||
}
|
|
||||||
float3 evaluateAmbient()
|
|
||||||
{
|
|
||||||
return ambient;
|
|
||||||
}
|
|
||||||
float getAlpha()
|
|
||||||
{
|
|
||||||
return alpha;
|
|
||||||
}
|
|
||||||
float3 getEmissive()
|
|
||||||
{
|
|
||||||
return emissive;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BlinnPhong : IBRDF
|
|
||||||
{
|
|
||||||
float3 baseColor;
|
|
||||||
float alpha;
|
|
||||||
float3 specularColor;
|
|
||||||
float3 normal;
|
|
||||||
float shininess;
|
|
||||||
float3 ambient;
|
|
||||||
float3 emissive;
|
|
||||||
|
|
||||||
__init()
|
|
||||||
{
|
|
||||||
baseColor = float3(0, 0, 0);
|
|
||||||
alpha = 1;
|
|
||||||
specularColor = float3(0, 0, 0);
|
|
||||||
normal = float3(0, 0, 1);
|
|
||||||
shininess = 4;
|
|
||||||
ambient = float3(0, 0, 0);
|
|
||||||
emissive = float3(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
|
||||||
{
|
|
||||||
float3 normal_WS = normal;
|
|
||||||
float diffuse = max(dot(normal_WS, lightDir_WS), 0);
|
|
||||||
float3 h = normalize(lightDir_WS + viewDir_WS);
|
|
||||||
float specular = pow(saturate(dot(normal_WS, h)), shininess);
|
|
||||||
|
|
||||||
return (baseColor * diffuse * lightColor) + (specularColor * specular);
|
|
||||||
}
|
|
||||||
[mutating]
|
|
||||||
void transformNormal(float3x3 tangentToWorld)
|
|
||||||
{
|
|
||||||
normal = normalize(mul(tangentToWorld, normal));
|
|
||||||
}
|
|
||||||
float3 getNormal()
|
|
||||||
{
|
|
||||||
return normal;
|
|
||||||
}
|
|
||||||
float3 getBaseColor()
|
|
||||||
{
|
|
||||||
return baseColor;
|
|
||||||
}
|
|
||||||
float3 evaluateAmbient()
|
|
||||||
{
|
|
||||||
return ambient;
|
|
||||||
}
|
|
||||||
float getAlpha()
|
|
||||||
{
|
|
||||||
return alpha;
|
|
||||||
}
|
|
||||||
float3 getEmissive()
|
|
||||||
{
|
|
||||||
return emissive;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CelShading : IBRDF
|
|
||||||
{
|
|
||||||
float3 baseColor;
|
|
||||||
float alpha;
|
|
||||||
float3 normal;
|
|
||||||
float3 emissive;
|
|
||||||
|
|
||||||
__init()
|
|
||||||
{
|
|
||||||
baseColor = float3(0, 0, 0);
|
|
||||||
alpha = 1;
|
|
||||||
normal = float3(0, 0, 1);
|
|
||||||
emissive = float3(0, 0, 0);
|
|
||||||
}
|
|
||||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
|
||||||
{
|
|
||||||
float3 normal_WS = normal;
|
|
||||||
float nDotL = dot(normal_WS, lightDir_WS);
|
|
||||||
float diffuse = max(nDotL, 0);
|
|
||||||
|
|
||||||
float3 darkenedBase = baseColor * 0.8;
|
|
||||||
if(diffuse > 0.5)
|
|
||||||
{
|
|
||||||
return baseColor * lightColor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return darkenedBase * lightColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[mutating]
|
|
||||||
void transformNormal(float3x3 tangentToWorld)
|
|
||||||
{
|
|
||||||
normal = normalize(mul(tangentToWorld, normal));
|
|
||||||
}
|
|
||||||
float3 getNormal()
|
|
||||||
{
|
|
||||||
return normal;
|
|
||||||
}
|
|
||||||
float3 getBaseColor()
|
|
||||||
{
|
|
||||||
return baseColor;
|
|
||||||
}
|
|
||||||
float3 evaluateAmbient()
|
|
||||||
{
|
|
||||||
return float3(0, 0, 0);
|
|
||||||
}
|
|
||||||
float getAlpha()
|
|
||||||
{
|
|
||||||
return alpha;
|
|
||||||
}
|
|
||||||
float3 getEmissive()
|
|
||||||
{
|
|
||||||
return emissive;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://learnopengl.com/PBR/Theory
|
|
||||||
struct CookTorrance : IBRDF
|
|
||||||
{
|
|
||||||
float3 baseColor;
|
|
||||||
float alpha;
|
|
||||||
float3 normal;
|
|
||||||
float roughness;
|
|
||||||
float metallic;
|
|
||||||
float ambientOcclusion;
|
|
||||||
float3 emissive;
|
|
||||||
|
|
||||||
__init()
|
|
||||||
{
|
|
||||||
baseColor = float3(0, 0, 0);
|
|
||||||
alpha = 1;
|
|
||||||
normal = float3(0, 0, 1);
|
|
||||||
roughness = 0;
|
|
||||||
metallic = 0;
|
|
||||||
ambientOcclusion = 1;
|
|
||||||
emissive = float3(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float TrowbridgeReitzGGX(float3 normal, float3 halfway)
|
|
||||||
{
|
|
||||||
float a_sqr = roughness * roughness;
|
|
||||||
float nDotH = max(dot(normal, halfway), 0.0);
|
|
||||||
float nDotH_sqr = nDotH * nDotH;
|
|
||||||
|
|
||||||
float denom = (nDotH_sqr * (a_sqr - 1.0) + 1.0);
|
|
||||||
|
|
||||||
return a_sqr / (PI * denom * denom);
|
|
||||||
}
|
|
||||||
|
|
||||||
float SchlickGGX(float nDotV, float k)
|
|
||||||
{
|
|
||||||
return nDotV / (nDotV * (1.0 - k) + k);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Smith(float3 normal, float3 view, float3 light)
|
|
||||||
{
|
|
||||||
float k = (roughness + 1);
|
|
||||||
k = (k * k) / 8;
|
|
||||||
float nDotV = max(dot(normal, view), 0.0);
|
|
||||||
float nDotL = max(dot(normal, light), 0.0);
|
|
||||||
float ggx1 = SchlickGGX(nDotV, k);
|
|
||||||
float ggx2 = SchlickGGX(nDotL, k);
|
|
||||||
return ggx1 * ggx2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 FresnelSchlick(float cosTheta, float3 F0)
|
|
||||||
{
|
|
||||||
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
|
||||||
{
|
|
||||||
float3 n = normal;
|
|
||||||
float3 h = normalize(lightDir_WS + viewDir_WS);
|
|
||||||
|
|
||||||
float3 F0 = float3(0.04);
|
|
||||||
F0 = lerp(F0, baseColor, metallic);
|
|
||||||
|
|
||||||
float3 F = FresnelSchlick(max(dot(h, viewDir_WS), 0.0), F0);
|
|
||||||
|
|
||||||
float NDF = TrowbridgeReitzGGX(n, h);
|
|
||||||
float G = Smith(n, viewDir_WS, lightDir_WS);
|
|
||||||
|
|
||||||
float3 num = NDF * G * F;
|
|
||||||
float denom = 4.0 * max(dot(n, viewDir_WS), 0.0) * max(dot(n, lightDir_WS), 0.0) + 0.000001;
|
|
||||||
float3 specular = num / denom;
|
|
||||||
|
|
||||||
float3 k_s = F;
|
|
||||||
float3 k_d = float3(1.0) - k_s;
|
|
||||||
|
|
||||||
k_d *= 1.0 - metallic;
|
|
||||||
|
|
||||||
float nDotL = max(dot(n, lightDir_WS), 0.0);
|
|
||||||
|
|
||||||
float3 result = (k_d * baseColor / PI + specular) * nDotL * lightColor;
|
|
||||||
return result * ambientOcclusion;
|
|
||||||
}
|
|
||||||
[mutating]
|
|
||||||
void transformNormal(float3x3 tangentToWorld)
|
|
||||||
{
|
|
||||||
normal = normalize(mul(tangentToWorld, normal));
|
|
||||||
}
|
|
||||||
float3 getNormal()
|
|
||||||
{
|
|
||||||
return normal;
|
|
||||||
}
|
|
||||||
float3 getBaseColor()
|
|
||||||
{
|
|
||||||
return baseColor;
|
|
||||||
}
|
|
||||||
float3 evaluateAmbient()
|
|
||||||
{
|
|
||||||
return float3(0.03) * baseColor * ambientOcclusion;
|
|
||||||
}
|
|
||||||
float getAlpha()
|
|
||||||
{
|
|
||||||
return alpha;
|
|
||||||
}
|
|
||||||
float3 getEmissive()
|
|
||||||
{
|
|
||||||
return emissive;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import Common;
|
import Common;
|
||||||
import BRDF;
|
|
||||||
import MaterialParameter;
|
import MaterialParameter;
|
||||||
|
|
||||||
interface ILightEnv
|
interface ILightEnv
|
||||||
@@ -28,7 +27,7 @@ struct PointLight : ILightEnv
|
|||||||
{
|
{
|
||||||
float3 lightDir_WS = position_WS.xyz - params.position_WS;
|
float3 lightDir_WS = position_WS.xyz - params.position_WS;
|
||||||
float d = length(lightDir_WS);
|
float d = length(lightDir_WS);
|
||||||
float illuminance = max(1 - d / colorRange.w, 0);
|
float illuminance = max(1 / (d * d), 0);
|
||||||
return illuminance * brdf.evaluate(params.viewDir_WS, normalize(lightDir_WS), colorRange.xyz * position_WS.w);
|
return illuminance * brdf.evaluate(params.viewDir_WS, normalize(lightDir_WS), colorRange.xyz * position_WS.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,6 +64,308 @@ struct LightEnv
|
|||||||
uint numDirectionalLights;
|
uint numDirectionalLights;
|
||||||
StructuredBuffer<PointLight> pointLights;
|
StructuredBuffer<PointLight> pointLights;
|
||||||
uint numPointLights;
|
uint numPointLights;
|
||||||
|
TextureCube irradianceMap;
|
||||||
|
SamplerState irradianceSampler;
|
||||||
};
|
};
|
||||||
layout(set=3)
|
layout(set=3)
|
||||||
ParameterBlock<LightEnv> pLightEnv;
|
ParameterBlock<LightEnv> pLightEnv;
|
||||||
|
|
||||||
|
|
||||||
|
interface IBRDF
|
||||||
|
{
|
||||||
|
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor);
|
||||||
|
[mutating] void transformNormal(float3x3 tangentToWorld);
|
||||||
|
float3 getNormal();
|
||||||
|
float3 getBaseColor();
|
||||||
|
float3 evaluateAmbient(float3 viewDir_WS);
|
||||||
|
float getAlpha();
|
||||||
|
float3 getEmissive();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Phong : IBRDF
|
||||||
|
{
|
||||||
|
float3 baseColor;
|
||||||
|
float alpha;
|
||||||
|
float3 specular;
|
||||||
|
float3 normal;
|
||||||
|
float3 ambient;
|
||||||
|
float shininess;
|
||||||
|
float3 emissive;
|
||||||
|
|
||||||
|
__init()
|
||||||
|
{
|
||||||
|
baseColor = float3(0, 0, 0);
|
||||||
|
alpha = 1;
|
||||||
|
specular = float3(0, 0, 0);
|
||||||
|
normal = float3(0, 0, 1);
|
||||||
|
ambient = float3(0, 0, 0);
|
||||||
|
shininess = 0;
|
||||||
|
emissive = float3(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||||
|
{
|
||||||
|
float3 normal_WS = normal;
|
||||||
|
float3 nDotL = dot(normal_WS, lightDir_WS);
|
||||||
|
float3 r = 2 * (nDotL) * normal_WS - lightDir_WS;
|
||||||
|
float rDotV = dot(r, viewDir_WS);
|
||||||
|
|
||||||
|
return lightColor * (baseColor * max(nDotL, 0.0)) + specular * pow(max(rDotV, 0.0), max(shininess, 1));
|
||||||
|
}
|
||||||
|
[mutating]
|
||||||
|
void transformNormal(float3x3 tangentToWorld)
|
||||||
|
{
|
||||||
|
normal = normalize(mul(tangentToWorld, normal));
|
||||||
|
}
|
||||||
|
float3 getNormal()
|
||||||
|
{
|
||||||
|
return normal;
|
||||||
|
}
|
||||||
|
float3 getBaseColor()
|
||||||
|
{
|
||||||
|
return baseColor;
|
||||||
|
}
|
||||||
|
float3 evaluateAmbient(float3 viewDir_WS)
|
||||||
|
{
|
||||||
|
return ambient;
|
||||||
|
}
|
||||||
|
float getAlpha()
|
||||||
|
{
|
||||||
|
return alpha;
|
||||||
|
}
|
||||||
|
float3 getEmissive()
|
||||||
|
{
|
||||||
|
return emissive;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BlinnPhong : IBRDF
|
||||||
|
{
|
||||||
|
float3 baseColor;
|
||||||
|
float alpha;
|
||||||
|
float3 specularColor;
|
||||||
|
float3 normal;
|
||||||
|
float shininess;
|
||||||
|
float3 ambient;
|
||||||
|
float3 emissive;
|
||||||
|
|
||||||
|
__init()
|
||||||
|
{
|
||||||
|
baseColor = float3(0, 0, 0);
|
||||||
|
alpha = 1;
|
||||||
|
specularColor = float3(0, 0, 0);
|
||||||
|
normal = float3(0, 0, 1);
|
||||||
|
shininess = 4;
|
||||||
|
ambient = float3(0, 0, 0);
|
||||||
|
emissive = float3(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||||
|
{
|
||||||
|
float3 normal_WS = normal;
|
||||||
|
float diffuse = max(dot(normal_WS, lightDir_WS), 0);
|
||||||
|
float3 h = normalize(lightDir_WS + viewDir_WS);
|
||||||
|
float specular = pow(saturate(dot(normal_WS, h)), shininess);
|
||||||
|
|
||||||
|
return (baseColor * diffuse * lightColor) + (specularColor * specular);
|
||||||
|
}
|
||||||
|
[mutating]
|
||||||
|
void transformNormal(float3x3 tangentToWorld)
|
||||||
|
{
|
||||||
|
normal = normalize(mul(tangentToWorld, normal));
|
||||||
|
}
|
||||||
|
float3 getNormal()
|
||||||
|
{
|
||||||
|
return normal;
|
||||||
|
}
|
||||||
|
float3 getBaseColor()
|
||||||
|
{
|
||||||
|
return baseColor;
|
||||||
|
}
|
||||||
|
float3 evaluateAmbient(float3 viewDir_WS)
|
||||||
|
{
|
||||||
|
return ambient;
|
||||||
|
}
|
||||||
|
float getAlpha()
|
||||||
|
{
|
||||||
|
return alpha;
|
||||||
|
}
|
||||||
|
float3 getEmissive()
|
||||||
|
{
|
||||||
|
return emissive;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CelShading : IBRDF
|
||||||
|
{
|
||||||
|
float3 baseColor;
|
||||||
|
float alpha;
|
||||||
|
float3 normal;
|
||||||
|
float3 emissive;
|
||||||
|
|
||||||
|
__init()
|
||||||
|
{
|
||||||
|
baseColor = float3(0, 0, 0);
|
||||||
|
alpha = 1;
|
||||||
|
normal = float3(0, 0, 1);
|
||||||
|
emissive = float3(0, 0, 0);
|
||||||
|
}
|
||||||
|
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||||
|
{
|
||||||
|
float3 normal_WS = normal;
|
||||||
|
float nDotL = dot(normal_WS, lightDir_WS);
|
||||||
|
float diffuse = max(nDotL, 0);
|
||||||
|
|
||||||
|
float3 darkenedBase = baseColor * 0.8;
|
||||||
|
if(diffuse > 0.5)
|
||||||
|
{
|
||||||
|
return baseColor * lightColor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return darkenedBase * lightColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[mutating]
|
||||||
|
void transformNormal(float3x3 tangentToWorld)
|
||||||
|
{
|
||||||
|
normal = normalize(mul(tangentToWorld, normal));
|
||||||
|
}
|
||||||
|
float3 getNormal()
|
||||||
|
{
|
||||||
|
return normal;
|
||||||
|
}
|
||||||
|
float3 getBaseColor()
|
||||||
|
{
|
||||||
|
return baseColor;
|
||||||
|
}
|
||||||
|
float3 evaluateAmbient(float3 viewDir_WS)
|
||||||
|
{
|
||||||
|
return float3(0, 0, 0);
|
||||||
|
}
|
||||||
|
float getAlpha()
|
||||||
|
{
|
||||||
|
return alpha;
|
||||||
|
}
|
||||||
|
float3 getEmissive()
|
||||||
|
{
|
||||||
|
return emissive;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://learnopengl.com/PBR/Theory
|
||||||
|
struct CookTorrance : IBRDF
|
||||||
|
{
|
||||||
|
float3 baseColor;
|
||||||
|
float alpha;
|
||||||
|
float3 normal;
|
||||||
|
float roughness;
|
||||||
|
float metallic;
|
||||||
|
float ambientOcclusion;
|
||||||
|
float3 emissive;
|
||||||
|
|
||||||
|
__init()
|
||||||
|
{
|
||||||
|
baseColor = float3(0, 0, 0);
|
||||||
|
alpha = 1;
|
||||||
|
normal = float3(0, 0, 1);
|
||||||
|
roughness = 0;
|
||||||
|
metallic = 0;
|
||||||
|
ambientOcclusion = 1;
|
||||||
|
emissive = float3(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float TrowbridgeReitzGGX(float3 normal, float3 halfway)
|
||||||
|
{
|
||||||
|
float a = roughness * roughness;
|
||||||
|
float a2 = a * a;
|
||||||
|
float nDotH = max(dot(normal, halfway), 0.0);
|
||||||
|
float nDotH2 = nDotH * nDotH;
|
||||||
|
|
||||||
|
float nom = a2;
|
||||||
|
float denom = (nDotH * (a2 - 1.0) + 1.0);
|
||||||
|
|
||||||
|
return nom / (PI * denom * denom);
|
||||||
|
}
|
||||||
|
|
||||||
|
float SchlickGGX(float nDotV, float k)
|
||||||
|
{
|
||||||
|
return nDotV / (nDotV * (1.0 - k) + k);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Smith(float3 normal, float3 view, float3 light)
|
||||||
|
{
|
||||||
|
float k = (roughness + 1);
|
||||||
|
k = (k * k) / 8;
|
||||||
|
float nDotV = max(dot(normal, view), 0.0);
|
||||||
|
float nDotL = max(dot(normal, light), 0.0);
|
||||||
|
float ggx1 = SchlickGGX(nDotV, k);
|
||||||
|
float ggx2 = SchlickGGX(nDotL, k);
|
||||||
|
return ggx1 * ggx2;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 FresnelSchlick(float cosTheta, float3 F0)
|
||||||
|
{
|
||||||
|
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 evaluate(float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||||
|
{
|
||||||
|
float3 n = normal;
|
||||||
|
float3 h = normalize(lightDir_WS + viewDir_WS);
|
||||||
|
|
||||||
|
float3 F0 = float3(0.04);
|
||||||
|
F0 = lerp(F0, baseColor, metallic);
|
||||||
|
|
||||||
|
float NDF = TrowbridgeReitzGGX(n, h);
|
||||||
|
float G = Smith(n, viewDir_WS, lightDir_WS);
|
||||||
|
float3 F = FresnelSchlick(max(dot(h, viewDir_WS), 0.0), F0);
|
||||||
|
|
||||||
|
float3 num = NDF * G * F;
|
||||||
|
float denom = 4.0 * max(dot(n, viewDir_WS), 0.0) * max(dot(n, lightDir_WS), 0.0) + 0.000001;
|
||||||
|
float3 specular = num / denom;
|
||||||
|
|
||||||
|
float3 k_s = F;
|
||||||
|
float3 k_d = float3(1.0) - k_s;
|
||||||
|
|
||||||
|
k_d *= 1.0 - metallic;
|
||||||
|
|
||||||
|
float nDotL = max(dot(n, lightDir_WS), 0.0);
|
||||||
|
|
||||||
|
float3 result = (k_d * baseColor / PI + specular) * nDotL * lightColor;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
[mutating]
|
||||||
|
void transformNormal(float3x3 tangentToWorld)
|
||||||
|
{
|
||||||
|
normal = normalize(mul(tangentToWorld, normal));
|
||||||
|
}
|
||||||
|
float3 getNormal()
|
||||||
|
{
|
||||||
|
return normal;
|
||||||
|
}
|
||||||
|
float3 getBaseColor()
|
||||||
|
{
|
||||||
|
return baseColor;
|
||||||
|
}
|
||||||
|
float3 evaluateAmbient(float3 viewDir_WS)
|
||||||
|
{
|
||||||
|
float3 F0 = float3(0.04);
|
||||||
|
F0 = lerp(F0, baseColor, metallic);
|
||||||
|
float3 k_s = FresnelSchlick(max(dot(normal, viewDir_WS), 0.0), F0);
|
||||||
|
float3 k_d = 1 - k_s;
|
||||||
|
k_d *= 1 - metallic;
|
||||||
|
float3 irradiance = pLightEnv.irradianceMap.Sample(pLightEnv.irradianceSampler, normal).rgb;
|
||||||
|
float3 diffuse = irradiance * baseColor;
|
||||||
|
return (k_d * diffuse) * ambientOcclusion;
|
||||||
|
}
|
||||||
|
float getAlpha()
|
||||||
|
{
|
||||||
|
return alpha;
|
||||||
|
}
|
||||||
|
float3 getEmissive()
|
||||||
|
{
|
||||||
|
return emissive;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import Common;
|
import Common;
|
||||||
import BRDF;
|
|
||||||
import MaterialParameter;
|
import MaterialParameter;
|
||||||
import Scene;
|
import Scene;
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ void closestHit(inout RayPayload hitValue, in BuiltInTriangleIntersectionAttribu
|
|||||||
if (rnd.z >= p) return;
|
if (rnd.z >= p) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hitValue.light += brdf.getEmissive() * hitValue.emissive + brdf.evaluateAmbient();
|
hitValue.light += brdf.getEmissive() * hitValue.emissive + brdf.evaluateAmbient(lightingParams.viewDir_WS);
|
||||||
//-- Ideal DIFFUSE reflection
|
//-- Ideal DIFFUSE reflection
|
||||||
//if(bool(useNEE)) {
|
//if(bool(useNEE)) {
|
||||||
// accrad += nextEventEstimation(accmat, r.d, params.x, params.nl, kt, false, rnd);
|
// accrad += nextEventEstimation(accmat, r.d, params.x, params.nl, kt, false, rnd);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import MaterialParameter;
|
import MaterialParameter;
|
||||||
import BRDF;
|
|
||||||
|
|
||||||
struct RayTracingParams
|
struct RayTracingParams
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,20 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
|||||||
.offset = {0, 0},
|
.offset = {0, 0},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
convolutionViewport = graphics->createViewport(nullptr, ViewportCreateInfo{
|
||||||
|
.dimensions =
|
||||||
|
{
|
||||||
|
.size = {32, 32},
|
||||||
|
.offset = {0, 0},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
cubeSampler = graphics->createSampler({
|
||||||
|
.magFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.minFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
});
|
||||||
|
|
||||||
cubeRenderLayout = graphics->createDescriptorLayout("pViewParams");
|
cubeRenderLayout = graphics->createDescriptorLayout("pViewParams");
|
||||||
cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
@@ -32,6 +46,10 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
|||||||
.name = "sampler",
|
.name = "sampler",
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
});
|
});
|
||||||
|
cubeRenderLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "cubeMap",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
});
|
||||||
cubeRenderLayout->create();
|
cubeRenderLayout->create();
|
||||||
|
|
||||||
cubePipelineLayout = graphics->createPipelineLayout("CubeRenderLayout");
|
cubePipelineLayout = graphics->createPipelineLayout("CubeRenderLayout");
|
||||||
@@ -43,7 +61,8 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
|||||||
.entryPoints =
|
.entryPoints =
|
||||||
{
|
{
|
||||||
{"vertMain", "EnvironmentMapping"},
|
{"vertMain", "EnvironmentMapping"},
|
||||||
{"fragMain", "EnvironmentMapping"},
|
{"computeCubemap", "EnvironmentMapping"},
|
||||||
|
{"convolveCubemap", "EnvironmentMapping"},
|
||||||
},
|
},
|
||||||
.rootSignature = cubePipelineLayout,
|
.rootSignature = cubePipelineLayout,
|
||||||
});
|
});
|
||||||
@@ -51,14 +70,7 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
|||||||
|
|
||||||
cubeRenderVertex = graphics->createVertexShader({0});
|
cubeRenderVertex = graphics->createVertexShader({0});
|
||||||
cubeRenderFrag = graphics->createFragmentShader({1});
|
cubeRenderFrag = graphics->createFragmentShader({1});
|
||||||
|
convolutionFrag = graphics->createFragmentShader({2});
|
||||||
cubeSampler = graphics->createSampler({
|
|
||||||
.magFilter = Gfx::SE_FILTER_LINEAR,
|
|
||||||
.minFilter = Gfx::SE_FILTER_LINEAR,
|
|
||||||
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
|
||||||
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
|
||||||
.addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvironmentLoader::~EnvironmentLoader() {}
|
EnvironmentLoader::~EnvironmentLoader() {}
|
||||||
@@ -93,12 +105,12 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
|
|||||||
});
|
});
|
||||||
Matrix4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
|
Matrix4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
|
||||||
Matrix4 captureViews[] = {
|
Matrix4 captureViews[] = {
|
||||||
|
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||||
|
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(-1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||||
|
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f), Vector(0.0f, 0.0f, 1.0f)),
|
||||||
|
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, -1.0f, 0.0f), Vector(0.0f, 0.0f, -1.0f)),
|
||||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 1.0f), Vector(0.0f, 1.0f, 0.0f)),
|
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 1.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, -1.0f), Vector(0.0f, 1.0f, 0.0f)),
|
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, -1.0f), Vector(0.0f, 1.0f, 0.0f)),
|
||||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, -1.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f)),
|
|
||||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f)),
|
|
||||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(-1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
|
||||||
glm::lookAt(Vector(0.0f, 0.0f, 0.0f), Vector(1.0f, 0.0f, 0.0f), Vector(0.0f, 1.0f, 0.0f)),
|
|
||||||
};
|
};
|
||||||
Gfx::PDescriptorSet set = cubeRenderLayout->allocateDescriptorSet();
|
Gfx::PDescriptorSet set = cubeRenderLayout->allocateDescriptorSet();
|
||||||
set->updateConstants("view", 0, captureViews);
|
set->updateConstants("view", 0, captureViews);
|
||||||
@@ -110,9 +122,9 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
|
|||||||
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
||||||
.width = 1024,
|
.width = 1024,
|
||||||
.height = 1024,
|
.height = 1024,
|
||||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
});
|
});
|
||||||
cubeRenderPass = graphics->createRenderPass(
|
Gfx::ORenderPass cubeRenderPass = graphics->createRenderPass(
|
||||||
Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout{
|
||||||
.colorAttachments = {Gfx::RenderTargetAttachment(cubeMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
.colorAttachments = {Gfx::RenderTargetAttachment(cubeMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
@@ -139,9 +151,57 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
|
|||||||
renderCommand->bindPipeline(cubeRenderPipeline);
|
renderCommand->bindPipeline(cubeRenderPipeline);
|
||||||
renderCommand->bindDescriptor({set});
|
renderCommand->bindDescriptor({set});
|
||||||
renderCommand->setViewport(cubeRenderViewport);
|
renderCommand->setViewport(cubeRenderViewport);
|
||||||
renderCommand->draw(6, 1, 0, 0);
|
renderCommand->draw(36, 1, 0, 0);
|
||||||
graphics->executeCommands(std::move(renderCommand));
|
graphics->executeCommands(std::move(renderCommand));
|
||||||
graphics->endRenderPass();
|
graphics->endRenderPass();
|
||||||
|
|
||||||
|
Gfx::OTextureCube convolutedMap = graphics->createTextureCube(TextureCreateInfo{
|
||||||
|
.format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT,
|
||||||
|
.width = 32,
|
||||||
|
.height = 32,
|
||||||
|
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||||
|
});
|
||||||
|
Gfx::ORenderPass convolutionPass = graphics->createRenderPass(
|
||||||
|
Gfx::RenderTargetLayout{
|
||||||
|
.colorAttachments = {Gfx::RenderTargetAttachment(convolutedMap, Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)},
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
URect{
|
||||||
|
.size = {32, 32},
|
||||||
|
.offset = {0, 0},
|
||||||
|
},
|
||||||
|
"EnvironmentRenderPass", {0b111111}, {0b111111});
|
||||||
|
convolutionPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
|
||||||
|
.vertexShader = cubeRenderVertex,
|
||||||
|
.fragmentShader = convolutionFrag,
|
||||||
|
.renderPass = convolutionPass,
|
||||||
|
.pipelineLayout = cubePipelineLayout,
|
||||||
|
.colorBlend =
|
||||||
|
{
|
||||||
|
.attachmentCount = 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
set = cubeRenderLayout->allocateDescriptorSet();
|
||||||
|
set->updateConstants("view", 0, captureViews);
|
||||||
|
set->updateConstants("projection", 0, &captureProjection);
|
||||||
|
set->updateSampler("sampler", 0, cubeSampler);
|
||||||
|
set->updateTexture("cubeMap", 0, Gfx::PTextureCube(cubeMap));
|
||||||
|
set->writeChanges();
|
||||||
|
|
||||||
|
graphics->beginRenderPass(convolutionPass);
|
||||||
|
Gfx::ORenderCommand cmd = graphics->createRenderCommand("ConvolutionPass");
|
||||||
|
cmd->bindPipeline(convolutionPipeline);
|
||||||
|
cmd->bindDescriptor({set});
|
||||||
|
cmd->setViewport(convolutionViewport);
|
||||||
|
cmd->draw(36, 1, 0, 0);
|
||||||
|
graphics->executeCommands(std::move(cmd));
|
||||||
|
graphics->endRenderPass();
|
||||||
|
|
||||||
|
asset->skybox = std::move(cubeMap);
|
||||||
|
asset->irradianceMap = std::move(convolutedMap);
|
||||||
|
asset->specularMap = std::move(cubeMap);
|
||||||
graphics->waitDeviceIdle();
|
graphics->waitDeviceIdle();
|
||||||
asset->diffuseMap = std::move(cubeMap);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,10 @@ class EnvironmentLoader {
|
|||||||
Gfx::ODescriptorLayout cubeRenderLayout;
|
Gfx::ODescriptorLayout cubeRenderLayout;
|
||||||
Gfx::OPipelineLayout cubePipelineLayout;
|
Gfx::OPipelineLayout cubePipelineLayout;
|
||||||
Gfx::PGraphicsPipeline cubeRenderPipeline;
|
Gfx::PGraphicsPipeline cubeRenderPipeline;
|
||||||
Gfx::ORenderPass cubeRenderPass;
|
Gfx::OFragmentShader convolutionFrag;
|
||||||
|
Gfx::PGraphicsPipeline convolutionPipeline;
|
||||||
Gfx::OViewport cubeRenderViewport;
|
Gfx::OViewport cubeRenderViewport;
|
||||||
|
Gfx::OViewport convolutionViewport;
|
||||||
Gfx::OSampler cubeSampler;
|
Gfx::OSampler cubeSampler;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
+4
-1
@@ -100,8 +100,11 @@ int main() {
|
|||||||
.filePath = sourcePath / "import/textures/skybox.jpg",
|
.filePath = sourcePath / "import/textures/skybox.jpg",
|
||||||
.type = TextureImportType::TEXTURE_CUBEMAP,
|
.type = TextureImportType::TEXTURE_CUBEMAP,
|
||||||
});
|
});
|
||||||
|
//AssetImporter::importEnvironmentMap(EnvironmentImportArgs{
|
||||||
|
// .filePath = sourcePath / "import/models/main1_sponza/textures/kloppenheim_05_4k.hdr",
|
||||||
|
//});
|
||||||
AssetImporter::importEnvironmentMap(EnvironmentImportArgs{
|
AssetImporter::importEnvironmentMap(EnvironmentImportArgs{
|
||||||
.filePath = sourcePath / "import/models/main1_sponza/textures/kloppenheim_05_4k.hdr",
|
.filePath = sourcePath / "import/textures/newport_loft.hdr",
|
||||||
});
|
});
|
||||||
// AssetImporter::importMesh(MeshImportArgs{
|
// AssetImporter::importMesh(MeshImportArgs{
|
||||||
// .filePath = sourcePath / "import/models/ship.fbx",
|
// .filePath = sourcePath / "import/models/ship.fbx",
|
||||||
|
|||||||
@@ -11,8 +11,12 @@ class EnvironmentMapAsset : public Asset {
|
|||||||
virtual ~EnvironmentMapAsset();
|
virtual ~EnvironmentMapAsset();
|
||||||
virtual void save(ArchiveBuffer& buffer) const override;
|
virtual void save(ArchiveBuffer& buffer) const override;
|
||||||
virtual void load(ArchiveBuffer& buffer) override;
|
virtual void load(ArchiveBuffer& buffer) override;
|
||||||
|
Gfx::PTextureCube getSkybox() const { return skybox; }
|
||||||
|
Gfx::PTextureCube getIrradianceMap() const { return irradianceMap; }
|
||||||
|
Gfx::PTextureCube getSpecularMap() const { return specularMap; }
|
||||||
private:
|
private:
|
||||||
Gfx::OTextureCube diffuseMap;
|
Gfx::OTextureCube skybox;
|
||||||
|
Gfx::OTextureCube irradianceMap;
|
||||||
Gfx::OTextureCube specularMap;
|
Gfx::OTextureCube specularMap;
|
||||||
friend class EnvironmentLoader;
|
friend class EnvironmentLoader;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ void TextureAsset::load(ArchiveBuffer& buffer) {
|
|||||||
.width = ktxHandle->baseWidth,
|
.width = ktxHandle->baseWidth,
|
||||||
.height = ktxHandle->baseHeight,
|
.height = ktxHandle->baseHeight,
|
||||||
.depth = ktxHandle->baseDepth,
|
.depth = ktxHandle->baseDepth,
|
||||||
.layers = ktxHandle->numFaces,
|
|
||||||
.elements = ktxHandle->numLayers,
|
.elements = ktxHandle->numLayers,
|
||||||
.useMip = true,
|
.useMip = true,
|
||||||
.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class Graphics {
|
|||||||
virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo& createInfo) = 0;
|
virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo& createInfo) = 0;
|
||||||
|
|
||||||
virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies, URect renderArea,
|
virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies, URect renderArea,
|
||||||
std::string name = "", Array<uint32> viewMasks = {}, Array<uint32> correlationMasks = {}) = 0;
|
std::string name = "", Array<uint32> viewMasks = {0}, Array<uint32> correlationMasks = {}) = 0;
|
||||||
virtual void beginRenderPass(PRenderPass renderPass) = 0;
|
virtual void beginRenderPass(PRenderPass renderPass) = 0;
|
||||||
virtual void endRenderPass() = 0;
|
virtual void endRenderPass() = 0;
|
||||||
virtual void waitDeviceIdle() = 0;
|
virtual void waitDeviceIdle() = 0;
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ struct TextureCreateInfo {
|
|||||||
uint32 width = 1;
|
uint32 width = 1;
|
||||||
uint32 height = 1;
|
uint32 height = 1;
|
||||||
uint32 depth = 1;
|
uint32 depth = 1;
|
||||||
uint32 layers = 1;
|
|
||||||
uint32 elements = 1;
|
uint32 elements = 1;
|
||||||
uint32 samples = 1;
|
uint32 samples = 1;
|
||||||
bool useMip = false;
|
bool useMip = false;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "BasePass.h"
|
#include "BasePass.h"
|
||||||
#include "Actor/CameraActor.h"
|
#include "Actor/CameraActor.h"
|
||||||
#include "Asset/AssetRegistry.h"
|
#include "Asset/AssetRegistry.h"
|
||||||
|
#include "Asset/EnvironmentMapAsset.h"
|
||||||
#include "Component/Camera.h"
|
#include "Component/Camera.h"
|
||||||
#include "Component/Mesh.h"
|
#include "Component/Mesh.h"
|
||||||
#include "Component/WaterTile.h"
|
#include "Component/WaterTile.h"
|
||||||
@@ -78,8 +79,8 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
skybox = Seele::Component::Skybox{
|
skybox = Seele::Component::Skybox{
|
||||||
.day = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>(),
|
.day = scene->getLightEnvironment()->getEnvironmentMap()->getIrradianceMap(),
|
||||||
.night = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>(),
|
.night = scene->getLightEnvironment()->getEnvironmentMap()->getIrradianceMap(),
|
||||||
.fogColor = Vector(0.1, 0.1, 0.8),
|
.fogColor = Vector(0.1, 0.1, 0.8),
|
||||||
.blendFactor = 0,
|
.blendFactor = 0,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -108,7 +108,6 @@ class RenderPass {
|
|||||||
RenderPass(RenderPass&&) = default;
|
RenderPass(RenderPass&&) = default;
|
||||||
RenderPass& operator=(RenderPass&&) = default;
|
RenderPass& operator=(RenderPass&&) = default;
|
||||||
const RenderTargetLayout& getLayout() const { return layout; }
|
const RenderTargetLayout& getLayout() const { return layout; }
|
||||||
void updateColorAttachment(uint32 index, Gfx::PTextureCube attachment) { layout.colorAttachments[index].setTexture(attachment); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RenderTargetLayout layout;
|
RenderTargetLayout layout;
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render
|
|||||||
Array<VkImageView> attachments;
|
Array<VkImageView> attachments;
|
||||||
uint32 width = 0;
|
uint32 width = 0;
|
||||||
uint32 height = 0;
|
uint32 height = 0;
|
||||||
|
uint32 layers = 0;
|
||||||
for (auto inputAttachment : layout.inputAttachments) {
|
for (auto inputAttachment : layout.inputAttachments) {
|
||||||
PTextureBase vkInputAttachment = inputAttachment.getTexture().cast<TextureBase>();
|
PTextureBase vkInputAttachment = inputAttachment.getTexture().cast<TextureBase>();
|
||||||
attachments.add(vkInputAttachment->getView());
|
attachments.add(vkInputAttachment->getView());
|
||||||
description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView();
|
description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView();
|
||||||
width = std::max(width, vkInputAttachment->getWidth());
|
width = std::max(width, vkInputAttachment->getWidth());
|
||||||
height = std::max(height, vkInputAttachment->getHeight());
|
height = std::max(height, vkInputAttachment->getHeight());
|
||||||
|
layers = std::max(layers, vkInputAttachment->getNumLayers());
|
||||||
}
|
}
|
||||||
for (auto colorAttachment : layout.colorAttachments) {
|
for (auto colorAttachment : layout.colorAttachments) {
|
||||||
PTextureBase vkColorAttachment = colorAttachment.getTexture().cast<TextureBase>();
|
PTextureBase vkColorAttachment = colorAttachment.getTexture().cast<TextureBase>();
|
||||||
@@ -29,6 +31,7 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render
|
|||||||
description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView();
|
description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView();
|
||||||
width = std::max(width, vkColorAttachment->getWidth());
|
width = std::max(width, vkColorAttachment->getWidth());
|
||||||
height = std::max(height, vkColorAttachment->getHeight());
|
height = std::max(height, vkColorAttachment->getHeight());
|
||||||
|
layers = std::max(layers, vkColorAttachment->getNumLayers());
|
||||||
}
|
}
|
||||||
for (auto resolveAttachment : layout.resolveAttachments) {
|
for (auto resolveAttachment : layout.resolveAttachments) {
|
||||||
PTextureBase vkResolveAttachment = resolveAttachment.getTexture().cast<TextureBase>();
|
PTextureBase vkResolveAttachment = resolveAttachment.getTexture().cast<TextureBase>();
|
||||||
@@ -36,6 +39,7 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render
|
|||||||
description.resolveAttachments[description.numResolveAttachments++] = vkResolveAttachment->getView();
|
description.resolveAttachments[description.numResolveAttachments++] = vkResolveAttachment->getView();
|
||||||
width = std::max(width, vkResolveAttachment->getWidth());
|
width = std::max(width, vkResolveAttachment->getWidth());
|
||||||
height = std::max(height, vkResolveAttachment->getHeight());
|
height = std::max(height, vkResolveAttachment->getHeight());
|
||||||
|
layers = std::max(layers, vkResolveAttachment->getNumLayers());
|
||||||
}
|
}
|
||||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||||
PTextureBase vkDepthAttachment = layout.depthAttachment.getTexture().cast<TextureBase>();
|
PTextureBase vkDepthAttachment = layout.depthAttachment.getTexture().cast<TextureBase>();
|
||||||
@@ -43,6 +47,7 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render
|
|||||||
description.depthAttachment = vkDepthAttachment->getView();
|
description.depthAttachment = vkDepthAttachment->getView();
|
||||||
width = std::max(width, vkDepthAttachment->getWidth());
|
width = std::max(width, vkDepthAttachment->getWidth());
|
||||||
height = std::max(height, vkDepthAttachment->getHeight());
|
height = std::max(height, vkDepthAttachment->getHeight());
|
||||||
|
layers = std::max(layers, vkDepthAttachment->getNumLayers());
|
||||||
}
|
}
|
||||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||||
PTextureBase vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast<TextureBase>();
|
PTextureBase vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast<TextureBase>();
|
||||||
@@ -50,6 +55,7 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render
|
|||||||
description.depthResolveAttachment = vkDepthAttachment->getView();
|
description.depthResolveAttachment = vkDepthAttachment->getView();
|
||||||
width = std::max(width, vkDepthAttachment->getWidth());
|
width = std::max(width, vkDepthAttachment->getWidth());
|
||||||
height = std::max(height, vkDepthAttachment->getHeight());
|
height = std::max(height, vkDepthAttachment->getHeight());
|
||||||
|
layers = std::max(layers, vkDepthAttachment->getNumLayers());
|
||||||
}
|
}
|
||||||
VkFramebufferCreateInfo createInfo = {
|
VkFramebufferCreateInfo createInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Vulkan;
|
using namespace Seele::Vulkan;
|
||||||
|
|
||||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies,
|
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies, URect viewport,
|
||||||
URect viewport, std::string name, Array<uint32> viewMasks, Array<uint32> correlationMasks)
|
std::string name, Array<uint32> viewMasks, Array<uint32> correlationMasks)
|
||||||
: Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), graphics(graphics) {
|
: Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), graphics(graphics) {
|
||||||
renderArea.extent.width = viewport.size.x;
|
renderArea.extent.width = viewport.size.x;
|
||||||
renderArea.extent.height = viewport.size.y;
|
renderArea.extent.height = viewport.size.y;
|
||||||
@@ -166,6 +166,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
|
|||||||
.pNext = layout.depthResolveAttachment.getTexture() != nullptr ? &depthResolve : nullptr,
|
.pNext = layout.depthResolveAttachment.getTexture() != nullptr ? &depthResolve : nullptr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
.viewMask = viewMasks[0],
|
||||||
.inputAttachmentCount = (uint32)inputRefs.size(),
|
.inputAttachmentCount = (uint32)inputRefs.size(),
|
||||||
.pInputAttachments = inputRefs.data(),
|
.pInputAttachments = inputRefs.data(),
|
||||||
.colorAttachmentCount = (uint32)colorRefs.size(),
|
.colorAttachmentCount = (uint32)colorRefs.size(),
|
||||||
@@ -196,19 +197,9 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
|
|||||||
.pSubpasses = &subPassDesc,
|
.pSubpasses = &subPassDesc,
|
||||||
.dependencyCount = (uint32)dep.size(),
|
.dependencyCount = (uint32)dep.size(),
|
||||||
.pDependencies = dep.data(),
|
.pDependencies = dep.data(),
|
||||||
|
.correlatedViewMaskCount = (uint32)correlationMasks.size(),
|
||||||
|
.pCorrelatedViewMasks = correlationMasks.data(),
|
||||||
};
|
};
|
||||||
VkRenderPassMultiviewCreateInfo multiViewInfo;
|
|
||||||
if (!viewMasks.empty()) {
|
|
||||||
multiViewInfo = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
|
|
||||||
.pNext = nullptr,
|
|
||||||
.subpassCount = 1,
|
|
||||||
.pViewMasks = viewMasks.data(),
|
|
||||||
.correlationMaskCount = (uint32)correlationMasks.size(),
|
|
||||||
.pCorrelationMasks = correlationMasks.data(),
|
|
||||||
};
|
|
||||||
info.pNext = &multiViewInfo;
|
|
||||||
}
|
|
||||||
VK_CHECK(vkCreateRenderPass2(graphics->getDevice(), &info, nullptr, &renderPass));
|
VK_CHECK(vkCreateRenderPass2(graphics->getDevice(), &info, nullptr, &renderPass));
|
||||||
VkDebugUtilsObjectNameInfoEXT nameInfo = {
|
VkDebugUtilsObjectNameInfoEXT nameInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format) {
|
|||||||
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage)
|
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage)
|
||||||
: CommandBoundResource(graphics, createInfo.name), image(existingImage), imageView(VK_NULL_HANDLE), allocation(nullptr),
|
: CommandBoundResource(graphics, createInfo.name), image(existingImage), imageView(VK_NULL_HANDLE), allocation(nullptr),
|
||||||
owner(createInfo.sourceData.owner), width(createInfo.width), height(createInfo.height), depth(createInfo.depth),
|
owner(createInfo.sourceData.owner), width(createInfo.width), height(createInfo.height), depth(createInfo.depth),
|
||||||
arrayCount(createInfo.elements), layerCount(createInfo.layers), mipLevels(1), samples(createInfo.samples), format(createInfo.format),
|
layerCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format),
|
||||||
usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) {
|
usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) {
|
||||||
if (createInfo.useMip) {
|
if (createInfo.useMip) {
|
||||||
mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
|
mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
|
||||||
@@ -55,7 +55,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
|||||||
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
|
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
|
||||||
type = VK_IMAGE_TYPE_2D;
|
type = VK_IMAGE_TYPE_2D;
|
||||||
flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||||
layerCount = 6 * arrayCount;
|
layerCount = 6 * layerCount;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -76,7 +76,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
|||||||
.depth = depth,
|
.depth = depth,
|
||||||
},
|
},
|
||||||
.mipLevels = mipLevels,
|
.mipLevels = mipLevels,
|
||||||
.arrayLayers = arrayCount * layerCount,
|
.arrayLayers = layerCount,
|
||||||
.samples = (VkSampleCountFlagBits)samples,
|
.samples = (VkSampleCountFlagBits)samples,
|
||||||
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
||||||
.usage = usage,
|
.usage = usage,
|
||||||
@@ -129,7 +129,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
|||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
.mipLevel = 0,
|
.mipLevel = 0,
|
||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = arrayCount * layerCount,
|
.layerCount = layerCount,
|
||||||
},
|
},
|
||||||
.imageOffset =
|
.imageOffset =
|
||||||
{
|
{
|
||||||
@@ -163,7 +163,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
|
|||||||
{
|
{
|
||||||
.aspectMask = aspect,
|
.aspectMask = aspect,
|
||||||
.levelCount = mipLevels,
|
.levelCount = mipLevels,
|
||||||
.layerCount = layerCount * arrayCount,
|
.layerCount = layerCount,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ void TextureHandle::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag
|
|||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
.levelCount = mipLevels,
|
.levelCount = mipLevels,
|
||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = layerCount * arrayCount,
|
.layerCount = layerCount,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
PCommand command = graphics->getQueueCommands(owner)->getCommands();
|
PCommand command = graphics->getQueueCommands(owner)->getCommands();
|
||||||
@@ -223,7 +223,7 @@ void TextureHandle::transferOwnership(Gfx::QueueType newOwner) {
|
|||||||
.baseMipLevel = 0,
|
.baseMipLevel = 0,
|
||||||
.levelCount = mipLevels,
|
.levelCount = mipLevels,
|
||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = arrayCount,
|
.layerCount = layerCount,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
PCommandPool sourcePool = graphics->getQueueCommands(owner);
|
PCommandPool sourcePool = graphics->getQueueCommands(owner);
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ class TextureHandle : public CommandBoundResource {
|
|||||||
uint32 width;
|
uint32 width;
|
||||||
uint32 height;
|
uint32 height;
|
||||||
uint32 depth;
|
uint32 depth;
|
||||||
uint32 arrayCount;
|
|
||||||
uint32 layerCount;
|
uint32 layerCount;
|
||||||
uint32 mipLevels;
|
uint32 mipLevels;
|
||||||
uint32 samples;
|
uint32 samples;
|
||||||
@@ -48,6 +47,7 @@ class TextureBase {
|
|||||||
uint32 getWidth() const { return handle->width; }
|
uint32 getWidth() const { return handle->width; }
|
||||||
uint32 getHeight() const { return handle->height; }
|
uint32 getHeight() const { return handle->height; }
|
||||||
uint32 getDepth() const { return handle->depth; }
|
uint32 getDepth() const { return handle->depth; }
|
||||||
|
uint32 getNumLayers() const { return handle->layerCount; }
|
||||||
PTextureHandle getHandle() const { return handle; }
|
PTextureHandle getHandle() const { return handle; }
|
||||||
VkImage getImage() const { return handle->image; };
|
VkImage getImage() const { return handle->image; };
|
||||||
VkImageView getView() const { return handle->imageView; };
|
VkImageView getView() const { return handle->imageView; };
|
||||||
|
|||||||
@@ -276,7 +276,6 @@ void Window::createSwapChain() {
|
|||||||
.width = extent.width,
|
.width = extent.width,
|
||||||
.height = extent.height,
|
.height = extent.height,
|
||||||
.depth = 1,
|
.depth = 1,
|
||||||
.layers = 1,
|
|
||||||
.elements = 1,
|
.elements = 1,
|
||||||
.samples = 1,
|
.samples = 1,
|
||||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSFER_DST_BIT,
|
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||||
|
|||||||
@@ -9,7 +9,12 @@ Window::~Window() {}
|
|||||||
|
|
||||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
||||||
: sizeX(viewportInfo.dimensions.size.x), sizeY(viewportInfo.dimensions.size.y), offsetX(viewportInfo.dimensions.offset.x),
|
: sizeX(viewportInfo.dimensions.size.x), sizeY(viewportInfo.dimensions.size.y), offsetX(viewportInfo.dimensions.offset.x),
|
||||||
offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), owner(owner) {}
|
offsetY(viewportInfo.dimensions.offset.y), fieldOfView(viewportInfo.fieldOfView), owner(owner) {
|
||||||
|
if (owner != nullptr) {
|
||||||
|
sizeX = std::min(owner->getFramebufferWidth(), sizeX);
|
||||||
|
sizeY = std::min(owner->getFramebufferHeight(), sizeY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Viewport::~Viewport() {}
|
Viewport::~Viewport() {}
|
||||||
|
|
||||||
|
|||||||
@@ -158,8 +158,8 @@ void Material::load(ArchiveBuffer& buffer) {
|
|||||||
|
|
||||||
void Material::compile() {
|
void Material::compile() {
|
||||||
std::ofstream codeStream("./shaders/generated/" + materialName + ".slang");
|
std::ofstream codeStream("./shaders/generated/" + materialName + ".slang");
|
||||||
codeStream << "import BRDF;\n";
|
|
||||||
codeStream << "import MaterialParameter;\n";
|
codeStream << "import MaterialParameter;\n";
|
||||||
|
codeStream << "import LightEnv;\n";
|
||||||
codeStream << "import Material;\n";
|
codeStream << "import Material;\n";
|
||||||
codeStream << "struct Material{\n";
|
codeStream << "struct Material{\n";
|
||||||
codeStream << "\ttypedef " << brdf.profile << " BRDF;\n";
|
codeStream << "\ttypedef " << brdf.profile << " BRDF;\n";
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
#include "LightEnvironment.h"
|
#include "LightEnvironment.h"
|
||||||
|
#include "Asset/EnvironmentMapAsset.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
|
#include "Asset/AssetRegistry.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) : graphics(graphics) {
|
LightEnvironment::LightEnvironment(Gfx::PGraphics graphics)
|
||||||
|
: graphics(graphics), environment(AssetRegistry::findEnvironmentMap("", "newport_loft")) {
|
||||||
layout = graphics->createDescriptorLayout("pLightEnv");
|
layout = graphics->createDescriptorLayout("pLightEnv");
|
||||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.name = "directionalLights",
|
.name = "directionalLights",
|
||||||
@@ -21,6 +24,10 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) : graphics(graphics)
|
|||||||
.name = "numPointLights",
|
.name = "numPointLights",
|
||||||
.uniformLength = sizeof(uint32),
|
.uniformLength = sizeof(uint32),
|
||||||
});
|
});
|
||||||
|
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "irradianceMap",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
});
|
||||||
layout->create();
|
layout->create();
|
||||||
|
|
||||||
directionalLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
directionalLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
@@ -29,6 +36,13 @@ LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) : graphics(graphics)
|
|||||||
pointLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
pointLights = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.name = "PointLights",
|
.name = "PointLights",
|
||||||
});
|
});
|
||||||
|
environmentSampler = graphics->createSampler({
|
||||||
|
.magFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.minFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LightEnvironment::~LightEnvironment() {}
|
LightEnvironment::~LightEnvironment() {}
|
||||||
@@ -63,6 +77,7 @@ void LightEnvironment::commit() {
|
|||||||
set->updateBuffer("pointLights", 0, pointLights);
|
set->updateBuffer("pointLights", 0, pointLights);
|
||||||
set->updateConstants("numDirectionalLights", 0, &numDirectionalLights);
|
set->updateConstants("numDirectionalLights", 0, &numDirectionalLights);
|
||||||
set->updateBuffer("directionalLights", 0, directionalLights);
|
set->updateBuffer("directionalLights", 0, directionalLights);
|
||||||
|
set->updateTexture("irradianceMap", 0, environment->getIrradianceMap());
|
||||||
set->writeChanges();
|
set->writeChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
#include "Graphics/Buffer.h"
|
#include "Graphics/Buffer.h"
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
|
DECLARE_REF(EnvironmentMapAsset)
|
||||||
class LightEnvironment {
|
class LightEnvironment {
|
||||||
public:
|
public:
|
||||||
LightEnvironment(Gfx::PGraphics graphics);
|
LightEnvironment(Gfx::PGraphics graphics);
|
||||||
@@ -16,12 +16,15 @@ class LightEnvironment {
|
|||||||
void commit();
|
void commit();
|
||||||
const Gfx::PDescriptorLayout getDescriptorLayout() const;
|
const Gfx::PDescriptorLayout getDescriptorLayout() const;
|
||||||
Gfx::PDescriptorSet getDescriptorSet();
|
Gfx::PDescriptorSet getDescriptorSet();
|
||||||
|
PEnvironmentMapAsset getEnvironmentMap() { return environment; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gfx::OShaderBuffer directionalLights;
|
Gfx::OShaderBuffer directionalLights;
|
||||||
Gfx::OShaderBuffer pointLights;
|
Gfx::OShaderBuffer pointLights;
|
||||||
Array<Component::DirectionalLight> dirs;
|
Array<Component::DirectionalLight> dirs;
|
||||||
Array<Component::PointLight> points;
|
Array<Component::PointLight> points;
|
||||||
|
PEnvironmentMapAsset environment;
|
||||||
|
Gfx::OSampler environmentSampler;
|
||||||
Gfx::ODescriptorLayout layout;
|
Gfx::ODescriptorLayout layout;
|
||||||
Gfx::PDescriptorSet set;
|
Gfx::PDescriptorSet set;
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "Actor/PointLightActor.h"
|
#include "Actor/PointLightActor.h"
|
||||||
#include "Asset/AssetRegistry.h"
|
|
||||||
#include "Asset/MaterialAsset.h"
|
#include "Asset/MaterialAsset.h"
|
||||||
#include "Asset/TextureAsset.h"
|
#include "Asset/TextureAsset.h"
|
||||||
#include "Component/DirectionalLight.h"
|
#include "Component/DirectionalLight.h"
|
||||||
@@ -13,7 +12,8 @@
|
|||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
Scene::Scene(Gfx::PGraphics graphics) : graphics(graphics), lightEnv(new LightEnvironment(graphics)), physics(registry) {}
|
Scene::Scene(Gfx::PGraphics graphics)
|
||||||
|
: graphics(graphics), lightEnv(new LightEnvironment(graphics)), physics(registry) {}
|
||||||
|
|
||||||
Scene::~Scene() {}
|
Scene::~Scene() {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "MinimalEngine.h"
|
||||||
#include "Component/Skybox.h"
|
#include "Component/Skybox.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "LightEnvironment.h"
|
#include "LightEnvironment.h"
|
||||||
#include "MinimalEngine.h"
|
|
||||||
#include "Physics/PhysicsSystem.h"
|
#include "Physics/PhysicsSystem.h"
|
||||||
#include <entt/entt.hpp>
|
#include <entt/entt.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|||||||
Reference in New Issue
Block a user