ПрограммированиеФорумГрафика

Объёмный свет / объёмный туман (решено) (4 стр)

Страницы: 13 4 5 68 Следующая »
#45
23:36, 13 янв 2024


    innuendo
 

romanshuvalov
Посмотри шейдера

Какие шейдера ?
Все которые есть в интернете :)

#46
9:22, 14 янв 2024

/A\
> Не дорого, я делал блур на мобилках и работало даже на дохлых мали Т830.
это он:
https://github.com/azhirnov/as-en/blob/dev/AE/engine/shared_data/… ers/Blur.glsl
?

#47
21:28, 14 янв 2024

Grobozavr
Кажется, мы друг друга не понимаем.

Вот картинка. Как её сделать из конуса на постпроцессе? Никак.

Cone light | Объёмный свет / объёмный туман (решено)

Сейчас пробую параметрически, вроде получается (картинка моя), надо только решить вопрос со взглядом с торца, а так же избавиться от множества временных хаков вида

x = pow(x, 0.25);
#48
21:48, 14 янв 2024

romanshuvalov
Степень это не хак а нелинейность
Можно смувстеп попробовать

#49
5:16, 15 янв 2024

innuendo
Я имел в виду, что для повышения производительности хорошо бы вместо степеней найти менее дорогую альтернативу с более-менее похожей функцией.

Смувстеп не даст нелинейности. Арктангенс не знаю, быстрее степени или нет.

#50
6:01, 15 янв 2024

romanshuvalov
Лет двадцать назад раскладывали синус в ряд Тейлора в пиксельном :)
Кубический полином линейный?

#51
9:36, 15 янв 2024

romanshuvalov

Я имел в виду, что для повышения производительности хорошо бы вместо степеней найти менее дорогую альтернативу с более-менее похожей функцией.

Смувстеп не даст нелинейности. Арктангенс не знаю, быстрее степени или нет.

А ты попробуй пиченьки с Бизье :)

Изображение

Изображение
#52
20:58, 15 янв 2024

Вот картинка. Как её сделать из конуса на постпроцессе? Никак.

Берем SDF конус, трассируем луч от камеры сквозь него до первой попавшейся в z-буфере геометрии и суммируем цвет с учетом дистанции до светильника(ов). Опционально учитываем  плавные границы конуса, хотя, думаю, даже без этого так и будет. Можно вполне физически корректно посчитать с любыми наложениями разных источников.

#53
23:53, 15 янв 2024

я так делаю, вдохновившись идеей отсюда https://ijdykeman.github.io/graphics/simple_fog_shader

vec2 ray_cone_intersection(vec3 r0, vec3 rd, vec3 c0, vec3 cd, float angle_cos)
{  
  float cos2 = angle_cos * angle_cos;
  float dv = dot(rd, cd);
  vec3 co = r0 - c0;
  float cov = dot(co , cd);
  
  float a = dv * dv - cos2;
  float b = 2.0 * ( dv * cov - dot(rd , co) * cos2);
  float c = cov * cov - dot(co, co) * cos2;
  
  float det = b * b - 4.0 * a * c;
  
  if (det <= 0.0) return vec2(0.0);
  
  vec2 result = vec2(-b) + vec2(-1.0 , 1.0) * sqrt(det);
  result /= 2.0 * a;  
  
  result = vec2(min(result.x,result.y) , max(result.x,result.y));  
  
  float sx = dot(cd, co + rd * result.x);
  float sy = dot(cd, co + rd * result.y);
  //sx>0 sy>0   start=x  end=y
  //sx<0 sy>0   start=y end=inf
  //sx>0 sy<0    start=0 end=x
  //sx<0 sy<0    start=0 end=0
  
  vec2 res1 = (sx < 0.0) ? vec2(result.y, 1e30) : result;
  vec2 res2 = (sx < 0.0) ? vec2(0.0) : vec2(0.0 , result.x);
  result = (sy < 0.0) ? res2 : res1;  

  return result;
}

float FogFactorSpot(vec3 view_pos, vec3 view_dir, float view_dist, vec3 light_pos, vec3 light_dir, float angle_cos)
{    
  vec2 cone_intersections = ray_cone_intersection(view_pos, view_dir, light_pos, light_dir, angle_cos );
  if ((cone_intersections.y == 0.0) || (cone_intersections.x > view_dist))
    return 0.0;  
    
  cone_intersections = min(cone_intersections, vec2(view_dist));
  cone_intersections = max(cone_intersections, vec2(0.0));
  float t_start = cone_intersections.x;
  float t_end = cone_intersections.y;
  
  vec3 V = view_dir;
  vec3 P = view_pos - light_pos;
  vec3 L = light_dir;
  //float a = dot(V,V);  //always = 1.0
  float b = 2.0 * dot(V,P);
  float c = dot(P,P);
  float m = dot(V,L);
  float n = dot(P,L);  
  
  float an4bm2 = -4.0 * n + 2.0 * b * m;
  float bn2cm4 = -2.0 * b * n + 4.0 * c * m;
  float invbb4ac = (b * b - 4.0 * c);  
  
  if (invbb4ac >= 0.0) return 0.0;  
  
  float integral_end = (an4bm2 * t_end + bn2cm4) *  inversesqrt(max(t_end * ( t_end + b) + c, 0.0));
  float integral_start = (an4bm2 * t_start + bn2cm4) * inversesqrt(max(t_start * ( t_start + b) + c, 0.0));    
    
  float result = (integral_end - integral_start) / invbb4ac;
    
  float k = 1.0 / (1.0 - angle_cos);  
  float invsqrt4acb = inversesqrt(-invbb4ac);  
  
  vec2 atb = (vec2(t_end, t_start) * 2.0 + vec2(b)) * invsqrt4acb;    
  result = mix( 2.0 * (ATan(atb.x) - ATan(atb.y)) * invsqrt4acb , result ,  k);
    
  result *= FOG_GLOBAL_DENSITY;
    
  result = clamp(result, 0.0, 1.0);  
  
  return result;
}
#54
1:16, 16 янв 2024

Мисс_Самец
view_pos - позиция камеры
view_dir - вью вектор
view_dist - расстояние от камеры до освещаемой точки
light_pos - позиция спотлайта
light_dir - направление спотлайта
angle_cos - косинус угла раствора спотлайта (или половины угла, не помню)
подразумевается, что внутри конуса свет распределяется по косинусу
если нужен полусферический лайт вместо спотлайта (последний скрин), нужно заменить пределы интегрирования с пересечения луча с конусом на пересечение луча с плоскостью и выкинуть ремапинг косинусного распределения света (4 строчки, начиная с float k = 1.0 / (1.0 - angle_cos);)

+ скрины
#55
5:59, 16 янв 2024

ncuxonaT
Красиво, но слишком много честных вычислений. Я тоже пробовал делать параметрический конус из вершины, направления оси и угла при вершине, что-то даже получалось, но медленно. В итоге применил другой подход - сфера с изменяемым радиусом, радиус - функция от dot(вектор от вершины до точки, ось конуса).

Изначально получалась в прямом смысле жопа, примерно такая:

Изображение

Но если поиграться с коэффициентами, то будет получится как на черно-белой картинке выше.

Код для shader toy (2D)

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{

    vec2 cone_top = vec2(0.5, 0.95);
    vec2 cone_axle = normalize(vec2(0.35, -0.77));
    
    float factor1 = 2.0;
    float factor2 = factor1 * 0.7;
    float factor3 = 0.25;
    float factor4 = 1.0;

    // ----------------------------------

    vec2 p = fragCoord/iResolution.xy;
    p.x *= iResolution.x/iResolution.y;

    float k = 0.5 + 0.5*dot( normalize(p - cone_top), cone_axle);
    
    k = pow(k, factor1);
    
    float r = k*factor2;
    
    float r_scale = 1.0 - 1.0*smoothstep(0.0, r, pow(factor4*distance(cone_top, p), factor3));  
    
    // r_scale = pow(r_scale, 0.1); // <--- shape test
    
    // -----------------------------------
    
    float o = r_scale; 
    fragColor = vec4(o, o, o, 1.0);
}

Для 3D надо немного повозиться, чтобы спроецировать точку на плоскость, проходящую через источник света и повернутую к камере. Но не обязательно делать это честно:

vec3 restored_pos_in_lightspace = eye_pos + normalize(eye_to_frag) * distance_from_eye_to_light;
#56
11:55, 16 янв 2024

skalogryz
> > Не дорого, я делал блур на мобилках и работало даже на дохлых мали Т830.
> это он:
либо тот, либо этот
https://github.com/Experience-Monks/glsl-fast-gaussian-blur/blob/master/5.glsl

Там суть в том что на десктопах хорошо работает двухпроходный блур, а на мобилках однопроходный, так как меньше памяти гоняется. Еще всякие RGBM с mediump float вместо RGBA16F, но на NV с mediump начинаются какие-то артефакты. В общем там надо много подгонять и пробовать разные варианты.

Еще на мали Т830 трафик был 1500Мб/с, а на мали G52 уже 500Мб/с, то есть сильно улучшили сжатие даже для fp16.

#57
12:24, 16 янв 2024

/A\
> а на мобилках однопроходный,
Подтверждаю. Но главное не перебарщивать с количеством выборок из текстуры. На Mali t830 практический потолок для 60 fps составляет около 8 выборок на пиксель если не ошибаюсь.

#58
1:44, 17 янв 2024

Мисс_Самец
👍🏿
romanshuvalov
Я не понял, как применять ваш способ в случае, когда камера внутри конуса лайта. Или как учитывать глубину объекта.

#59
2:40, 17 янв 2024

ncuxonaT
> когда камера внутри конуса
Всё срабатывает автоматически, надо только передать в шейдер расстояние до источника света (light_distance) и домножать альфу на

smoothstep(-light_radius*light_radius_bleeding_coef, light_radius, v_frag_distance - light_distance);

(v_frag_distance - расстояние от камеры до пикселя)

Страницы: 13 4 5 68 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.