Skip to content

Commit

Permalink
Fixing normal based UV calculation in Metal shader
Browse files Browse the repository at this point in the history
The matrix multiply order was incorrect. Also added some clarity to the varaible names.
  • Loading branch information
colincornaby committed Dec 4, 2024
1 parent 5cdc425 commit 395d438
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,10 @@ vertex ColorInOut pipelineVertexShader(Vertex in [[stage_in]],
// Fog
out.fogColor = uniforms.calcFog(vCamPosition);

const float4 normal = (uniforms.localToWorldMatrix * float4(in.normal, 0.f)) * uniforms.worldToCameraMatrix;
const float4 cameraSpaceNormal = normalize(((float4(in.normal, 0.f) * uniforms.localToWorldMatrix) * uniforms.worldToCameraMatrix));

for (size_t layer=0; layer<num_layers; layer++) {
(&out.texCoord1)[layer] = uniforms.sampleLocation(layer, &in.texCoord1, normal, vCamPosition);
(&out.texCoord1)[layer] = uniforms.sampleLocation(layer, &in.texCoord1, cameraSpaceNormal, vCamPosition);
}

out.position = vCamPosition * uniforms.projectionMatrix;
Expand All @@ -260,7 +260,7 @@ vertex ColorInOut pipelineVertexShader(Vertex in [[stage_in]],
constexpr void blendFirst(half4 srcSample, thread half4 &destSample, const uint32_t blendFlags);
constexpr void blend(half4 srcSample, thread half4 &destSample, uint32_t blendFlags);

float3 VertexUniforms::sampleLocation(size_t index, thread float3 *texCoords, const float4 normal, const float4 camPosition) constant
float3 VertexUniforms::sampleLocation(size_t index, thread float3 *texCoords, const float4 cameraSpaceNormal, const float4 camPosition) constant
{
const uint32_t UVWSrc = uvTransforms[index].UVWSrc;
float4x4 matrix = uvTransforms[index].transform;
Expand Down Expand Up @@ -348,7 +348,7 @@ float3 VertexUniforms::sampleLocation(size_t index, thread float3 *texCoords, co
switch (UVWSrc) {
case kUVWNormal:
{
sampleCoord = normal * matrix;
sampleCoord = cameraSpaceNormal * matrix;
}
break;
case kUVWPosition:
Expand All @@ -358,7 +358,7 @@ float3 VertexUniforms::sampleLocation(size_t index, thread float3 *texCoords, co
break;
case kUVWReflect:
{
sampleCoord = reflect(normalize(camPosition), normalize(normal)) * matrix;
sampleCoord = reflect(normalize(camPosition), cameraSpaceNormal) * matrix;
}
break;
default:
Expand Down Expand Up @@ -643,10 +643,11 @@ vertex ColorInOut shadowCastVertexShader(Vertex in
// Fog
out.fogColor = uniforms.calcFog(vCamPosition);

const float4 normal = (uniforms.localToWorldMatrix * float4(in.normal, 0.f)) * uniforms.worldToCameraMatrix;
// FIXME: Shadow casting doesn't use normals. Simplify texture sampling.
const float4 cameraSpaceNormal = normalize(((float4(in.normal, 0.f) * uniforms.localToWorldMatrix) * uniforms.worldToCameraMatrix));

for (size_t layer=0; layer<num_layers; layer++) {
(&out.texCoord1)[layer] = uniforms.sampleLocation(layer, &in.texCoord1, normal, vCamPosition);
(&out.texCoord1)[layer] = uniforms.sampleLocation(layer, &in.texCoord1, cameraSpaceNormal, vCamPosition);
}

out.position = vCamPosition * uniforms.projectionMatrix;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ struct VertexUniforms

UVOutDescriptor uvTransforms[8];
#ifdef __METAL_VERSION__
float3 sampleLocation(size_t index, thread float3 *texCoords, const float4 normal, const float4 camPosition) constant;
float3 sampleLocation(size_t index, thread float3 *texCoords, const float4 cameraSpaceNormal, const float4 camPosition) constant;
half4 calcFog(float4 camPosition) constant;
#endif
};
Expand Down

0 comments on commit 395d438

Please sign in to comment.