Hi,
I have implemented a terrain rendering system. The texture coordinates are computed at runtime in the PS, according to the 2D world position (basically, each material/texture contains a 2x2 transformation matrix - rotation + scale only -, which is used to project the 2D world position into texture space).
Now, the materials IDs which are to be applied at a specific terrain location are read in the pixel shader (using a kind of indirection textures) - so, for each pixel on screen.
The material ID is then used to index the 2x2 matrix (each material has one 2x2 matrix).
Then, for each material used for a specific pixel, we project the 2D world position into texture space using this 2x2 matrix.
However, since two neighbours pixels can have different materials, in different orders, the ddx/ddy don't work correctly, leading to rendering artifacts due to discontinuities within a 2x2 pixel block, at borders between two materials for instance.
So, I have solved this by changing the original code ("vUVMatrix" is built for each material layer dynamically - it is different for each material layer):
to
It seems to provide good results visually. My problem is gone and the filtering looks correct.
Still, I am wondering: is it correct to transform the partial derivative using a 2x2 matrix ? Since the transformation is a affine transformation, with only an uniform scale and a rotation, my feeling is it should be correct, but I would be happy to hear your opinion !
I hope this question makes sense, it is not very easy to explain...
Thanks
Greg
I have implemented a terrain rendering system. The texture coordinates are computed at runtime in the PS, according to the 2D world position (basically, each material/texture contains a 2x2 transformation matrix - rotation + scale only -, which is used to project the 2D world position into texture space).
Now, the materials IDs which are to be applied at a specific terrain location are read in the pixel shader (using a kind of indirection textures) - so, for each pixel on screen.
The material ID is then used to index the 2x2 matrix (each material has one 2x2 matrix).
Then, for each material used for a specific pixel, we project the 2D world position into texture space using this 2x2 matrix.
However, since two neighbours pixels can have different materials, in different orders, the ddx/ddy don't work correctly, leading to rendering artifacts due to discontinuities within a 2x2 pixel block, at borders between two materials for instance.
So, I have solved this by changing the original code ("vUVMatrix" is built for each material layer dynamically - it is different for each material layer):
Code:
For each material layer:
(build vUVMatrix)
float2 vUVMat = mul(vUVMatrix, vWorldPosition2D);
ddX = ddx(vUVMat);
ddY = ddy(vUVMat);
vDiffuse = TextureDiffuse.SampleGrad(SamplerTerrainMaterials, vUV, ddX, ddY);
to
Code:
ddX = ddx(vWorldPosition2D);
ddY = ddy(vWorldPosition2D);
For each material layer:
(build vUVMatrix)
float2 vUVMat = mul(vUVMatrix, vWorldPosition2D);
vDiffuse = TextureDiffuse.SampleGrad(SamplerTerrainMaterials, vUV, mul(vUVMatrix, ddX), mul(vUVMatrix, ddY) );
It seems to provide good results visually. My problem is gone and the filtering looks correct.
Still, I am wondering: is it correct to transform the partial derivative using a 2x2 matrix ? Since the transformation is a affine transformation, with only an uniform scale and a rotation, my feeling is it should be correct, but I would be happy to hear your opinion !
I hope this question makes sense, it is not very easy to explain...
Thanks
Greg