More tangent changes
This commit is contained in:
@@ -35,5 +35,4 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target
|
||||
//result = result / (result + float3(1.0));
|
||||
//result = pow(result, float3(1.0/2.2));
|
||||
return float4(result, brdf.getAlpha());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,7 +52,7 @@ void meshMain(
|
||||
{
|
||||
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
|
||||
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];
|
||||
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
|
||||
{
|
||||
float3 evaluate(float3 viewDir_TS, float3 lightDir_TS, float3 lightColor);
|
||||
float3 evaluate(float3x3 tangentToWorld, float3 viewDir_WS, float3 lightDir_WS, float3 lightColor);
|
||||
float3 evaluateAmbient();
|
||||
float getAlpha();
|
||||
float3 getTangentNormal();
|
||||
@@ -27,12 +27,12 @@ struct Phong : IBRDF
|
||||
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 nDotL = dot(normal_TS, lightDir_TS);
|
||||
float3 r = 2 * (nDotL) * normal_TS - lightDir_TS;
|
||||
float rDotV = dot(r, viewDir_TS);
|
||||
float3 normal_WS = normalize(mul(tangentToWorld, 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)));
|
||||
}
|
||||
@@ -70,12 +70,12 @@ struct BlinnPhong : IBRDF
|
||||
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);
|
||||
float diffuse = max(dot(normal_TS, lightDir_TS), 0);
|
||||
float3 h = normalize(lightDir_TS + viewDir_TS);
|
||||
float specular = pow(saturate(dot(normal_TS, h)), shininess);
|
||||
float3 normal_WS = normalize(mul(tangentToWorld, 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);
|
||||
}
|
||||
@@ -107,10 +107,10 @@ struct CelShading : IBRDF
|
||||
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);
|
||||
float nDotL = dot(normal_TS, lightDir_TS);
|
||||
float3 normal_WS = normalize(mul(tangentToWorld, normal));
|
||||
float nDotL = dot(normal_WS, lightDir_WS);
|
||||
float diffuse = max(nDotL, 0);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 h = normalize(lightDir_TS + viewDir_TS);
|
||||
float3 n = normalize(mul(tangentToWorld, 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_TS), 0.0), F0);
|
||||
float3 F = FresnelSchlick(max(dot(h, viewDir_WS), 0.0), F0);
|
||||
|
||||
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;
|
||||
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 k_s = F;
|
||||
@@ -211,7 +211,7 @@ struct CookTorrance : IBRDF
|
||||
|
||||
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;
|
||||
return result * ambientOcclusion;
|
||||
|
||||
@@ -14,8 +14,8 @@ struct DirectionalLight : ILightEnv
|
||||
|
||||
float3 illuminate<B:IBRDF>(LightingParameter params, B brdf)
|
||||
{
|
||||
float3 dir_TS = mul(params.worldToTangent, -normalize(direction.xyz));
|
||||
return brdf.evaluate(params.viewDir_TS, dir_TS, color.xyz);
|
||||
float3 dir_WS = normalize(direction.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 pos_TS = mul(params.worldToTangent, position_WS.xyz);
|
||||
float3 lightDir_TS = pos_TS.xyz - params.position_TS;
|
||||
float d = length(lightDir_TS);
|
||||
float3 lightDir_WS = position_WS.xyz - params.position_WS;
|
||||
float d = length(lightDir_WS);
|
||||
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)
|
||||
|
||||
@@ -9,18 +9,50 @@ struct MaterialParameter
|
||||
|
||||
struct LightingParameter
|
||||
{
|
||||
float3x3 worldToTangent;
|
||||
float3 viewDir_TS;
|
||||
float3 position_TS;
|
||||
float3x3 tangentToWorld;
|
||||
float3 viewDir_WS;
|
||||
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){
|
||||
q = normalize(q); // Ensure that the quaternion is normalized in case it is not, for example after interpolation and so on
|
||||
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) * ((q.w < 0.0) ? -1.0 : 1.0), normal);
|
||||
|
||||
float3x3 qTangentToMatrix(float4 q){
|
||||
q = normalize(q);
|
||||
float qx2 = q.x + q.x;
|
||||
float qy2 = q.y + q.y;
|
||||
float qz2 = q.z + q.z;
|
||||
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
|
||||
@@ -28,10 +60,10 @@ struct FragmentParameter
|
||||
{
|
||||
float4 position_CS : SV_Position;
|
||||
#ifndef POS_ONLY
|
||||
float4 qTangent : QTANGENT;
|
||||
float3 normal_WS : NORMALWS;
|
||||
float3 tangent_WS : TANGENTWS;
|
||||
float3 biTangent_WS : BITANGENTWS;
|
||||
float3 position_WS : POSITIONWS;
|
||||
float3 position_TS : POSITIONTS;
|
||||
float3 cameraPos_TS : CAMPOSTS;
|
||||
float3 vertexColor : COLOR;
|
||||
float4 texCoords0 : TEXCOORDS0;
|
||||
float4 texCoords1 : TEXCOORDS1;
|
||||
@@ -55,17 +87,16 @@ struct FragmentParameter
|
||||
|
||||
LightingParameter getLightingParameter()
|
||||
{
|
||||
float3x3 worldToTangent = transpose(constructTBNFromQTangent(qTangent));
|
||||
LightingParameter result;
|
||||
result.worldToTangent = worldToTangent;
|
||||
result.viewDir_TS = cameraPos_TS - position_TS;
|
||||
result.position_TS = position_TS;
|
||||
result.tangentToWorld = getTangentToWorld();
|
||||
result.viewDir_WS = normalize(pViewParams.cameraPosition_WS.xyz - position_WS);
|
||||
result.position_WS = position_WS;
|
||||
return result;
|
||||
}
|
||||
|
||||
float3x3 getTangentToWorld()
|
||||
{
|
||||
return constructTBNFromQTangent(qTangent);
|
||||
return float3x3(normalize(tangent_WS), normalize(biTangent_WS), normalize(normal_WS));
|
||||
}
|
||||
#endif
|
||||
static FragmentParameter interpolate(FragmentParameter f0, FragmentParameter f1, FragmentParameter f2, float3 barycentricCoords)
|
||||
@@ -73,14 +104,15 @@ struct FragmentParameter
|
||||
FragmentParameter result;
|
||||
result.position_CS = f0.position_CS * barycentricCoords.x + f1.position_CS * barycentricCoords.y + f2.position_CS * barycentricCoords.z;
|
||||
#ifndef POS_ONLY
|
||||
result.qTangent = f0.qTangent * barycentricCoords.x + f1.qTangent * barycentricCoords.y + f2.qTangent * barycentricCoords.z;
|
||||
result.position_WS = f0.position_WS * barycentricCoords.x + f1.position_WS * barycentricCoords.y + f2.position_WS * barycentricCoords.z;
|
||||
result.normal_WS = f0.normal_WS * barycentricCoords.x + f1.normal_WS * barycentricCoords.y + f2.normal_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.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.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;
|
||||
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
@@ -91,11 +123,13 @@ struct VertexAttributes
|
||||
{
|
||||
float3 position_MS;
|
||||
#ifndef POS_ONLY
|
||||
float4 qTangent;
|
||||
float3 normal_MS;
|
||||
float3 tangent_MS;
|
||||
float3 biTangent_MS;
|
||||
float3 vertexColor;
|
||||
float2 texCoords[MAX_TEXCOORDS];
|
||||
#endif
|
||||
FragmentParameter getParameter(float4x4 transformMatrix)
|
||||
FragmentParameter getParameter(float4x4 transformMatrix, float4x4 inverseTransformMatrix)
|
||||
{
|
||||
float4 modelPos = float4(position_MS, 1);
|
||||
float4 worldPos = mul(transformMatrix, modelPos);
|
||||
@@ -104,12 +138,12 @@ struct VertexAttributes
|
||||
FragmentParameter result;
|
||||
result.position_CS = clipPos;
|
||||
#ifndef POS_ONLY
|
||||
result.qTangent = qTangent;
|
||||
float3x3 tbn = constructTBNFromQTangent(qTangent);
|
||||
result.position_TS = mul(tbn, worldPos.xyz);
|
||||
float3x3 normalMatrix = transpose(float3x3(inverseTransformMatrix));
|
||||
result.tangent_WS = mul(normalMatrix, tangent_MS);
|
||||
result.biTangent_WS = mul(normalMatrix, biTangent_MS);
|
||||
result.normal_WS = mul(normalMatrix, normal_MS);
|
||||
result.vertexColor = vertexColor;
|
||||
result.position_WS = worldPos.xyz;
|
||||
result.cameraPos_TS = mul(tbn, pViewParams.cameraPosition_WS.xyz);
|
||||
result.texCoords0 = float4(texCoords[0], texCoords[1]);
|
||||
result.texCoords1 = float4(texCoords[2], texCoords[3]);
|
||||
result.texCoords2 = float4(texCoords[4], texCoords[5]);
|
||||
|
||||
@@ -9,29 +9,14 @@ struct StaticMeshVertexData
|
||||
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 attributes;
|
||||
attributes.position_MS = float3(positions[index * 3 + 0], positions[index * 3 + 1], positions[index * 3 + 2]);
|
||||
#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)
|
||||
{
|
||||
attributes.texCoords[i] = float2(uint16ToFloat(texCoords[i][index * 2 + 0]), uint16ToFloat(texCoords[i][index * 2 + 1]));
|
||||
@@ -41,7 +26,9 @@ struct StaticMeshVertexData
|
||||
return attributes;
|
||||
}
|
||||
StructuredBuffer<float> positions;
|
||||
StructuredBuffer<uint> qtangents;
|
||||
StructuredBuffer<float> normals;
|
||||
StructuredBuffer<float> tangents;
|
||||
StructuredBuffer<float> biTangents;
|
||||
StructuredBuffer<uint16_t> color;
|
||||
StructuredBuffer<uint16_t> texCoords[MAX_TEXCOORDS];
|
||||
};
|
||||
|
||||
@@ -30,9 +30,9 @@ void closestHit(inout RayPayload hitValue, in BuiltInTriangleIntersectionAttribu
|
||||
VertexAttributes attr1 = pVertexData.getAttributes(vertexIndex1);
|
||||
VertexAttributes attr2 = pVertexData.getAttributes(vertexIndex2);
|
||||
|
||||
FragmentParameter f0 = attr0.getParameter(inst.transformMatrix);
|
||||
FragmentParameter f1 = attr1.getParameter(inst.transformMatrix);
|
||||
FragmentParameter f2 = attr2.getParameter(inst.transformMatrix);
|
||||
FragmentParameter f0 = attr0.getParameter(inst.transformMatrix, inst.inverseTransformMatrix);
|
||||
FragmentParameter f1 = attr1.getParameter(inst.transformMatrix, inst.inverseTransformMatrix);
|
||||
FragmentParameter f2 = attr2.getParameter(inst.transformMatrix, inst.inverseTransformMatrix);
|
||||
|
||||
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.emissive = float3(0, 0, 0);
|
||||
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;
|
||||
}
|
||||
@@ -10,7 +10,7 @@ struct Ray
|
||||
|
||||
const static float S_O = 6.9;
|
||||
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 ks = 0;
|
||||
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) {
|
||||
float r = (glm::determinant(m) ? -1.0 : 1.0);
|
||||
m[2] *= r;
|
||||
Vector4 MeshLoader::encodeQTangent(Matrix3 m) {
|
||||
float f = 1.0;
|
||||
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]);
|
||||
Vector4 q;
|
||||
Vector4 r;
|
||||
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) {
|
||||
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])) {
|
||||
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]) {
|
||||
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);
|
||||
q = Vector4(q.x, q.w, q.y, q.z);
|
||||
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);
|
||||
r = Vector4(r.x, r.w, r.y, r.z);
|
||||
} else {
|
||||
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);
|
||||
q = Vector4(q.x, q.y, q.w, q.z);
|
||||
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);
|
||||
r = Vector4(r.x, r.y, r.w, r.z);
|
||||
}
|
||||
Vector4 qAbs = abs(q = glm::normalize(q));
|
||||
int maxComponentIndex = (qAbs.x > qAbs.y) ? ((qAbs.x > qAbs.z) ? ((qAbs.x > qAbs.w) ? 0 : 3) : ((qAbs.z > qAbs.w) ? 2 : 3))
|
||||
: ((qAbs.y > qAbs.z) ? ((qAbs.y > qAbs.w) ? 1 : 3) : ((qAbs.z > qAbs.w) ? 2 : 3));
|
||||
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)};
|
||||
|
||||
q = Vector4(components[maxComponentIndex] * float(((q[maxComponentIndex] < 0.0) ? -1.0 : 1.0) * 1.4142135623730951), q.w);
|
||||
return ((uint32(round(glm::clamp(q.x * 511.0, -511.0, 511.0) + 512.0)) & 0x3ffu) << 0u) |
|
||||
((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) |
|
||||
((uint32(((dot(cross(m[0], m[2]), m[1]) * r) < 0.0) ? 1u : 0u) & 0x1u) << 29u) | ((uint32(maxComponentIndex) & 0x3u) << 30u);
|
||||
r = normalize(r);
|
||||
const float threshold = 1.0 / 32767.0;
|
||||
if (r.w <= threshold) {
|
||||
r = Vector4(Vector(r) * (float)sqrt(1.0 - (threshold * threshold)), (r.w > 0.0) ? threshold : -threshold);
|
||||
}
|
||||
if (((f < 0.0) && (r.w >= 0.0)) || ((f >= 0.0) && (r.w < 0.0))) {
|
||||
r = -r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialInstanceAsset>& materials, Array<OMesh>& globalMeshes,
|
||||
Component::Collider& collider) {
|
||||
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));
|
||||
work.add([=, this, &globalMeshes]() {
|
||||
// assume static mesh for now
|
||||
Array<Vector> positions(mesh->mNumVertices);
|
||||
StaticArray<Array<U16Vector2>, MAX_TEXCOORDS> texCoords;
|
||||
Array<StaticMeshVertexData::PositionType> positions(mesh->mNumVertices);
|
||||
StaticArray<Array<StaticMeshVertexData::TexCoordType>, MAX_TEXCOORDS> texCoords;
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
texCoords[i].resize(mesh->mNumVertices);
|
||||
}
|
||||
Array<uint32> normals(mesh->mNumVertices);
|
||||
Array<U16Vector> colors(mesh->mNumVertices);
|
||||
Array<StaticMeshVertexData::NormalType> normals(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) {
|
||||
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);
|
||||
biTangent = Vector(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z);
|
||||
}
|
||||
Matrix3 tbn = {normal, biTangent, tangent};
|
||||
|
||||
normals[i] = encodeQTangent(tbn);
|
||||
normals[i] = normal;
|
||||
tangents[i] = tangent;
|
||||
biTangents[i] = biTangent;
|
||||
|
||||
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 {
|
||||
colors[i] = U16Vector(1, 1, 1);
|
||||
colors[i] = StaticMeshVertexData::ColorType(1, 1, 1);
|
||||
}
|
||||
}
|
||||
vertexData->loadPositions(offset, positions);
|
||||
@@ -552,6 +558,8 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
|
||||
vertexData->loadTexCoords(offset, i, texCoords[i]);
|
||||
}
|
||||
vertexData->loadNormals(offset, normals);
|
||||
vertexData->loadTangents(offset, tangents);
|
||||
vertexData->loadBitangents(offset, biTangents);
|
||||
vertexData->loadColors(offset, colors);
|
||||
|
||||
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{
|
||||
.mesh = globalMeshes[meshIndex],
|
||||
});
|
||||
// vertexData->registerBottomLevelAccelerationStructure(globalMeshes[meshIndex]->blas);
|
||||
vertexData->registerBottomLevelAccelerationStructure(globalMeshes[meshIndex]->blas);
|
||||
});
|
||||
}
|
||||
getThreadPool().runAndWait(std::move(work));
|
||||
|
||||
@@ -26,7 +26,7 @@ class MeshLoader {
|
||||
|
||||
private:
|
||||
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,
|
||||
Array<PTextureAsset>& textures);
|
||||
|
||||
+12
-1
@@ -96,6 +96,13 @@ int main() {
|
||||
.filePath = sourcePath / "import/textures/skybox.jpg",
|
||||
.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{
|
||||
// .filePath = sourcePath / "import/models/ship.fbx",
|
||||
// .importPath = "ship",
|
||||
@@ -113,7 +120,11 @@ int main() {
|
||||
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
||||
.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",
|
||||
// .importPath = "suburbs",
|
||||
// });
|
||||
|
||||
@@ -79,8 +79,8 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics,
|
||||
});
|
||||
}
|
||||
skybox = Seele::Component::Skybox{
|
||||
.day = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast<Gfx::TextureCube>(),
|
||||
.night = AssetRegistry::findTexture("", "skyboxsun5deg_tn")->getTexture().cast<Gfx::TextureCube>(),
|
||||
.day = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>(),
|
||||
.night = AssetRegistry::findTexture("", "skybox")->getTexture().cast<Gfx::TextureCube>(),
|
||||
.fogColor = Vector(0.1, 0.1, 0.8),
|
||||
.blendFactor = 0,
|
||||
};
|
||||
|
||||
@@ -18,31 +18,38 @@ StaticMeshVertexData* StaticMeshVertexData::getInstance() {
|
||||
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);
|
||||
std::memcpy(posData.data() + offset, data.data(), data.size() * sizeof(Vector));
|
||||
// positions->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data());
|
||||
std::memcpy(posData.data() + offset, data.data(), data.size() * sizeof(PositionType));
|
||||
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);
|
||||
std::memcpy(texData[index].data() + offset, data.data(), data.size() * sizeof(U16Vector2));
|
||||
// texCoords[index]->updateContents(offset * sizeof(Vector2), data.size() * sizeof(Vector2), data.data());
|
||||
std::memcpy(texData[index].data() + offset, data.data(), data.size() * sizeof(TexCoordType));
|
||||
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);
|
||||
std::memcpy(norData.data() + offset, data.data(), data.size() * sizeof(uint32));
|
||||
// normals->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data());
|
||||
std::memcpy(norData.data() + offset, data.data(), data.size() * sizeof(NormalType));
|
||||
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);
|
||||
std::memcpy(colData.data() + offset, data.data(), data.size() * sizeof(U16Vector));
|
||||
// colors->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data());
|
||||
std::memcpy(tanData.data() + offset, data.data(), data.size() * sizeof(TangentType));
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -53,20 +60,26 @@ void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveB
|
||||
std::unique_lock l(vertexDataLock);
|
||||
offset = meshOffsets[id];
|
||||
}
|
||||
Array<U16Vector2> tex[MAX_TEXCOORDS];
|
||||
Array<TexCoordType> tex[MAX_TEXCOORDS];
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
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]);
|
||||
}
|
||||
Array<Vector> pos(numVertices);
|
||||
Array<uint32> nor(numVertices);
|
||||
Array<U16Vector> col(numVertices);
|
||||
std::memcpy(pos.data(), posData.data() + offset, numVertices * sizeof(Vector));
|
||||
std::memcpy(nor.data(), norData.data() + offset, numVertices * sizeof(uint32));
|
||||
std::memcpy(col.data(), colData.data() + offset, numVertices * sizeof(U16Vector));
|
||||
Array<PositionType> pos(numVertices);
|
||||
Array<NormalType> nor(numVertices);
|
||||
Array<TangentType> tan(numVertices);
|
||||
Array<BiTangentType> bit(numVertices);
|
||||
Array<ColorType> col(numVertices);
|
||||
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, nor);
|
||||
Serialization::save(buffer, tan);
|
||||
Serialization::save(buffer, bit);
|
||||
Serialization::save(buffer, col);
|
||||
}
|
||||
|
||||
@@ -77,36 +90,61 @@ uint64 StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
||||
std::unique_lock l(vertexDataLock);
|
||||
offset = meshOffsets[id];
|
||||
}
|
||||
Array<U16Vector2> tex[MAX_TEXCOORDS];
|
||||
Array<TexCoordType> tex[MAX_TEXCOORDS];
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
Serialization::load(buffer, tex[i]);
|
||||
loadTexCoords(offset, i, tex[i]);
|
||||
result += tex[i].size() * sizeof(U16Vector2);
|
||||
result += tex[i].size() * sizeof(TexCoordType);
|
||||
}
|
||||
Array<Vector> pos;
|
||||
Array<uint32> nor;
|
||||
Array<U16Vector> col;
|
||||
Array<PositionType> pos;
|
||||
Array<NormalType> nor;
|
||||
Array<TangentType> tan;
|
||||
Array<BiTangentType> bit;
|
||||
Array<ColorType> col;
|
||||
Serialization::load(buffer, pos);
|
||||
Serialization::load(buffer, nor);
|
||||
Serialization::load(buffer, tan);
|
||||
Serialization::load(buffer, bit);
|
||||
Serialization::load(buffer, col);
|
||||
loadPositions(offset, pos);
|
||||
loadNormals(offset, nor);
|
||||
loadTangents(offset, tan);
|
||||
loadBitangents(offset, bit);
|
||||
loadColors(offset, col);
|
||||
result += pos.size() * sizeof(Vector);
|
||||
result += nor.size() * sizeof(uint32);
|
||||
result += col.size() * sizeof(U16Vector);
|
||||
result += pos.size() * sizeof(PositionType);
|
||||
result += nor.size() * sizeof(NormalType);
|
||||
result += tan.size() * sizeof(TangentType);
|
||||
result += bit.size() * sizeof(BiTangentType);
|
||||
result += col.size() * sizeof(ColorType);
|
||||
return result;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::init(Gfx::PGraphics _graphics) {
|
||||
VertexData::init(_graphics);
|
||||
descriptorLayout = _graphics->createDescriptorLayout("pVertexData");
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .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{
|
||||
.binding = 0,
|
||||
.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{
|
||||
.binding = 3,
|
||||
.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,
|
||||
});
|
||||
descriptorLayout->create();
|
||||
@@ -120,6 +158,8 @@ void StaticMeshVertexData::destroy() {
|
||||
}
|
||||
positions = nullptr;
|
||||
normals = nullptr;
|
||||
tangents = nullptr;
|
||||
biTangents = nullptr;
|
||||
colors = nullptr;
|
||||
descriptorSet = nullptr;
|
||||
descriptorLayout = nullptr;
|
||||
@@ -136,6 +176,8 @@ Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet() { return descriptor
|
||||
void StaticMeshVertexData::resizeBuffers() {
|
||||
posData.resize(verticesAllocated);
|
||||
norData.resize(verticesAllocated);
|
||||
tanData.resize(verticesAllocated);
|
||||
bitData.resize(verticesAllocated);
|
||||
colData.resize(verticesAllocated);
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
texData[i].resize(verticesAllocated);
|
||||
@@ -146,7 +188,7 @@ void StaticMeshVertexData::updateBuffers() {
|
||||
positions = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = verticesAllocated * sizeof(Vector),
|
||||
.size = verticesAllocated * sizeof(PositionType),
|
||||
.data = (uint8*)posData.data(),
|
||||
},
|
||||
.usage = Gfx::SE_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
|
||||
@@ -155,15 +197,31 @@ void StaticMeshVertexData::updateBuffers() {
|
||||
normals = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = verticesAllocated * sizeof(uint32),
|
||||
.size = verticesAllocated * sizeof(NormalType),
|
||||
.data = (uint8*)norData.data(),
|
||||
},
|
||||
.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{
|
||||
.sourceData =
|
||||
{
|
||||
.size = verticesAllocated * sizeof(U16Vector),
|
||||
.size = verticesAllocated * sizeof(ColorType),
|
||||
.data = (uint8*)colData.data(),
|
||||
},
|
||||
.name = "Colors",
|
||||
@@ -172,7 +230,7 @@ void StaticMeshVertexData::updateBuffers() {
|
||||
texCoords[i] = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = verticesAllocated * sizeof(U16Vector2),
|
||||
.size = verticesAllocated * sizeof(TexCoordType),
|
||||
.data = (uint8*)texData[i].data(),
|
||||
},
|
||||
.name = "TexCoords",
|
||||
@@ -182,9 +240,11 @@ void StaticMeshVertexData::updateBuffers() {
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer(0, 0, positions);
|
||||
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) {
|
||||
descriptorSet->updateBuffer(3, i, texCoords[i]);
|
||||
descriptorSet->updateBuffer(5, i, texCoords[i]);
|
||||
}
|
||||
descriptorSet->writeChanges();
|
||||
}
|
||||
|
||||
@@ -9,13 +9,22 @@
|
||||
namespace Seele {
|
||||
class StaticMeshVertexData : public VertexData {
|
||||
public:
|
||||
using PositionType = Vector;
|
||||
using NormalType = Vector;
|
||||
using TangentType = Vector;
|
||||
using BiTangentType = Vector;
|
||||
using TexCoordType = U16Vector2;
|
||||
using ColorType = U16Vector;
|
||||
|
||||
StaticMeshVertexData();
|
||||
virtual ~StaticMeshVertexData();
|
||||
static StaticMeshVertexData* getInstance();
|
||||
void loadPositions(uint64 offset, const Array<Vector>& data);
|
||||
void loadTexCoords(uint64 offset, uint64 index, const Array<U16Vector2>& data);
|
||||
void loadNormals(uint64 offset, const Array<uint32>& data);
|
||||
void loadColors(uint64 offset, const Array<U16Vector>& data);
|
||||
void loadPositions(uint64 offset, const Array<PositionType>& data);
|
||||
void loadTexCoords(uint64 offset, uint64 index, const Array<TexCoordType>& data);
|
||||
void loadNormals(uint64 offset, const Array<NormalType>& 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 uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer) override;
|
||||
virtual void init(Gfx::PGraphics graphics) override;
|
||||
@@ -30,14 +39,19 @@ class StaticMeshVertexData : public VertexData {
|
||||
virtual void resizeBuffers() override;
|
||||
virtual void updateBuffers() override;
|
||||
|
||||
|
||||
Gfx::OShaderBuffer positions;
|
||||
Gfx::OShaderBuffer texCoords[MAX_TEXCOORDS];
|
||||
Gfx::OShaderBuffer normals;
|
||||
Gfx::OShaderBuffer tangents;
|
||||
Gfx::OShaderBuffer biTangents;
|
||||
Gfx::OShaderBuffer colors;
|
||||
Array<Vector> posData;
|
||||
Array<U16Vector2> texData[MAX_TEXCOORDS];
|
||||
Array<Quaternion> norData;
|
||||
Array<U16Vector4> colData;
|
||||
Array<PositionType> posData;
|
||||
Array<TexCoordType> texData[MAX_TEXCOORDS];
|
||||
Array<NormalType> norData;
|
||||
Array<TangentType> tanData;
|
||||
Array<BiTangentType> bitData;
|
||||
Array<ColorType> colData;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user