More tangent changes
This commit is contained in:
@@ -36,4 +36,3 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
|||||||
//result = pow(result, float3(1.0/2.2));
|
//result = pow(result, float3(1.0/2.2));
|
||||||
return float4(result, brdf.getAlpha());
|
return float4(result, brdf.getAlpha());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ void meshMain(
|
|||||||
{
|
{
|
||||||
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
|
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
|
||||||
VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex);
|
VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex);
|
||||||
vertices[v] = attr.getParameter(inst.transformMatrix);
|
vertices[v] = attr.getParameter(inst.transformMatrix, inst.inverseTransformMatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ void meshMain(
|
|||||||
{
|
{
|
||||||
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
|
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
|
||||||
VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex);
|
VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex);
|
||||||
vertices[v] = attr.getParameter(inst.transformMatrix);
|
vertices[v] = attr.getParameter(inst.transformMatrix, inst.inverseTransformMatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+21
-21
@@ -2,7 +2,7 @@ import Common;
|
|||||||
|
|
||||||
interface IBRDF
|
interface IBRDF
|
||||||
{
|
{
|
||||||
float3 evaluate(float3 viewDir_TS, float3 lightDir_TS, float3 lightColor);
|
float3 evaluate(float3x3 tangentToWorld, float3 viewDir_WS, float3 lightDir_WS, float3 lightColor);
|
||||||
float3 evaluateAmbient();
|
float3 evaluateAmbient();
|
||||||
float getAlpha();
|
float getAlpha();
|
||||||
float3 getTangentNormal();
|
float3 getTangentNormal();
|
||||||
@@ -27,12 +27,12 @@ struct Phong : IBRDF
|
|||||||
shininess = 0;
|
shininess = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 evaluate(float3 viewDir_TS, float3 lightDir_TS, float3 lightColor)
|
float3 evaluate(float3x3 tangentToWorld, float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||||
{
|
{
|
||||||
float3 normal_TS = normal;
|
float3 normal_WS = normalize(mul(tangentToWorld, normal));
|
||||||
float3 nDotL = dot(normal_TS, lightDir_TS);
|
float3 nDotL = dot(normal_WS, lightDir_WS);
|
||||||
float3 r = 2 * (nDotL) * normal_TS - lightDir_TS;
|
float3 r = 2 * (nDotL) * normal_WS - lightDir_WS;
|
||||||
float rDotV = dot(r, viewDir_TS);
|
float rDotV = dot(r, viewDir_WS);
|
||||||
|
|
||||||
return lightColor * (baseColor * max(nDotL, 0.0));// + specular * pow(max(rDotV, 0.0), max(shininess, 1)));
|
return lightColor * (baseColor * max(nDotL, 0.0));// + specular * pow(max(rDotV, 0.0), max(shininess, 1)));
|
||||||
}
|
}
|
||||||
@@ -70,12 +70,12 @@ struct BlinnPhong : IBRDF
|
|||||||
ambient = float3(0, 0, 0);
|
ambient = float3(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 evaluate(float3 viewDir_TS, float3 lightDir_TS, float3 lightColor)
|
float3 evaluate(float3x3 tangentToWorld, float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||||
{
|
{
|
||||||
float3 normal_TS = normalize(normal);
|
float3 normal_WS = normalize(mul(tangentToWorld, normal));
|
||||||
float diffuse = max(dot(normal_TS, lightDir_TS), 0);
|
float diffuse = max(dot(normal_WS, lightDir_WS), 0);
|
||||||
float3 h = normalize(lightDir_TS + viewDir_TS);
|
float3 h = normalize(lightDir_WS + viewDir_WS);
|
||||||
float specular = pow(saturate(dot(normal_TS, h)), shininess);
|
float specular = pow(saturate(dot(normal_WS, h)), shininess);
|
||||||
|
|
||||||
return (baseColor * diffuse * lightColor) + (specularColor * specular);
|
return (baseColor * diffuse * lightColor) + (specularColor * specular);
|
||||||
}
|
}
|
||||||
@@ -107,10 +107,10 @@ struct CelShading : IBRDF
|
|||||||
normal = float3(0, 0, 1);
|
normal = float3(0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 evaluate(float3 viewDir_TS, float3 lightDir_TS, float3 lightColor)
|
float3 evaluate(float3x3 tangentToWorld, float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||||
{
|
{
|
||||||
float3 normal_TS = normalize(normal);
|
float3 normal_WS = normalize(mul(tangentToWorld, normal));
|
||||||
float nDotL = dot(normal_TS, lightDir_TS);
|
float nDotL = dot(normal_WS, lightDir_WS);
|
||||||
float diffuse = max(nDotL, 0);
|
float diffuse = max(nDotL, 0);
|
||||||
|
|
||||||
float3 darkenedBase = baseColor * 0.8;
|
float3 darkenedBase = baseColor * 0.8;
|
||||||
@@ -189,21 +189,21 @@ struct CookTorrance : IBRDF
|
|||||||
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 evaluate(float3 viewDir_TS, float3 lightDir_TS, float3 lightColor)
|
float3 evaluate(float3x3 tangentToWorld, float3 viewDir_WS, float3 lightDir_WS, float3 lightColor)
|
||||||
{
|
{
|
||||||
float3 n = normal;//normalize(mul(tbn, normal));
|
float3 n = normalize(mul(tangentToWorld, normal));
|
||||||
float3 h = normalize(lightDir_TS + viewDir_TS);
|
float3 h = normalize(lightDir_WS + viewDir_WS);
|
||||||
|
|
||||||
float3 F0 = float3(0.04);
|
float3 F0 = float3(0.04);
|
||||||
F0 = lerp(F0, baseColor, metallic);
|
F0 = lerp(F0, baseColor, metallic);
|
||||||
|
|
||||||
float3 F = FresnelSchlick(max(dot(h, viewDir_TS), 0.0), F0);
|
float3 F = FresnelSchlick(max(dot(h, viewDir_WS), 0.0), F0);
|
||||||
|
|
||||||
float NDF = TrowbridgeReitzGGX(n, h);
|
float NDF = TrowbridgeReitzGGX(n, h);
|
||||||
float G = Smith(n, viewDir_TS, lightDir_TS);
|
float G = Smith(n, viewDir_WS, lightDir_WS);
|
||||||
|
|
||||||
float3 num = NDF * G * F;
|
float3 num = NDF * G * F;
|
||||||
float denom = 4.0 * max(dot(n, viewDir_TS), 0.0) * max(dot(n, lightDir_TS), 0.0) + 0.000001;
|
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 specular = num / denom;
|
||||||
|
|
||||||
float3 k_s = F;
|
float3 k_s = F;
|
||||||
@@ -211,7 +211,7 @@ struct CookTorrance : IBRDF
|
|||||||
|
|
||||||
k_d *= 1.0 - metallic;
|
k_d *= 1.0 - metallic;
|
||||||
|
|
||||||
float nDotL = max(dot(n, lightDir_TS), 0.0);
|
float nDotL = max(dot(n, lightDir_WS), 0.0);
|
||||||
|
|
||||||
float3 result = (k_d * baseColor / PI + specular) * nDotL * lightColor;
|
float3 result = (k_d * baseColor / PI + specular) * nDotL * lightColor;
|
||||||
return result * ambientOcclusion;
|
return result * ambientOcclusion;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ struct DirectionalLight : ILightEnv
|
|||||||
|
|
||||||
float3 illuminate<B:IBRDF>(LightingParameter params, B brdf)
|
float3 illuminate<B:IBRDF>(LightingParameter params, B brdf)
|
||||||
{
|
{
|
||||||
float3 dir_TS = mul(params.worldToTangent, -normalize(direction.xyz));
|
float3 dir_WS = normalize(direction.xyz);
|
||||||
return brdf.evaluate(params.viewDir_TS, dir_TS, color.xyz);
|
return brdf.evaluate(params.tangentToWorld, params.viewDir_WS, dir_WS, color.xyz);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -26,11 +26,10 @@ struct PointLight : ILightEnv
|
|||||||
|
|
||||||
float3 illuminate<B:IBRDF>(LightingParameter params, B brdf)
|
float3 illuminate<B:IBRDF>(LightingParameter params, B brdf)
|
||||||
{
|
{
|
||||||
float3 pos_TS = mul(params.worldToTangent, position_WS.xyz);
|
float3 lightDir_WS = position_WS.xyz - params.position_WS;
|
||||||
float3 lightDir_TS = pos_TS.xyz - params.position_TS;
|
float d = length(lightDir_WS);
|
||||||
float d = length(lightDir_TS);
|
|
||||||
float illuminance = max(1 - d / colorRange.w, 0);
|
float illuminance = max(1 - d / colorRange.w, 0);
|
||||||
return illuminance * brdf.evaluate(params.viewDir_TS, normalize(lightDir_TS), colorRange.xyz);
|
return illuminance * brdf.evaluate(params.tangentToWorld, params.viewDir_WS, normalize(lightDir_WS), colorRange.xyz);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insidePlane(Plane plane, float3 position)
|
bool insidePlane(Plane plane, float3 position)
|
||||||
|
|||||||
@@ -9,18 +9,50 @@ struct MaterialParameter
|
|||||||
|
|
||||||
struct LightingParameter
|
struct LightingParameter
|
||||||
{
|
{
|
||||||
float3x3 worldToTangent;
|
float3x3 tangentToWorld;
|
||||||
float3 viewDir_TS;
|
float3 viewDir_WS;
|
||||||
float3 position_TS;
|
float3 position_WS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a TBN matrix from a unpacked qtangent for example for after vertex interpolation in the fragment shader
|
|
||||||
float3x3 constructTBNFromQTangent(float4 q){
|
float3x3 qTangentToMatrix(float4 q){
|
||||||
q = normalize(q); // Ensure that the quaternion is normalized in case it is not, for example after interpolation and so on
|
q = normalize(q);
|
||||||
float3 t2 = q.xyz * 2.0, tx = q.xxx * t2.xyz, ty = q.yyy * t2.xyz, tz = q.www * t2.xyz;
|
float qx2 = q.x + q.x;
|
||||||
float3 tangent = float3(1.0 - (ty.y + (q.z * t2.z)), tx.y + tz.z, tx.z - tz.y);
|
float qy2 = q.y + q.y;
|
||||||
float3 normal = float3(tx.z + tz.y, ty.z - tz.x, 1.0 - (tx.x + ty.y));
|
float qz2 = q.z + q.z;
|
||||||
return float3x3(tangent, cross(tangent, normal) * ((q.w < 0.0) ? -1.0 : 1.0), normal);
|
float qxqx2 = q.x * qx2;
|
||||||
|
float qxqy2 = q.x * qy2;
|
||||||
|
float qxqz2 = q.x * qz2;
|
||||||
|
float qxqw2 = q.w * qx2;
|
||||||
|
float qyqy2 = q.y * qy2;
|
||||||
|
float qyqz2 = q.y * qz2;
|
||||||
|
float qyqw2 = q.w * qy2;
|
||||||
|
float qzqz2 = q.z * qz2;
|
||||||
|
float qzqw2 = q.w * qz2;
|
||||||
|
float3x3 m = float3x3(1.0 - (qyqy2 + qzqz2), qxqy2 + qzqw2, qxqz2 - qyqw2,
|
||||||
|
qxqy2 - qzqw2, 1.0 - (qxqx2 + qzqz2), qyqz2 + qxqw2,
|
||||||
|
qxqz2 + qyqw2, qyqz2 - qxqw2, 1.0 - (qxqx2 + qyqy2));
|
||||||
|
m[2] = normalize(cross(m[0], m[1])) * ((q.w < 0.0) ? -1.0 : 1.0);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 qTangentSlerp(float4 q0, float4 q1, float t){
|
||||||
|
float co = dot(q0, q1), so, s0, s1, s2 = 1.0, Omega;
|
||||||
|
if(co < 0.0){
|
||||||
|
co = -co;
|
||||||
|
s2 = -s2;
|
||||||
|
}
|
||||||
|
if((1.0 - co) > 1e-8){
|
||||||
|
Omega = acos(co);
|
||||||
|
so = sin(Omega);
|
||||||
|
s0 = sin((1.0 - t) * Omega) / so;
|
||||||
|
s1 = sin(t * Omega) / so;
|
||||||
|
} else {
|
||||||
|
s0 = 1.0 - t;
|
||||||
|
s1 = t;
|
||||||
|
}
|
||||||
|
float4 r = ((q0 * s0) + (q1 * (s1 * s2)));
|
||||||
|
return r * ((((q0.w < 0.0) || (q1.w < 0.0)) != (r.w < 0.0)) ? -1.0 : 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// data passed to fragment shader
|
// data passed to fragment shader
|
||||||
@@ -28,10 +60,10 @@ struct FragmentParameter
|
|||||||
{
|
{
|
||||||
float4 position_CS : SV_Position;
|
float4 position_CS : SV_Position;
|
||||||
#ifndef POS_ONLY
|
#ifndef POS_ONLY
|
||||||
float4 qTangent : QTANGENT;
|
float3 normal_WS : NORMALWS;
|
||||||
|
float3 tangent_WS : TANGENTWS;
|
||||||
|
float3 biTangent_WS : BITANGENTWS;
|
||||||
float3 position_WS : POSITIONWS;
|
float3 position_WS : POSITIONWS;
|
||||||
float3 position_TS : POSITIONTS;
|
|
||||||
float3 cameraPos_TS : CAMPOSTS;
|
|
||||||
float3 vertexColor : COLOR;
|
float3 vertexColor : COLOR;
|
||||||
float4 texCoords0 : TEXCOORDS0;
|
float4 texCoords0 : TEXCOORDS0;
|
||||||
float4 texCoords1 : TEXCOORDS1;
|
float4 texCoords1 : TEXCOORDS1;
|
||||||
@@ -55,17 +87,16 @@ struct FragmentParameter
|
|||||||
|
|
||||||
LightingParameter getLightingParameter()
|
LightingParameter getLightingParameter()
|
||||||
{
|
{
|
||||||
float3x3 worldToTangent = transpose(constructTBNFromQTangent(qTangent));
|
|
||||||
LightingParameter result;
|
LightingParameter result;
|
||||||
result.worldToTangent = worldToTangent;
|
result.tangentToWorld = getTangentToWorld();
|
||||||
result.viewDir_TS = cameraPos_TS - position_TS;
|
result.viewDir_WS = normalize(pViewParams.cameraPosition_WS.xyz - position_WS);
|
||||||
result.position_TS = position_TS;
|
result.position_WS = position_WS;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
float3x3 getTangentToWorld()
|
float3x3 getTangentToWorld()
|
||||||
{
|
{
|
||||||
return constructTBNFromQTangent(qTangent);
|
return float3x3(normalize(tangent_WS), normalize(biTangent_WS), normalize(normal_WS));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
static FragmentParameter interpolate(FragmentParameter f0, FragmentParameter f1, FragmentParameter f2, float3 barycentricCoords)
|
static FragmentParameter interpolate(FragmentParameter f0, FragmentParameter f1, FragmentParameter f2, float3 barycentricCoords)
|
||||||
@@ -73,14 +104,15 @@ struct FragmentParameter
|
|||||||
FragmentParameter result;
|
FragmentParameter result;
|
||||||
result.position_CS = f0.position_CS * barycentricCoords.x + f1.position_CS * barycentricCoords.y + f2.position_CS * barycentricCoords.z;
|
result.position_CS = f0.position_CS * barycentricCoords.x + f1.position_CS * barycentricCoords.y + f2.position_CS * barycentricCoords.z;
|
||||||
#ifndef POS_ONLY
|
#ifndef POS_ONLY
|
||||||
result.qTangent = f0.qTangent * barycentricCoords.x + f1.qTangent * barycentricCoords.y + f2.qTangent * barycentricCoords.z;
|
result.normal_WS = f0.normal_WS * barycentricCoords.x + f1.normal_WS * barycentricCoords.y + f2.normal_WS * barycentricCoords.z;
|
||||||
result.position_WS = f0.position_WS * barycentricCoords.x + f1.position_WS * barycentricCoords.y + f2.position_WS * barycentricCoords.z;
|
result.tangent_WS = f0.tangent_WS * barycentricCoords.x + f1.tangent_WS * barycentricCoords.y + f2.tangent_WS * barycentricCoords.z;
|
||||||
|
result.biTangent_WS = f0.biTangent_WS * barycentricCoords.x + f1.biTangent_WS * barycentricCoords.y + f2.biTangent_WS * barycentricCoords.z;
|
||||||
|
result.position_WS = f0.position_WS * barycentricCoords.x + f1.position_WS * barycentricCoords.y + f2.position_WS * barycentricCoords.z;
|
||||||
result.vertexColor = f0.vertexColor * barycentricCoords.x + f1.vertexColor * barycentricCoords.y + f2.vertexColor * barycentricCoords.z;
|
result.vertexColor = f0.vertexColor * barycentricCoords.x + f1.vertexColor * barycentricCoords.y + f2.vertexColor * barycentricCoords.z;
|
||||||
result.texCoords0 = f0.texCoords0 * barycentricCoords.x + f1.texCoords0 * barycentricCoords.y + f2.texCoords0 * barycentricCoords.z;
|
result.texCoords0 = f0.texCoords0 * barycentricCoords.x + f1.texCoords0 * barycentricCoords.y + f2.texCoords0 * barycentricCoords.z;
|
||||||
result.texCoords1 = f0.texCoords1 * barycentricCoords.x + f1.texCoords1 * barycentricCoords.y + f2.texCoords1 * barycentricCoords.z;
|
result.texCoords1 = f0.texCoords1 * barycentricCoords.x + f1.texCoords1 * barycentricCoords.y + f2.texCoords1 * barycentricCoords.z;
|
||||||
result.texCoords2 = f0.texCoords2 * barycentricCoords.x + f1.texCoords2 * barycentricCoords.y + f2.texCoords2 * barycentricCoords.z;
|
result.texCoords2 = f0.texCoords2 * barycentricCoords.x + f1.texCoords2 * barycentricCoords.y + f2.texCoords2 * barycentricCoords.z;
|
||||||
result.texCoords3 = f0.texCoords3 * barycentricCoords.x + f1.texCoords3 * barycentricCoords.y + f2.texCoords3 * barycentricCoords.z;
|
result.texCoords3 = f0.texCoords3 * barycentricCoords.x + f1.texCoords3 * barycentricCoords.y + f2.texCoords3 * barycentricCoords.z;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -91,11 +123,13 @@ struct VertexAttributes
|
|||||||
{
|
{
|
||||||
float3 position_MS;
|
float3 position_MS;
|
||||||
#ifndef POS_ONLY
|
#ifndef POS_ONLY
|
||||||
float4 qTangent;
|
float3 normal_MS;
|
||||||
|
float3 tangent_MS;
|
||||||
|
float3 biTangent_MS;
|
||||||
float3 vertexColor;
|
float3 vertexColor;
|
||||||
float2 texCoords[MAX_TEXCOORDS];
|
float2 texCoords[MAX_TEXCOORDS];
|
||||||
#endif
|
#endif
|
||||||
FragmentParameter getParameter(float4x4 transformMatrix)
|
FragmentParameter getParameter(float4x4 transformMatrix, float4x4 inverseTransformMatrix)
|
||||||
{
|
{
|
||||||
float4 modelPos = float4(position_MS, 1);
|
float4 modelPos = float4(position_MS, 1);
|
||||||
float4 worldPos = mul(transformMatrix, modelPos);
|
float4 worldPos = mul(transformMatrix, modelPos);
|
||||||
@@ -104,12 +138,12 @@ struct VertexAttributes
|
|||||||
FragmentParameter result;
|
FragmentParameter result;
|
||||||
result.position_CS = clipPos;
|
result.position_CS = clipPos;
|
||||||
#ifndef POS_ONLY
|
#ifndef POS_ONLY
|
||||||
result.qTangent = qTangent;
|
float3x3 normalMatrix = transpose(float3x3(inverseTransformMatrix));
|
||||||
float3x3 tbn = constructTBNFromQTangent(qTangent);
|
result.tangent_WS = mul(normalMatrix, tangent_MS);
|
||||||
result.position_TS = mul(tbn, worldPos.xyz);
|
result.biTangent_WS = mul(normalMatrix, biTangent_MS);
|
||||||
|
result.normal_WS = mul(normalMatrix, normal_MS);
|
||||||
result.vertexColor = vertexColor;
|
result.vertexColor = vertexColor;
|
||||||
result.position_WS = worldPos.xyz;
|
result.position_WS = worldPos.xyz;
|
||||||
result.cameraPos_TS = mul(tbn, pViewParams.cameraPosition_WS.xyz);
|
|
||||||
result.texCoords0 = float4(texCoords[0], texCoords[1]);
|
result.texCoords0 = float4(texCoords[0], texCoords[1]);
|
||||||
result.texCoords1 = float4(texCoords[2], texCoords[3]);
|
result.texCoords1 = float4(texCoords[2], texCoords[3]);
|
||||||
result.texCoords2 = float4(texCoords[4], texCoords[5]);
|
result.texCoords2 = float4(texCoords[4], texCoords[5]);
|
||||||
|
|||||||
@@ -9,29 +9,14 @@ struct StaticMeshVertexData
|
|||||||
return value / 65535.0f;
|
return value / 65535.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float3x3 decodeQTangentUI32(uint v){
|
|
||||||
float4 q = float4(((float3(int3(uint3((uint3(v) >> uint3(0u, 10u, 20u)) & uint2(0x3ffu, 0x1ffu).xxy)) - int2(512, 256).xxy)) / float2(511.0, 255.0).xxy) * 0.7071067811865475, 0.0);
|
|
||||||
q.w = sqrt(1.0 - clamp(dot(q.xyz, q.xyz), 0.0, 1.0));
|
|
||||||
q = normalize(float4[4](q.wxyz, q.xwyz, q.xywz, q.xyzw)[uint((v >> 30u) & 0x3u)]);
|
|
||||||
float3 t2 = q.xyz * 2.0, tx = q.xxx * t2.xyz, ty = q.yyy * t2.xyz, tz = q.www * t2.xyz;
|
|
||||||
float3 tangent = float3(1.0 - (ty.y + (q.z * t2.z)), tx.y + tz.z, tx.z - tz.y);
|
|
||||||
float3 normal = float3(tx.z + tz.y, ty.z - tz.x, 1.0 - (tx.x + ty.y));
|
|
||||||
return float3x3(tangent, cross(tangent, normal) * (((v & (1u << 29u)) != 0u) ? -1.0 : 1.0), normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decodes the UI32 encoded qtangent into a unpacked qtangent for further processing like vertex interpolation and so on
|
|
||||||
float4 decodeQTangentUI32Raw(uint v){
|
|
||||||
float4 q = float4(((float3(int3(uint3((uint3(v) >> uint3(0u, 10u, 20u)) & uint2(0x3ffu, 0x1ffu).xxy)) - int2(512, 256).xxy)) / float2(511.0, 255.0).xxy) * 0.7071067811865475, 0.0);
|
|
||||||
q.w = sqrt(1.0 - clamp(dot(q.xyz, q.xyz), 0.0, 1.0));
|
|
||||||
return normalize(float4[4](q.wxyz, q.xwyz, q.xywz, q.xyzw)[uint((v >> 30u) & 0x3u)]) * (((v & (1u << 29u)) != 0u) ? -1.0 : 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
VertexAttributes getAttributes(uint index)
|
VertexAttributes getAttributes(uint index)
|
||||||
{
|
{
|
||||||
VertexAttributes attributes;
|
VertexAttributes attributes;
|
||||||
attributes.position_MS = float3(positions[index * 3 + 0], positions[index * 3 + 1], positions[index * 3 + 2]);
|
attributes.position_MS = float3(positions[index * 3 + 0], positions[index * 3 + 1], positions[index * 3 + 2]);
|
||||||
#ifndef POS_ONLY
|
#ifndef POS_ONLY
|
||||||
attributes.qTangent = decodeQTangentUI32Raw(qtangents[index]);
|
attributes.normal_MS = float3(normals[index * 3 + 0], normals[index * 3 + 1], normals[index * 3 + 2]);
|
||||||
|
attributes.tangent_MS = float3(tangents[index * 3 + 0], tangents[index * 3 + 1], tangents[index * 3 + 2]);
|
||||||
|
attributes.biTangent_MS = float3(biTangents[index * 3 + 0], biTangents[index * 3 + 1], biTangents[index * 3 + 2]);
|
||||||
for(uint i = 0; i < MAX_TEXCOORDS; ++i)
|
for(uint i = 0; i < MAX_TEXCOORDS; ++i)
|
||||||
{
|
{
|
||||||
attributes.texCoords[i] = float2(uint16ToFloat(texCoords[i][index * 2 + 0]), uint16ToFloat(texCoords[i][index * 2 + 1]));
|
attributes.texCoords[i] = float2(uint16ToFloat(texCoords[i][index * 2 + 0]), uint16ToFloat(texCoords[i][index * 2 + 1]));
|
||||||
@@ -41,7 +26,9 @@ struct StaticMeshVertexData
|
|||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
StructuredBuffer<float> positions;
|
StructuredBuffer<float> positions;
|
||||||
StructuredBuffer<uint> qtangents;
|
StructuredBuffer<float> normals;
|
||||||
|
StructuredBuffer<float> tangents;
|
||||||
|
StructuredBuffer<float> biTangents;
|
||||||
StructuredBuffer<uint16_t> color;
|
StructuredBuffer<uint16_t> color;
|
||||||
StructuredBuffer<uint16_t> texCoords[MAX_TEXCOORDS];
|
StructuredBuffer<uint16_t> texCoords[MAX_TEXCOORDS];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ void closestHit(inout RayPayload hitValue, in BuiltInTriangleIntersectionAttribu
|
|||||||
VertexAttributes attr1 = pVertexData.getAttributes(vertexIndex1);
|
VertexAttributes attr1 = pVertexData.getAttributes(vertexIndex1);
|
||||||
VertexAttributes attr2 = pVertexData.getAttributes(vertexIndex2);
|
VertexAttributes attr2 = pVertexData.getAttributes(vertexIndex2);
|
||||||
|
|
||||||
FragmentParameter f0 = attr0.getParameter(inst.transformMatrix);
|
FragmentParameter f0 = attr0.getParameter(inst.transformMatrix, inst.inverseTransformMatrix);
|
||||||
FragmentParameter f1 = attr1.getParameter(inst.transformMatrix);
|
FragmentParameter f1 = attr1.getParameter(inst.transformMatrix, inst.inverseTransformMatrix);
|
||||||
FragmentParameter f2 = attr2.getParameter(inst.transformMatrix);
|
FragmentParameter f2 = attr2.getParameter(inst.transformMatrix, inst.inverseTransformMatrix);
|
||||||
|
|
||||||
FragmentParameter params = FragmentParameter.interpolate(f0, f1, f2, barycentricCoords);
|
FragmentParameter params = FragmentParameter.interpolate(f0, f1, f2, barycentricCoords);
|
||||||
|
|
||||||
@@ -43,6 +43,6 @@ void closestHit(inout RayPayload hitValue, in BuiltInTriangleIntersectionAttribu
|
|||||||
hitValue.material.color = float4(brdf.baseColor, 1);
|
hitValue.material.color = float4(brdf.baseColor, 1);
|
||||||
hitValue.material.emissive = float3(0, 0, 0);
|
hitValue.material.emissive = float3(0, 0, 0);
|
||||||
hitValue.shading.position = WorldRayOrigin() + RayTCurrent() * WorldRayDirection();
|
hitValue.shading.position = WorldRayOrigin() + RayTCurrent() * WorldRayDirection();
|
||||||
hitValue.shading.normal = cross(f2.position_WS - f0.position_WS, f1.position_WS - f0.position_WS);
|
hitValue.shading.normal = mul(params.getTangentToWorld(), brdf.normal);
|
||||||
hitValue.shading.normalLight = dot(hitValue.shading.normal, WorldRayDirection()) < 0 ? hitValue.shading.normal : -hitValue.shading.normal;
|
hitValue.shading.normalLight = dot(hitValue.shading.normal, WorldRayDirection()) < 0 ? hitValue.shading.normal : -hitValue.shading.normal;
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ struct Ray
|
|||||||
|
|
||||||
const static float S_O = 6.9;
|
const static float S_O = 6.9;
|
||||||
const static float f = 0.035;
|
const static float f = 0.035;
|
||||||
const static float A = 0.4;
|
const static float A = 0.04;
|
||||||
const static float ka = 0;
|
const static float ka = 0;
|
||||||
const static float ks = 0;
|
const static float ks = 0;
|
||||||
const static float3 fogEmm = float3(0, 0.01, 0.01);
|
const static float3 fogEmm = float3(0, 0.01, 0.01);
|
||||||
|
|||||||
@@ -462,40 +462,44 @@ void MeshLoader::findMeshRoots(aiNode* node, List<aiNode*>& meshNodes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 MeshLoader::encodeQTangent(Matrix3 m) {
|
Vector4 MeshLoader::encodeQTangent(Matrix3 m) {
|
||||||
float r = (glm::determinant(m) ? -1.0 : 1.0);
|
float f = 1.0;
|
||||||
m[2] *= r;
|
if (((((((m[0][0] * m[1][1] * m[2][2]) + (m[0][1] * m[1][2] * m[2][0])) + (m[0][2] * m[1][0] * m[2][1])) -
|
||||||
|
(m[0][2] * m[1][1] * m[2][0])) -
|
||||||
|
(m[0][1] * m[1][0] * m[2][2])) -
|
||||||
|
(m[0][0] * m[1][2] * m[2][1])) < 0.0) {
|
||||||
|
f = -1.0;
|
||||||
|
m[2] = -m[2];
|
||||||
|
}
|
||||||
float t = m[0][0] + (m[1][1] + m[2][2]);
|
float t = m[0][0] + (m[1][1] + m[2][2]);
|
||||||
Vector4 q;
|
Vector4 r;
|
||||||
if (t > 2.9999999) {
|
if (t > 2.9999999) {
|
||||||
q = Vector4(0.0, 0.0, 0.0, 1.0);
|
r = Vector4(0.0, 0.0, 0.0, 1.0);
|
||||||
} else if (t > 0.0000001) {
|
} else if (t > 0.0000001) {
|
||||||
float s = sqrt(1.0 + t) * 2.0;
|
float s = sqrt(1.0 + t) * 2.0;
|
||||||
q = Vector4(Vector(m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0]) / s, s * 0.25);
|
r = Vector4(Vector(m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0]) / s, s * 0.25);
|
||||||
} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {
|
} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {
|
||||||
float s = sqrt(1.0 + (m[0][0] - (m[1][1] + m[2][2]))) * 2.0;
|
float s = sqrt(1.0 + (m[0][0] - (m[1][1] + m[2][2]))) * 2.0;
|
||||||
q = Vector4(s * 0.25, Vector(m[1][0] + m[0][1], m[2][0] + m[0][2], m[1][2] - m[2][1]) / s);
|
r = Vector4(s * 0.25, Vector(m[1][0] - m[0][1], m[2][0] - m[0][2], m[0][2] - m[2][1]) / s);
|
||||||
} else if (m[1][1] > m[2][2]) {
|
} else if (m[1][1] > m[2][2]) {
|
||||||
float s = sqrt(1.0 + (m[1][1] - (m[0][0] + m[2][2]))) * 2.0;
|
float s = sqrt(1.0 + (m[1][1] - (m[0][0] + m[2][2]))) * 2.0;
|
||||||
q = Vector4(Vector(m[1][0] + m[0][1], m[2][1] + m[1][2], m[2][0] - m[0][2]) / s, s * 0.25);
|
r = Vector4(Vector(m[1][0] + m[0][1], m[2][1] + m[1][2], m[2][0] - m[0][2]) / s, s * 0.25);
|
||||||
q = Vector4(q.x, q.w, q.y, q.z);
|
r = Vector4(r.x, r.w, r.y, r.z);
|
||||||
} else {
|
} else {
|
||||||
float s = sqrt(1.0 + (m[2][2] - (m[0][0] + m[1][1]))) * 2.0;
|
float s = sqrt(1.0 + (m[2][2] - (m[0][0] + m[1][1]))) * 2.0;
|
||||||
q = Vector4(Vector(m[2][0] + m[0][2], m[2][1] + m[1][2], m[0][1] - m[1][0]) / s, s * 0.25);
|
r = Vector4(Vector(m[2][0] + m[0][2], m[2][1] + m[1][2], m[0][1] - m[1][0]) / s, s * 0.25);
|
||||||
q = Vector4(q.x, q.y, q.w, q.z);
|
r = Vector4(r.x, r.y, r.w, r.z);
|
||||||
}
|
}
|
||||||
Vector4 qAbs = abs(q = glm::normalize(q));
|
r = normalize(r);
|
||||||
int maxComponentIndex = (qAbs.x > qAbs.y) ? ((qAbs.x > qAbs.z) ? ((qAbs.x > qAbs.w) ? 0 : 3) : ((qAbs.z > qAbs.w) ? 2 : 3))
|
const float threshold = 1.0 / 32767.0;
|
||||||
: ((qAbs.y > qAbs.z) ? ((qAbs.y > qAbs.w) ? 1 : 3) : ((qAbs.z > qAbs.w) ? 2 : 3));
|
if (r.w <= threshold) {
|
||||||
Vector components[4] = {Vector(q.y, q.z, q.w), Vector(q.x, q.z, q.w), Vector(q.x, q.y, q.w), Vector(q.x, q.y, q.z)};
|
r = Vector4(Vector(r) * (float)sqrt(1.0 - (threshold * threshold)), (r.w > 0.0) ? threshold : -threshold);
|
||||||
|
}
|
||||||
q = Vector4(components[maxComponentIndex] * float(((q[maxComponentIndex] < 0.0) ? -1.0 : 1.0) * 1.4142135623730951), q.w);
|
if (((f < 0.0) && (r.w >= 0.0)) || ((f >= 0.0) && (r.w < 0.0))) {
|
||||||
return ((uint32(round(glm::clamp(q.x * 511.0, -511.0, 511.0) + 512.0)) & 0x3ffu) << 0u) |
|
r = -r;
|
||||||
((uint32(round(glm::clamp(q.y * 511.0, -511.0, 511.0) + 512.0)) & 0x3ffu) << 10u) |
|
}
|
||||||
((uint32(round(glm::clamp(q.z * 255.0, -255.0, 255.0) + 256.0)) & 0x1ffu) << 20u) |
|
return r;
|
||||||
((uint32(((dot(cross(m[0], m[2]), m[1]) * r) < 0.0) ? 1u : 0u) & 0x1u) << 29u) | ((uint32(maxComponentIndex) & 0x3u) << 30u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialInstanceAsset>& materials, Array<OMesh>& globalMeshes,
|
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialInstanceAsset>& materials, Array<OMesh>& globalMeshes,
|
||||||
Component::Collider& collider) {
|
Component::Collider& collider) {
|
||||||
List<std::function<void()>> work;
|
List<std::function<void()>> work;
|
||||||
@@ -512,13 +516,15 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
|
|||||||
collider.boundingbox.adjust(Vector(mesh->mAABB.mMax.x, mesh->mAABB.mMax.y, mesh->mAABB.mMax.z));
|
collider.boundingbox.adjust(Vector(mesh->mAABB.mMax.x, mesh->mAABB.mMax.y, mesh->mAABB.mMax.z));
|
||||||
work.add([=, this, &globalMeshes]() {
|
work.add([=, this, &globalMeshes]() {
|
||||||
// assume static mesh for now
|
// assume static mesh for now
|
||||||
Array<Vector> positions(mesh->mNumVertices);
|
Array<StaticMeshVertexData::PositionType> positions(mesh->mNumVertices);
|
||||||
StaticArray<Array<U16Vector2>, MAX_TEXCOORDS> texCoords;
|
StaticArray<Array<StaticMeshVertexData::TexCoordType>, MAX_TEXCOORDS> texCoords;
|
||||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||||
texCoords[i].resize(mesh->mNumVertices);
|
texCoords[i].resize(mesh->mNumVertices);
|
||||||
}
|
}
|
||||||
Array<uint32> normals(mesh->mNumVertices);
|
Array<StaticMeshVertexData::NormalType> normals(mesh->mNumVertices);
|
||||||
Array<U16Vector> colors(mesh->mNumVertices);
|
Array<StaticMeshVertexData::TangentType> tangents(mesh->mNumVertices);
|
||||||
|
Array<StaticMeshVertexData::BiTangentType> biTangents(mesh->mNumVertices);
|
||||||
|
Array<StaticMeshVertexData::ColorType> colors(mesh->mNumVertices);
|
||||||
|
|
||||||
for (int32 i = 0; i < mesh->mNumVertices; ++i) {
|
for (int32 i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
positions[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
|
positions[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
|
||||||
@@ -536,14 +542,14 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
|
|||||||
tangent = Vector(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z);
|
tangent = Vector(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z);
|
||||||
biTangent = Vector(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z);
|
biTangent = Vector(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z);
|
||||||
}
|
}
|
||||||
Matrix3 tbn = {normal, biTangent, tangent};
|
normals[i] = normal;
|
||||||
|
tangents[i] = tangent;
|
||||||
normals[i] = encodeQTangent(tbn);
|
biTangents[i] = biTangent;
|
||||||
|
|
||||||
if (mesh->HasVertexColors(0)) {
|
if (mesh->HasVertexColors(0)) {
|
||||||
colors[i] = U16Vector(mesh->mColors[0][i].r * 65535, mesh->mColors[0][i].g * 65535, mesh->mColors[0][i].b * 65535);
|
colors[i] = StaticMeshVertexData::ColorType(mesh->mColors[0][i].r * 65535, mesh->mColors[0][i].g * 65535, mesh->mColors[0][i].b * 65535);
|
||||||
} else {
|
} else {
|
||||||
colors[i] = U16Vector(1, 1, 1);
|
colors[i] = StaticMeshVertexData::ColorType(1, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vertexData->loadPositions(offset, positions);
|
vertexData->loadPositions(offset, positions);
|
||||||
@@ -552,6 +558,8 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
|
|||||||
vertexData->loadTexCoords(offset, i, texCoords[i]);
|
vertexData->loadTexCoords(offset, i, texCoords[i]);
|
||||||
}
|
}
|
||||||
vertexData->loadNormals(offset, normals);
|
vertexData->loadNormals(offset, normals);
|
||||||
|
vertexData->loadTangents(offset, tangents);
|
||||||
|
vertexData->loadBitangents(offset, biTangents);
|
||||||
vertexData->loadColors(offset, colors);
|
vertexData->loadColors(offset, colors);
|
||||||
|
|
||||||
Array<uint32> indices(mesh->mNumFaces * 3);
|
Array<uint32> indices(mesh->mNumFaces * 3);
|
||||||
@@ -575,7 +583,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
|
|||||||
globalMeshes[meshIndex]->blas = graphics->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo{
|
globalMeshes[meshIndex]->blas = graphics->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo{
|
||||||
.mesh = globalMeshes[meshIndex],
|
.mesh = globalMeshes[meshIndex],
|
||||||
});
|
});
|
||||||
// vertexData->registerBottomLevelAccelerationStructure(globalMeshes[meshIndex]->blas);
|
vertexData->registerBottomLevelAccelerationStructure(globalMeshes[meshIndex]->blas);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
getThreadPool().runAndWait(std::move(work));
|
getThreadPool().runAndWait(std::move(work));
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class MeshLoader {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void findMeshRoots(aiNode* node, List<aiNode*>& meshNodes);
|
void findMeshRoots(aiNode* node, List<aiNode*>& meshNodes);
|
||||||
uint32 encodeQTangent(Matrix3 m);
|
Vector4 encodeQTangent(Matrix3 m);
|
||||||
|
|
||||||
void loadTextures(const aiScene* scene, const std::filesystem::path& meshDirectory, const std::string& importPath,
|
void loadTextures(const aiScene* scene, const std::filesystem::path& meshDirectory, const std::string& importPath,
|
||||||
Array<PTextureAsset>& textures);
|
Array<PTextureAsset>& textures);
|
||||||
|
|||||||
+12
-1
@@ -96,6 +96,13 @@ int main() {
|
|||||||
.filePath = sourcePath / "import/textures/skybox.jpg",
|
.filePath = sourcePath / "import/textures/skybox.jpg",
|
||||||
.type = TextureImportType::TEXTURE_CUBEMAP,
|
.type = TextureImportType::TEXTURE_CUBEMAP,
|
||||||
});
|
});
|
||||||
|
AssetImporter::importTexture(TextureImportArgs{
|
||||||
|
.filePath = sourcePath / "import/textures/brickwall.jpg",
|
||||||
|
});
|
||||||
|
AssetImporter::importTexture(TextureImportArgs{
|
||||||
|
.filePath = sourcePath / "import/textures/brickwall_normal.jpg",
|
||||||
|
.type = TextureImportType::TEXTURE_NORMAL,
|
||||||
|
});
|
||||||
// AssetImporter::importMesh(MeshImportArgs{
|
// AssetImporter::importMesh(MeshImportArgs{
|
||||||
// .filePath = sourcePath / "import/models/ship.fbx",
|
// .filePath = sourcePath / "import/models/ship.fbx",
|
||||||
// .importPath = "ship",
|
// .importPath = "ship",
|
||||||
@@ -113,7 +120,11 @@ int main() {
|
|||||||
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
||||||
.importPath = "Whitechapel",
|
.importPath = "Whitechapel",
|
||||||
});
|
});
|
||||||
// AssetImporter::importMesh(MeshImportArgs{521
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
|
// .filePath = sourcePath / "import/models/plane.obj",
|
||||||
|
// .importPath = "",
|
||||||
|
//});
|
||||||
|
// AssetImporter::importMesh(MeshImportArgs{
|
||||||
// .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj",
|
// .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj",
|
||||||
// .importPath = "suburbs",
|
// .importPath = "suburbs",
|
||||||
// });
|
// });
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
skybox = Seele::Component::Skybox{
|
skybox = Seele::Component::Skybox{
|
||||||
.day = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast<Gfx::TextureCube>(),
|
.day = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>(),
|
||||||
.night = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast<Gfx::TextureCube>(),
|
.night = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>(),
|
||||||
.fogColor = Vector(0.1, 0.1, 0.8),
|
.fogColor = Vector(0.1, 0.1, 0.8),
|
||||||
.blendFactor = 0,
|
.blendFactor = 0,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,31 +18,38 @@ StaticMeshVertexData* StaticMeshVertexData::getInstance() {
|
|||||||
return &instance;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticMeshVertexData::loadPositions(uint64 offset, const Array<Vector>& data) {
|
void StaticMeshVertexData::loadPositions(uint64 offset, const Array<PositionType>& data) {
|
||||||
assert(offset + data.size() <= head);
|
assert(offset + data.size() <= head);
|
||||||
std::memcpy(posData.data() + offset, data.data(), data.size() * sizeof(Vector));
|
std::memcpy(posData.data() + offset, data.data(), data.size() * sizeof(PositionType));
|
||||||
// positions->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data());
|
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticMeshVertexData::loadTexCoords(uint64 offset, uint64 index, const Array<U16Vector2>& data) {
|
void StaticMeshVertexData::loadTexCoords(uint64 offset, uint64 index, const Array<TexCoordType>& data) {
|
||||||
assert(offset + data.size() <= head);
|
assert(offset + data.size() <= head);
|
||||||
std::memcpy(texData[index].data() + offset, data.data(), data.size() * sizeof(U16Vector2));
|
std::memcpy(texData[index].data() + offset, data.data(), data.size() * sizeof(TexCoordType));
|
||||||
// texCoords[index]->updateContents(offset * sizeof(Vector2), data.size() * sizeof(Vector2), data.data());
|
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticMeshVertexData::loadNormals(uint64 offset, const Array<uint32>& data) {
|
void StaticMeshVertexData::loadNormals(uint64 offset, const Array<NormalType>& data) {
|
||||||
assert(offset + data.size() <= head);
|
assert(offset + data.size() <= head);
|
||||||
std::memcpy(norData.data() + offset, data.data(), data.size() * sizeof(uint32));
|
std::memcpy(norData.data() + offset, data.data(), data.size() * sizeof(NormalType));
|
||||||
// normals->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data());
|
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticMeshVertexData::loadColors(uint64 offset, const Array<U16Vector>& data) {
|
void StaticMeshVertexData::loadTangents(uint64 offset, const Array<TangentType>& data) {
|
||||||
assert(offset + data.size() <= head);
|
assert(offset + data.size() <= head);
|
||||||
std::memcpy(colData.data() + offset, data.data(), data.size() * sizeof(U16Vector));
|
std::memcpy(tanData.data() + offset, data.data(), data.size() * sizeof(TangentType));
|
||||||
// colors->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data());
|
dirty = true;
|
||||||
|
}
|
||||||
|
void StaticMeshVertexData::loadBitangents(uint64 offset, const Array<BiTangentType>& data) {
|
||||||
|
assert(offset + data.size() <= head);
|
||||||
|
std::memcpy(bitData.data() + offset, data.data(), data.size() * sizeof(BiTangentType));
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticMeshVertexData::loadColors(uint64 offset, const Array<ColorType>& data) {
|
||||||
|
assert(offset + data.size() <= head);
|
||||||
|
std::memcpy(colData.data() + offset, data.data(), data.size() * sizeof(ColorType));
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,20 +60,26 @@ void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveB
|
|||||||
std::unique_lock l(vertexDataLock);
|
std::unique_lock l(vertexDataLock);
|
||||||
offset = meshOffsets[id];
|
offset = meshOffsets[id];
|
||||||
}
|
}
|
||||||
Array<U16Vector2> tex[MAX_TEXCOORDS];
|
Array<TexCoordType> tex[MAX_TEXCOORDS];
|
||||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||||
tex[i].resize(numVertices);
|
tex[i].resize(numVertices);
|
||||||
std::memcpy(tex[i].data(), texData[i].data() + offset, numVertices * sizeof(U16Vector2));
|
std::memcpy(tex[i].data(), texData[i].data() + offset, numVertices * sizeof(TexCoordType));
|
||||||
Serialization::save(buffer, tex[i]);
|
Serialization::save(buffer, tex[i]);
|
||||||
}
|
}
|
||||||
Array<Vector> pos(numVertices);
|
Array<PositionType> pos(numVertices);
|
||||||
Array<uint32> nor(numVertices);
|
Array<NormalType> nor(numVertices);
|
||||||
Array<U16Vector> col(numVertices);
|
Array<TangentType> tan(numVertices);
|
||||||
std::memcpy(pos.data(), posData.data() + offset, numVertices * sizeof(Vector));
|
Array<BiTangentType> bit(numVertices);
|
||||||
std::memcpy(nor.data(), norData.data() + offset, numVertices * sizeof(uint32));
|
Array<ColorType> col(numVertices);
|
||||||
std::memcpy(col.data(), colData.data() + offset, numVertices * sizeof(U16Vector));
|
std::memcpy(pos.data(), posData.data() + offset, numVertices * sizeof(PositionType));
|
||||||
|
std::memcpy(nor.data(), norData.data() + offset, numVertices * sizeof(NormalType));
|
||||||
|
std::memcpy(tan.data(), tanData.data() + offset, numVertices * sizeof(TangentType));
|
||||||
|
std::memcpy(bit.data(), bitData.data() + offset, numVertices * sizeof(BiTangentType));
|
||||||
|
std::memcpy(col.data(), colData.data() + offset, numVertices * sizeof(ColorType));
|
||||||
Serialization::save(buffer, pos);
|
Serialization::save(buffer, pos);
|
||||||
Serialization::save(buffer, nor);
|
Serialization::save(buffer, nor);
|
||||||
|
Serialization::save(buffer, tan);
|
||||||
|
Serialization::save(buffer, bit);
|
||||||
Serialization::save(buffer, col);
|
Serialization::save(buffer, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,36 +90,61 @@ uint64 StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
|||||||
std::unique_lock l(vertexDataLock);
|
std::unique_lock l(vertexDataLock);
|
||||||
offset = meshOffsets[id];
|
offset = meshOffsets[id];
|
||||||
}
|
}
|
||||||
Array<U16Vector2> tex[MAX_TEXCOORDS];
|
Array<TexCoordType> tex[MAX_TEXCOORDS];
|
||||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||||
Serialization::load(buffer, tex[i]);
|
Serialization::load(buffer, tex[i]);
|
||||||
loadTexCoords(offset, i, tex[i]);
|
loadTexCoords(offset, i, tex[i]);
|
||||||
result += tex[i].size() * sizeof(U16Vector2);
|
result += tex[i].size() * sizeof(TexCoordType);
|
||||||
}
|
}
|
||||||
Array<Vector> pos;
|
Array<PositionType> pos;
|
||||||
Array<uint32> nor;
|
Array<NormalType> nor;
|
||||||
Array<U16Vector> col;
|
Array<TangentType> tan;
|
||||||
|
Array<BiTangentType> bit;
|
||||||
|
Array<ColorType> col;
|
||||||
Serialization::load(buffer, pos);
|
Serialization::load(buffer, pos);
|
||||||
Serialization::load(buffer, nor);
|
Serialization::load(buffer, nor);
|
||||||
|
Serialization::load(buffer, tan);
|
||||||
|
Serialization::load(buffer, bit);
|
||||||
Serialization::load(buffer, col);
|
Serialization::load(buffer, col);
|
||||||
loadPositions(offset, pos);
|
loadPositions(offset, pos);
|
||||||
loadNormals(offset, nor);
|
loadNormals(offset, nor);
|
||||||
|
loadTangents(offset, tan);
|
||||||
|
loadBitangents(offset, bit);
|
||||||
loadColors(offset, col);
|
loadColors(offset, col);
|
||||||
result += pos.size() * sizeof(Vector);
|
result += pos.size() * sizeof(PositionType);
|
||||||
result += nor.size() * sizeof(uint32);
|
result += nor.size() * sizeof(NormalType);
|
||||||
result += col.size() * sizeof(U16Vector);
|
result += tan.size() * sizeof(TangentType);
|
||||||
|
result += bit.size() * sizeof(BiTangentType);
|
||||||
|
result += col.size() * sizeof(ColorType);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticMeshVertexData::init(Gfx::PGraphics _graphics) {
|
void StaticMeshVertexData::init(Gfx::PGraphics _graphics) {
|
||||||
VertexData::init(_graphics);
|
VertexData::init(_graphics);
|
||||||
descriptorLayout = _graphics->createDescriptorLayout("pVertexData");
|
descriptorLayout = _graphics->createDescriptorLayout("pVertexData");
|
||||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
.binding = 0,
|
||||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.binding = 1,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.binding = 2,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
.binding = 3,
|
.binding = 3,
|
||||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.binding = 4,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.binding = 5,
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
.descriptorCount = MAX_TEXCOORDS,
|
.descriptorCount = MAX_TEXCOORDS,
|
||||||
});
|
});
|
||||||
descriptorLayout->create();
|
descriptorLayout->create();
|
||||||
@@ -120,6 +158,8 @@ void StaticMeshVertexData::destroy() {
|
|||||||
}
|
}
|
||||||
positions = nullptr;
|
positions = nullptr;
|
||||||
normals = nullptr;
|
normals = nullptr;
|
||||||
|
tangents = nullptr;
|
||||||
|
biTangents = nullptr;
|
||||||
colors = nullptr;
|
colors = nullptr;
|
||||||
descriptorSet = nullptr;
|
descriptorSet = nullptr;
|
||||||
descriptorLayout = nullptr;
|
descriptorLayout = nullptr;
|
||||||
@@ -136,6 +176,8 @@ Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet() { return descriptor
|
|||||||
void StaticMeshVertexData::resizeBuffers() {
|
void StaticMeshVertexData::resizeBuffers() {
|
||||||
posData.resize(verticesAllocated);
|
posData.resize(verticesAllocated);
|
||||||
norData.resize(verticesAllocated);
|
norData.resize(verticesAllocated);
|
||||||
|
tanData.resize(verticesAllocated);
|
||||||
|
bitData.resize(verticesAllocated);
|
||||||
colData.resize(verticesAllocated);
|
colData.resize(verticesAllocated);
|
||||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||||
texData[i].resize(verticesAllocated);
|
texData[i].resize(verticesAllocated);
|
||||||
@@ -146,7 +188,7 @@ void StaticMeshVertexData::updateBuffers() {
|
|||||||
positions = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
positions = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.sourceData =
|
.sourceData =
|
||||||
{
|
{
|
||||||
.size = verticesAllocated * sizeof(Vector),
|
.size = verticesAllocated * sizeof(PositionType),
|
||||||
.data = (uint8*)posData.data(),
|
.data = (uint8*)posData.data(),
|
||||||
},
|
},
|
||||||
.usage = Gfx::SE_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
|
.usage = Gfx::SE_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
|
||||||
@@ -155,15 +197,31 @@ void StaticMeshVertexData::updateBuffers() {
|
|||||||
normals = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
normals = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.sourceData =
|
.sourceData =
|
||||||
{
|
{
|
||||||
.size = verticesAllocated * sizeof(uint32),
|
.size = verticesAllocated * sizeof(NormalType),
|
||||||
.data = (uint8*)norData.data(),
|
.data = (uint8*)norData.data(),
|
||||||
},
|
},
|
||||||
.name = "Normals",
|
.name = "Normals",
|
||||||
});
|
});
|
||||||
|
tangents = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = verticesAllocated * sizeof(TangentType),
|
||||||
|
.data = (uint8*)tanData.data(),
|
||||||
|
},
|
||||||
|
.name = "Tangents",
|
||||||
|
});
|
||||||
|
biTangents = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = verticesAllocated * sizeof(BiTangentType),
|
||||||
|
.data = (uint8*)bitData.data(),
|
||||||
|
},
|
||||||
|
.name = "BiTangents",
|
||||||
|
});
|
||||||
colors = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
colors = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.sourceData =
|
.sourceData =
|
||||||
{
|
{
|
||||||
.size = verticesAllocated * sizeof(U16Vector),
|
.size = verticesAllocated * sizeof(ColorType),
|
||||||
.data = (uint8*)colData.data(),
|
.data = (uint8*)colData.data(),
|
||||||
},
|
},
|
||||||
.name = "Colors",
|
.name = "Colors",
|
||||||
@@ -172,7 +230,7 @@ void StaticMeshVertexData::updateBuffers() {
|
|||||||
texCoords[i] = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
texCoords[i] = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.sourceData =
|
.sourceData =
|
||||||
{
|
{
|
||||||
.size = verticesAllocated * sizeof(U16Vector2),
|
.size = verticesAllocated * sizeof(TexCoordType),
|
||||||
.data = (uint8*)texData[i].data(),
|
.data = (uint8*)texData[i].data(),
|
||||||
},
|
},
|
||||||
.name = "TexCoords",
|
.name = "TexCoords",
|
||||||
@@ -182,9 +240,11 @@ void StaticMeshVertexData::updateBuffers() {
|
|||||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||||
descriptorSet->updateBuffer(0, 0, positions);
|
descriptorSet->updateBuffer(0, 0, positions);
|
||||||
descriptorSet->updateBuffer(1, 0, normals);
|
descriptorSet->updateBuffer(1, 0, normals);
|
||||||
descriptorSet->updateBuffer(2, 0, colors);
|
descriptorSet->updateBuffer(2, 0, tangents);
|
||||||
|
descriptorSet->updateBuffer(3, 0, biTangents);
|
||||||
|
descriptorSet->updateBuffer(4, 0, colors);
|
||||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||||
descriptorSet->updateBuffer(3, i, texCoords[i]);
|
descriptorSet->updateBuffer(5, i, texCoords[i]);
|
||||||
}
|
}
|
||||||
descriptorSet->writeChanges();
|
descriptorSet->writeChanges();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,22 @@
|
|||||||
namespace Seele {
|
namespace Seele {
|
||||||
class StaticMeshVertexData : public VertexData {
|
class StaticMeshVertexData : public VertexData {
|
||||||
public:
|
public:
|
||||||
|
using PositionType = Vector;
|
||||||
|
using NormalType = Vector;
|
||||||
|
using TangentType = Vector;
|
||||||
|
using BiTangentType = Vector;
|
||||||
|
using TexCoordType = U16Vector2;
|
||||||
|
using ColorType = U16Vector;
|
||||||
|
|
||||||
StaticMeshVertexData();
|
StaticMeshVertexData();
|
||||||
virtual ~StaticMeshVertexData();
|
virtual ~StaticMeshVertexData();
|
||||||
static StaticMeshVertexData* getInstance();
|
static StaticMeshVertexData* getInstance();
|
||||||
void loadPositions(uint64 offset, const Array<Vector>& data);
|
void loadPositions(uint64 offset, const Array<PositionType>& data);
|
||||||
void loadTexCoords(uint64 offset, uint64 index, const Array<U16Vector2>& data);
|
void loadTexCoords(uint64 offset, uint64 index, const Array<TexCoordType>& data);
|
||||||
void loadNormals(uint64 offset, const Array<uint32>& data);
|
void loadNormals(uint64 offset, const Array<NormalType>& data);
|
||||||
void loadColors(uint64 offset, const Array<U16Vector>& data);
|
void loadTangents(uint64 offset, const Array<TangentType>& data);
|
||||||
|
void loadBitangents(uint64 offset, const Array<BiTangentType>& data);
|
||||||
|
void loadColors(uint64 offset, const Array<ColorType>& data);
|
||||||
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override;
|
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override;
|
||||||
virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer) override;
|
virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer) override;
|
||||||
virtual void init(Gfx::PGraphics graphics) override;
|
virtual void init(Gfx::PGraphics graphics) override;
|
||||||
@@ -30,14 +39,19 @@ class StaticMeshVertexData : public VertexData {
|
|||||||
virtual void resizeBuffers() override;
|
virtual void resizeBuffers() override;
|
||||||
virtual void updateBuffers() override;
|
virtual void updateBuffers() override;
|
||||||
|
|
||||||
|
|
||||||
Gfx::OShaderBuffer positions;
|
Gfx::OShaderBuffer positions;
|
||||||
Gfx::OShaderBuffer texCoords[MAX_TEXCOORDS];
|
Gfx::OShaderBuffer texCoords[MAX_TEXCOORDS];
|
||||||
Gfx::OShaderBuffer normals;
|
Gfx::OShaderBuffer normals;
|
||||||
|
Gfx::OShaderBuffer tangents;
|
||||||
|
Gfx::OShaderBuffer biTangents;
|
||||||
Gfx::OShaderBuffer colors;
|
Gfx::OShaderBuffer colors;
|
||||||
Array<Vector> posData;
|
Array<PositionType> posData;
|
||||||
Array<U16Vector2> texData[MAX_TEXCOORDS];
|
Array<TexCoordType> texData[MAX_TEXCOORDS];
|
||||||
Array<Quaternion> norData;
|
Array<NormalType> norData;
|
||||||
Array<U16Vector4> colData;
|
Array<TangentType> tanData;
|
||||||
|
Array<BiTangentType> bitData;
|
||||||
|
Array<ColorType> colData;
|
||||||
Gfx::ODescriptorLayout descriptorLayout;
|
Gfx::ODescriptorLayout descriptorLayout;
|
||||||
Gfx::PDescriptorSet descriptorSet;
|
Gfx::PDescriptorSet descriptorSet;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user