Files
Seele/res/shaders/lib/StaticMeshVertexInput.slang
T
2023-01-21 18:43:21 +01:00

225 lines
7.1 KiB
Plaintext

import Common;
import MaterialParameter;
import PrimitiveSceneData;
struct VertexValueCache
{
//This struct is passed between vertex and fragment stage
//which means, that it is passed as out mat3x3 in glsl
//but Slang for some reason puts a layout(row_major) above
//every attribute, including this matrix, but matrix layout
//qualifiers are illegal for non-uniform and buffer fields,
//leading to a compiler error
float3 tangentToLocal[3];
float3 tangentToWorld[3];
float4 color;
float3x3 getTangentToLocal()
{
return float3x3(tangentToLocal[0], tangentToLocal[1], tangentToLocal[2]);
}
float3x3 getTangentToWorld()
{
return float3x3(tangentToWorld[0], tangentToWorld[1], tangentToWorld[2]);
}
#if USE_INSTANCING
float4 instanceOrigin;
float3 instanceTransform1;
float3 instanceTransform2;
float3 instanceTransform3;
float4x4 getInstanceTransform()
{
return float4x4(
float4(instanceTransform1.xyz, 0.0f),
float4(instanceTransform2.xyz, 0.0f),
float4(instanceTransform3.xyz, 0.0f),
float4(instanceOrigin.xyz, 1.0f));
)
}
#endif // USE_INSTANCING
};
struct ShaderAttributeInterpolation
{
float3 worldPosition;
float3 viewPosition;
float3 normal;
float3 tangent;
float3 biTangent;
float4 color;
#if NUM_MATERIAL_TEXCOORDS
float4 packedTexCoords[(NUM_MATERIAL_TEXCOORDS+1) / 2];
#endif // NUM_MATERIAL_TEXCOORDS
#if USE_INSTANCING
float4 perInstanceParams;
#endif
MaterialFragmentParameter getMaterialParameter(float4 clipSpacePosition)
{
MaterialFragmentParameter result;
#if NUM_MATERIAL_TEXCOORDS
for(int i = 0; i < NUM_MATERIAL_TEXCOORDS; ++i)
{
if(i % 2 == 1)
{
result.texCoords[i] = packedTexCoords[i / 2].zw;
}
else
{
result.texCoords[i] = packedTexCoords[i / 2].xy;
}
}
#endif
result.tangentToWorld[0] = tangent;
result.tangentToWorld[1] = biTangent;
result.tangentToWorld[2] = normal;
result.clipPosition = clipSpacePosition;
result.worldPosition = worldPosition;
result.viewDir = gViewParams.cameraPos_WS.xyz - worldPosition;
result.worldNormal = normal;
result.worldTangent = tangent;
result.worldBiTangent = biTangent;
result.vertexColor = color;
return result;
}
};
struct VertexShaderInput
{
float4 position;
float3 normal;
float3 tangent;
float3 biTangent;
float4 color;
#if NUM_MATERIAL_TEXCOORDS
#if NUM_MATERIAL_TEXCOORDS > 1
float4 packedTexCoords[NUM_MATERIAL_TEXCOORDS / 2];
#endif
#if NUM_MATERIAL_TEXCOORDS == 1
float2 packedTexCoords2;
#endif
#if NUM_MATERIAL_TEXCOORDS == 3
float2 packedTexCoords2;
#endif
#if NUM_MATERIAL_TEXCOORDS == 5
float2 packedTexCoords2;
#endif
#if NUM_MATERIAL_TEXCOORDS == 7
float2 packedTexCoords2;
#endif
#endif // NUM_MATERIAL_TEXCOORDS
#if USE_INSTANCING
float4 instanceOrigin;
float3 instanceTransform1;
float3 instanceTransform2;
float3 instanceTransform3;
#endif // USE_INSTANCING
float3x3 calcTangentToLocal()
{
float3x3 result;
result[0] = tangent;
result[1] = biTangent;
result[2] = normal;
return result;
}
float3 getWorldPosition()
{
float4x4 localToWorld = getSceneData().localToWorld;
float3 rotatedPosition = localToWorld[0].xyz * position.xxx + localToWorld[1].xyz * position.yyy + localToWorld[2].xyz * position.zzz;
return mul(getSceneData().localToWorld, position).xyz;
//rotatedPosition + float3(localToWorld[0].w, localToWorld[1].w, localToWorld[2].w);
}
VertexValueCache getVertexCache()
{
VertexValueCache cache;
cache.color = color;
#if USE_INSTANCING
cache.instanceTransform1 = instanceTransform1;
cache.instanceTransform2 = instanceTransform2;
cache.instanceTransform3 = instanceTransform3;
cache.instanceOrigin = instanceOrigin;
#endif
float3x3 tangentToLocal = calcTangentToLocal();
cache.tangentToLocal[0] = tangentToLocal[0];
cache.tangentToLocal[1] = tangentToLocal[1];
cache.tangentToLocal[2] = tangentToLocal[2];
cache.tangentToWorld[0] = mul(getSceneData().localToWorld, float4(tangentToLocal[0], 0.0f)).xyz;
cache.tangentToWorld[1] = mul(getSceneData().localToWorld, float4(tangentToLocal[1], 0.0f)).xyz;
cache.tangentToWorld[2] = mul(getSceneData().localToWorld, float4(tangentToLocal[2], 0.0f)).xyz;
return cache;
}
MaterialVertexParameter getMaterialVertexParameters(VertexValueCache cache, float3 worldPosition, float3 viewPosition, float3x3 tangentToLocal)
{
MaterialVertexParameter result;
result.worldPosition = worldPosition;
result.viewPosition = viewPosition;
result.vertexColor = cache.color;
result.tangentToWorld = cache.getTangentToWorld();
// TODO instancing
/*for(int i = 0; i < NUM_MATERIAL_TEXCOORDS-1; i+=2)
{
result.texCoords[i] = packedTexCoords[i/2].xy;
if(i+1 < NUM_MATERIAL_TEXCOORDS)
{
result.texCoords = packedTexCoords[i / 2].zw;
}
}*/
result.texCoords[0] = packedTexCoords2;
return result;
}
ShaderAttributeInterpolation getInterpolants(VertexValueCache cache, MaterialVertexParameter vertexParams)
{
ShaderAttributeInterpolation result = (ShaderAttributeInterpolation)0;
float3x3 tangentToWorld = cache.getTangentToWorld();
result.normal = mul(getSceneData().localToWorld, float4(normal, 0.0f)).xyz;
result.tangent = mul(getSceneData().localToWorld, float4(tangent, 0.0f)).xyz;
result.biTangent = mul(getSceneData().localToWorld, float4(biTangent, 0.0f)).xyz;
result.color = color;
result.worldPosition = vertexParams.worldPosition;
result.viewPosition = vertexParams.viewPosition;
for(int i = 0; i < NUM_MATERIAL_TEXCOORDS; ++i)
{
if(i % 2 == 1)
{
result.packedTexCoords[i / 2].zw = vertexParams.texCoords[i];
}
else
{
result.packedTexCoords[i / 2].xy = vertexParams.texCoords[i];
}
}
return result;
}
};
struct PositionOnlyVertexShaderInput
{
float4 position;
#if USE_INSTANCING
float4 instanceOrigin;
float3 instanceTransform1;
float3 instanceTransform2;
float3 instanceTransform3;
#endif // USE_INSTANCING
float3 getWorldPosition()
{
float4x4 localToWorld = getSceneData().localToWorld;
float3 rotatedPosition = localToWorld[0].xyz * position.xxx + localToWorld[1].xyz * position.yyy + localToWorld[2].xyz * position.zzz;
return mul(getSceneData().localToWorld, position).xyz;
//rotatedPosition + float3(localToWorld[0].w, localToWorld[1].w, localToWorld[2].w);
}
};