More tangent changes

This commit is contained in:
Dynamitos
2024-12-27 17:06:43 +01:00
parent 7f4d7c7f71
commit f3b6ed31dc
15 changed files with 275 additions and 163 deletions
-1
View File
@@ -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());
} }
+1 -1
View File
@@ -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);
} }
} }
} }
+1 -1
View File
@@ -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
View File
@@ -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;
+5 -6
View File
@@ -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)
+60 -26
View File
@@ -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.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.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]);
+6 -19
View File
@@ -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];
}; };
+4 -4
View File
@@ -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;
} }
+1 -1
View File
@@ -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);
+40 -32
View File
@@ -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));
+1 -1
View File
@@ -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
View File
@@ -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",
// }); // });
+2 -2
View File
@@ -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,
}; };
+97 -37
View File
@@ -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();
} }
+22 -8
View File
@@ -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;
}; };