Hi,
Curious/want advice what other GPU devs perspectives are on spamming const in front of every variable in shader code or what guideline you follow? I'm on a new team and we have different opinions on this, but I find it hard to reason about it since it is partly a style thing and I see the style of this being a mixed bag in our org code, depending on a team. It's also not discussed in our org coding guidelines.
Some folks on my team believe in putting const in front of every single variable that's not going to change for consistency. However, when writing shaders, where you do a lot of data transformations, you define a lot of transitional/temporary/single use variables, so that you give specific names to them, or temporary variables to store values from textures, leading to const being suggested to be specified in front of every variable since they aren't expected to change and for consistency. That makes every statement longer, you have to skimread through const before getting to the variable name for every variable, increases mental/reading cost to process. It is a non-negligible cost to process it and adds up long-term. Especially when you have to use a longer var names naming for complex variables. There's a value in being concise (easier/faster to skimread through code, easier code reviews, since there's less text and less likely to text wrap when viewing diffs side by side on screen) and adding const to everything by default makes it all just longer. In my former job, I followed a guideline of specifying const where you explicitly want to guard something against change, or making it obvious it would break algorithm if the var changed, and/or making a var being constant obvious (such as const float kGravity = 9.81) , but not in front of everything. However coding style consistency is also very important when working on shared codebase.
What do you think/suggest/follow?
Consider an example where you put const everywhere:
float3 getWallBounceDirection( in const uint2 DTid,
in const float3 incidentDirection,
in const float speedScaledByDimensionY,
in const float speedClamp,
in const float3 rotateWallPlanePos,
in const float3 wallPlaneBentNormal)
{
const uint2 kResolution = uint2(1920, 1080);
const uint linearIndex = DTid.y * kResolution.x + DTid.x;
const float3 upDirection = float3(0, 1, 0);
const float NdotUp = dot(normal, upDirection);
const float depth = MyDepthTexture[DTid];
// Get reflection vector
const float3 normalVector = MyNormaTexture[DTid];
const float3 IdotN = dot(incidentDirection, normalVector);
const float3 reflectionVector = incidentDirection - 2 * IdotN * normalVector;
// Example of more complex named vars
const float kGravity = 9.81;
const float3 windFieldCoefficient = MyWindFieldTexture1D[linearIndex];
const float3 vectorWindFieldCoefficientScaledByGravityPull =
windFieldCoefficient * kGravity * (-upDirection);
const float3 surfacePosition = screenToWorldPosition(DTid, depth);
const float kRangeRadius = 9.1;
const uint numberOfParticlesInTheNeighborhood =
getNumberOfParticleNeighbors(surfacePosition, kRangeRadius);
const float algebraicCoefficientMultipliedByFactorOfXYZ = ...
// Get penalty force
const float kPenaltyForceCoeff = 27;
const float kFriction = 21;
conts float ...
// imagine 1-50 lines of code reusing some vars above
return bouncedDir;
}