Shader floating point precision issue on large planets
STR: Create a 1250km planet, fly down close to the surface.
The triplanar shaders uses voxel-local coordinates for texture UVs, but passes these voxel-local coordinates around using single precision. This results in significant pixelization on large planets due to those single precision -- a radius of 1250km has +/- .125m precision when used at single precision, corresponding to the pixel size below.
The loss of precision is due to an implicit assignment from Vector3D to Vector3 in
MyVoxelCellComponent.CreateRenderableProxyForPart:
myRenderableProxy.VoxelCommonObjectData.VoxelOffset = this.m_offset;
This ultimately gets used in shader code as a texture coordinate in TriplanarSampling.hlsli:
float3 texcoords = (triplanarInput.texcoords + offset) * scale;Since texture coordinates wrap, this is equivalent to:
float3 texcoords = frac(triplanarInput.texcoords * scale) + frac(offset * scale);To resolve the pixelization is is necessary to hoist the high precision frac call out of the shader and into C# code. This is possible because the unique values for scale are limited, and it should be possible to pre-compute every possible frac(offset * scale) value that could be used, storing that information on the object constants structure.
There might be some clever molduar math that can be performed here to find a f(offset, scales) such that [ frac(f(offset, scales) * scale) == frac(offset * scale) for all scale in scales ], which could avoid some constant buffer size.
Hello Engineer,
Thank you for reaching our and the help provided in reproducing this issue.
We have added this issue into our internal system.
Kind Regards,
Keen Software House:
QA Department
Hello Engineer,
Thank you for reaching our and the help provided in reproducing this issue.
We have added this issue into our internal system.
Kind Regards,
Keen Software House:
QA Department
Replies have been locked on this page!