在Compute Shader中从高度图生成法线图的异常问题排查
问题:高度图转法线图出现异常光照效果
将高度图转换为法线图时,生成的法线图纹理出现来自顶部(绿色)、右侧(红色)、左侧(蓝色)的异常光照效果。
用到的GeoMath.hlsl代码
static const float PI = 3.141592653589793238462643383279; float2 longitudeLatitudeToUV(float2 longLat) { float longitude = longLat[0]; float latitude = longLat[1]; float u = longitude / (2 * PI) + 0.5; float v = latitude / PI + 0.5; return float2(u,v); } float3 longitudeLatitudeToPoint(float2 longLat) { float longitude = longLat[0]; float latitude = longLat[1]; float x; float y; float z; y = sin(latitude); float r = cos(latitude); x = sin(longitude) * r; z = -cos(longitude) * r; return float3(x, y, z); } float2 uvToLongitudeLatitude(float2 uv) { float longitude = (uv.x - 0.5) * (2 * PI); float latitude = (uv.y - 0.5) * PI; return float2(longitude, latitude); } float2 pointToLongitudeLatitude(float3 p) { float longitude = atan2(p.x, p.z); float latitude = asin(p.y); return float2(longitude, latitude); } float2 pointToUV(float3 p) { p = normalize(p); return longitudeLatitudeToUV(pointToLongitudeLatitude(p)); }
转换用的Compute Shader代码
#pragma kernel CSMain #include "GeoMath.hlsl" Texture2D<float> _HeightMap; RWTexture2D<float4> _NormalMap; int _TextureSize_Width; int _TextureSize_Height; float _WorldRadius; float _HeightMultiplier; float3 CalculateWorldPoint(uint2 texCoord) { float2 uv = texCoord / float2(_TextureSize_Width - 1, _TextureSize_Height - 1); float2 longLat = uvToLongitudeLatitude(uv); float3 spherePoint = longitudeLatitudeToPoint(longLat); float height01 = _HeightMap[texCoord].r + 1.0; float worldHeight = _WorldRadius + height01 * _HeightMultiplier; return spherePoint * worldHeight; } uint2 WrapIndex(uint2 texCoord) { texCoord.x = (texCoord.x + _TextureSize_Width) % _TextureSize_Width; texCoord.y = max(min(_TextureSize_Height - 1, texCoord.y), 0); return texCoord; } [numthreads(8,8,1)] void CSMain (uint3 id : SV_DispatchThreadID) { float3 normalVector; float3 posNorth = CalculateWorldPoint(WrapIndex(id.xy + uint2(0, 1))); float3 posSouth = CalculateWorldPoint(WrapIndex(id.xy + uint2(0, -1))); float3 posEast = CalculateWorldPoint(WrapIndex(id.xy + uint2(1, 0))); float3 posWest = CalculateWorldPoint(WrapIndex(id.xy + uint2(-1, 0))); float3 dirNorth = normalize(posNorth - posSouth); float3 dirEast = normalize(posEast - posWest); normalVector = normalize(cross(dirNorth, dirEast)); _NormalMap[id.xy] = float4(normalVector, 1.0); }
相关纹理
- 高度图:

- 异常法线图:

内容的提问来源于stack exchange,提问作者Ann Anjell
相关产品推荐
相关产品推荐

