Я смещаю вершины, чтобы сформировать трехмерную планету, используя функцию случайного шума:
float hash( float n ) { return fract(sin(n)*753.5453123); }
float snoise( in vec3 x )
{
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
float n = p.x + p.y*157.0 + 113.0*p.z;
return mix(mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x),
mix( hash(n+157.0), hash(n+158.0),f.x),f.y),
mix(mix( hash(n+113.0), hash(n+114.0),f.x),
mix( hash(n+270.0), hash(n+271.0),f.x),f.y),f.z);
}
Поскольку точки рассчитываются на графическом процессоре, у меня нет возможности вычислить гладкие нормали (кроме плоских нормалей с использованием геометрического шейдера). Я нашел различные способы сделать это, например, используя метод соседей, однако это оставляет много артефактов на местности при выполнении расчетов молний.
В настоящее время я вычисляю нормали, используя эту функцию с различными тета-значениями, однако освещение имеет множество закрашенных областей яркого света:
vec3 calcNormal(vec3 pos)
{
float theta = Theta;
vec3 vecTangent = normalize(cross(pos, vec3(1.0, 0.0, 0.0))
+ cross(pos, vec3(0.0, 1.0, 0.0)));
vec3 vecBitangent = normalize(cross(vecTangent, pos));
vec3 ptTangentSample = getPos(normalize(pos + theta * normalize(vecTangent)));
vec3 ptBitangentSample = getPos(normalize(pos + theta * normalize(vecBitangent)));
return normalize(cross(ptTangentSample - pos, ptBitangentSample - pos));
}