рдлрд╛рд╕реНрдЯ рдФрд░ рдЖрд╕рд╛рди рд╡реЙрд▓реНрдпреВрдо рд░реЗрдВрдбрд░рд┐рдВрдЧ рдПрд▓реНрдЧреЛрд░рд┐рджрдо


рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ ShaderToy рд▓рд┐рдЦрд╛ рд╣реИ рдЬреЛ рд╕рд░рд▓ рд╡реЙрд▓реНрдпреВрдореЗрдЯреНрд░рд┐рдХ рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рд╕рдордЭрд╛рддреЗ рд╣реБрдП рдПрдХ рдкреЛрд╕реНрдЯ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ ShaderToy рд╣реА рдпрд╣рд╛рдБ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред рдпрджрд┐ рдЖрдк рдлреЛрди рдпрд╛ рд▓реИрдкрдЯреЙрдк рд╕реЗ тАЛтАЛрдкрдврд╝ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдЗрд╕ рддреНрд╡рд░рд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рджреЗрдЦрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ ред рдореИрдВрдиреЗ рдкреЛрд╕реНрдЯ рдореЗрдВ рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рд╢рд╛рдорд┐рд▓ рдХрд┐рдП рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЛ рдЙрдЪреНрдЪ рд╕реНрддрд░ рдкрд░ ShaderToy рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЙрдирдХреЗ рдкрд╛рд╕ рд╕рднреА рд╡рд┐рд╡рд░рдг рдирд╣реАрдВ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЧрд╣рд░реА рдЦреБрджрд╛рдИ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ ShaderToy рдХреЛрдб рдХреЗ рд╕рд╛рде рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред

рдореЗрд░реЗ ShaderToy рдХреЗ рддреАрди рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдереЗ:

  1. рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдирд┐рд╖реНрдкрд╛рджрди
  2. рд╕рд╛рджрдЧреА
  3. рд╢рд╛рд░реАрд░рд┐рдХ рд╢реБрджреНрдзрддрд╛ (... рдпрд╛ рдРрд╕рд╛ рдХреБрдЫ)

рдореИрдВ рдЗрд╕ рд░рд┐рдХреНрдд рдХреЛрдб рджреГрд╢реНрдп рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░реВрдВрдЧрд╛ред рдореИрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдКрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЖрдкрдХреЛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рд╣рдо рдХрд╣рд╛рдВ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:

  1. рдЕрдкрд╛рд░рджрд░реНрд╢реА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рд░реЗ рдЯреНрд░реЗрд╕рд┐рдВрдЧред рд╕рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд┐рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд░рд▓ рдЪреМрд░рд╛рд╣реЛрдВ рдХреЗ рд╕рд╛рде рдЖрджрд┐рдо рд╣реИрдВ (1 рд╡рд┐рдорд╛рди рдФрд░ 3 рдЧреЛрд▓реЗ)
  2. рдкреНрд░рдХрд╛рд╢ рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП, рдлреЛрдВрдЧ рдЫрд╛рдпрд╛рдВрдХрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рддреАрди рдЧреЛрд▓рд╛рдХрд╛рд░ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдореЗрдВ, рдПрдХ рдХрд╕реНрдЯрдо рдкреНрд░рдХрд╛рд╢ рдХреНрд╖реАрдгрди рдЧреБрдгрд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЫрд╛рдпрд╛ рдХреА рдХрд┐рд░рдгреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рд╡рд┐рдорд╛рди рдХреЛ рд░реЛрд╢рди рдХрд░рддреЗ рд╣реИрдВред

рдпрд╣рд╛рдБ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рд╣рдо рд╡реЙрд▓реНрдпреВрдо рдХреЛ рдПрдХ рдЕрд▓рдЧ рдорд╛рд░реНрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдПрдХ рдЕрдкрд╛рд░рджрд░реНрд╢реА рджреГрд╢реНрдп рдХреЗ рд╕рд╛рде рдорд┐рд╢реНрд░рдг рдХрд░рддрд╛ рд╣реИ; рдпрд╣ рд╕рднреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЗрдВрдЬрдиреЛрдВ рдХреЗ рд╕рдорд╛рди рд╣реИ рдЬреЛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЕрдкрд╛рд░рджрд░реНрд╢реА рдФрд░ рдкрд╛рд░рднрд╛рд╕реА рд╕рддрд╣реЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рднрд╛рдЧ 1: рдЕрдиреБрдХрд░рдг рдорд╛рддреНрд░рд╛


рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ, рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рд╡реЙрд▓реНрдпреВрдореЗрдЯреНрд░рд┐рдХ рдкреНрд░рддрд┐рдкрд╛рджрди рд╢реБрд░реВ рдХрд░ рд╕рдХреЗрдВ, рд╣рдореЗрдВ рдЗрд╕реА рдорд╛рддреНрд░рд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ! рд╡реЙрд▓реНрдпреВрдо рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рджреВрд░реА рдХрд╛рд░реНрдпреЛрдВ (рдПрд╕рдбреАрдПрдл) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рджреВрд░реА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдХрд╛рд░реНрдп рдХреНрдпреЛрдВ рдареАрдХ рд╣реИрдВ? рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдПрдХ рдХрд▓рд╛рдХрд╛рд░ рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рдЖрдкрдХреЛ рдХреЛрдб рдХреЗ рдХреБрдЫ рд╣реА рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдмрд╣реБрдд рдХрд╛рд░реНрдмрдирд┐рдХ рд░реВрдк рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рдореИрдВ рдПрдХ рд╕рдВрдХреЗрдд рдХреЗ рд╕рд╛рде рджреВрд░рд┐рдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрд╛рдд рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрдирд┐рдЧреЛ рдХрд┐рд▓реНрд╕ рдиреЗ рдкрд╣рд▓реЗ рд╣реА рдЙрдиреНрд╣реЗрдВ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ рд╕рдордЭрд╛рдпрд╛ рд╣реИред рдЖрдк рдЙрддреНрд╕реБрдХ рд╣реИрдВ, рддреЛ рд╡рд╣рд╛рдБ рдкрд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рджреВрд░реА рдФрд░ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд╡рд┐рднрд┐рдиреНрди func- рдорд╛рд╣реМрд▓ рдХрд╛ рдПрдХ рдмрдбрд╝рд╛ рд╕реВрдЪреА рд╣реИред рдФрд░ рдпрд╣рд╛рдБ рдПрдХ рдФрд░ рд▓реЗрдЦ рд╣реИ рдЬреЛ рдЗрди рдПрд╕рдбреАрдПрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред

рдЖрдЗрдП рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ рдФрд░ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдЬреЛрдбрд╝реЗрдВ:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рдЕрдм рд╣рдо рдПрдХ рдФрд░ рдЧреЛрд▓реЗ рдХреЛ рдЬреЛрдбрд╝реЗрдВрдЧреЗ рдФрд░ рдЧреЛрд▓реЗ рдХреЗ рджреВрд░реА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдорд░реНрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд┐рдХрдиреА рд╕рдВрдпреБрдЧреНрдорди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдпрд╣ рдХреЛрдб рдореИрдВрдиреЗ рд╕реАрдзреЗ Inigo рдкреЗрдЬ рд╕реЗ рд▓рд┐рдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЗрд╕реЗ рдпрд╣рд╛рдБ рдбрд╛рд▓реВрдБрдЧрд╛:

// Taken from https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
float sdSmoothUnion( float d1, float d2, float k ) 
{
    float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );
    return mix( d2, d1, h ) - k*h*(1.0-h); 
}

рдЪрд┐рдХрдирд╛ рдмрд╛рдБрдзрдирд╛ рдПрдХ рдЕрддреНрдпрдВрдд рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдХреБрдЫ рд╕рд░рд▓ рдЖрдХреГрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдХрд░рдХреЗ рдЗрд╕реЗ рдХреБрдЫ рд░реЛрдЪрдХ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдореЗрд░реЗ рдХрдИ рд╕реБрдЧрдо рд╕рдВрдпреБрдЧреНрдорд┐рдд рдЧреЛрд▓реЗ рджрд┐рдЦрддреЗ рд╣реИрдВ:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рддреЛ, рд╣рдореЗрдВ рдХреБрдЫ рдЕрд╢реНрд░реБ-рдЖрдХрд╛рд░ рдорд┐рд▓рд╛, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдПрдХ рдмреВрдВрдж рдХреА рддрд░рд╣ рдмрд╛рджрд▓ рдХреА рддрд░рд╣ рдХреБрдЫ рдФрд░ рдЪрд╛рд╣рд┐рдПред рдПрд╕рдбреАрдПрдл рдХреА рдПрдХ рдмрдбрд╝реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдПрд╕рдбреАрдПрдл рдореЗрдВ рдмрд╕ рдереЛрдбрд╝рд╛ рд╕рд╛ рд╢реЛрд░ рдЬреЛрдбрд╝рдХрд░ рд╕рддрд╣ рдХреЛ рд╡рд┐рдХреГрдд рдХрд░рдирд╛ рдХрд┐рддрдирд╛ рдЖрд╕рд╛рди рд╣реИред рддреЛ рдЪрд▓реЛ рд╢реЛрд░ рд╕рдорд╛рд░реЛрд╣ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╢реЛрд░ рдХреЗ рдКрдкрд░ рдХреБрдЫ рднрдЧреНрди рдмреНрд░рд╛рдЙрдирд┐рдпрди рдЧрддрд┐ (рдПрдлрдмреАрдПрдо) рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред Inigo Kiles рдиреЗ рднреА FBM рд╢реЛрд░ рдкрд░ рдПрдХ рдорд╣рд╛рди рд▓реЗрдЦ рдореЗрдВ рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рдХрд╡рд░ рдХрд┐рдпрд╛ ред рдпрд╣рд╛рдБ рдХреНрдпрд╛ рд╣реИ fBM рд╢реЛрд░ рдХреЗ рд╕рд╛рде рдЫрд╡рд┐ рд╕реБрдкрд░рдЗрдореНрдкреЛрдЬрд╝реНрдб рджрд┐рдЦреЗрдЧреА:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рдареАрдХ! рдПрдлрдмреАрдПрдо рд╢реЛрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╡рд╕реНрддреБ рдЕрдЪрд╛рдирдХ рдмрд╣реБрдд рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рд▓рдЧрдиреЗ рд▓рдЧреА!

рдЕрдм рд╣рдореЗрдВ рдпрд╣ рднреНрд░рдо рдкреИрджрд╛ рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рдЖрдпрддрди рдкреГрдереНрд╡реА рдХреЗ рд╕рдорддрд▓ рдХреЗ рд╕рд╛рде рдкрд░рд╕реНрдкрд░ рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рд╡рд┐рдорд╛рди рдХреА рджреВрд░реА рдХреЛ рдЬрдореАрди рдХреЗ рд╡рд┐рдорд╛рди рд╕реЗ рдереЛрдбрд╝рд╛ рдиреАрдЪреЗ рдЬреЛрдбрд╝рд╛ рдФрд░ рдмрд╣реБрдд рд╣реА рдЖрдХреНрд░рд╛рдордХ рдпреБрдЧреНрдорди рдореВрд▓реНрдп (рдкреИрд░рд╛рдореАрдЯрд░ k) рдХреЗ рд╕рд╛рде рдЪрд┐рдХрдиреА рдпреБрдЧреНрдорди рдХреЗ рд╕рдВрдпреЛрдЬрди рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдпрд╣ рдЪрд┐рддреНрд░ рдорд┐рд▓рд╛:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рдЕрдВрддрд┐рдо рд╕реНрдкрд░реНрд╢ рд╕рдордп рдХреЗ рд╕рд╛рде fBM рд╢реЛрд░ рдХреЗ xz рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрдЧрд╛, рддрд╛рдХрд┐ рд╡реЙрд▓реНрдпреВрдо рдШреВрдордиреЗ рд╡рд╛рд▓реЗ рдХреЛрд╣рд░реЗ рдХреА рддрд░рд╣ рджрд┐рдЦреЗред рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдкрд░, рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓рдЧрддрд╛ рд╣реИ!

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рдорд╣рд╛рди, рд╣рдореЗрдВ рдПрдХ рдмрд╛рджрд▓ рдХреА рддрд░рд╣ рдХреБрдЫ рдорд┐рд▓рд╛! рдПрд╕рдбреАрдПрдл рдЧрдгрдирд╛ рдХреЛрдб рднреА рдХрд╛рдлреА рдХреЙрдореНрдкреИрдХреНрдЯ рд╣реИ:

float QueryVolumetricDistanceField( in vec3 pos)
{    
    vec3 fbmCoord = (pos + 2.0 * vec3(iTime, 0.0, iTime)) / 1.5f;
    float sdfValue = sdSphere(pos, vec3(-8.0, 2.0 + 20.0 * sin(iTime), -1), 5.6);
    sdfValue = sdSmoothUnion(sdfValue,sdSphere(pos, vec3(8.0, 8.0 + 12.0 * cos(iTime), 3), 5.6), 3.0f);
    sdfValue = sdSmoothUnion(sdfValue, sdSphere(pos, vec3(5.0 * sin(iTime), 3.0, 0), 8.0), 3.0) + 7.0 * fbm_4(fbmCoord / 3.2);
    sdfValue = sdSmoothUnion(sdfValue, sdPlane(pos + vec3(0, 0.4, 0)), 22.0);
    return sdfValue;
}

рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдЕрдкрд╛рд░рджрд░реНрд╢реА рд╡рд╕реНрддреБ рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди рд╣реИред рд╣рдореЗрдВ рдПрдХ рд╕реБрдВрджрд░ рд╢рд╛рдирджрд╛рд░ рдХреЛрд╣рд░реЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ!

рд╣рдо рдЗрд╕реЗ рд╡реЙрд▓реНрдпреВрдо рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВ, рди рдХрд┐ рдПрдХ рдЕрдкрд╛рд░рджрд░реНрд╢реА рд╡рд╕реНрддреБ рдХреЗ рд░реВрдк рдореЗрдВ? рдЖрдЗрдП рдкрд╣рд▓реЗ рдЙрд╕ рднреМрддрд┐рдХреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╣рдо рдЕрдиреБрдХрд░рдг рдХрд░рддреЗ рд╣реИрдВред рдЕрдВрддрд░рд┐рдХреНрд╖ рдХреЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╡реЙрд▓реНрдпреВрдо рдХрдгреЛрдВ рдХреА рдПрдХ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рд╣реИред рдФрд░ рдЬрдм рдореИрдВ рдХрд╣рддрд╛ рд╣реВрдВ "рд╡рд┐рд╢рд╛рд▓", рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ "рд╡рд┐рд╢рд╛рд▓"ред рдЗрддрдирд╛ рдЕрдзрд┐рдХ рд╣реИ рдХрд┐ рдЗрди рдХрдгреЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдЖрдЬ рдореЙрдбрд▓рд┐рдВрдЧ рдПрдХ рдЕрд╕рдВрднрд╡ рдХрд╛рд░реНрдп рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдСрдлрд╝рд▓рд╛рдЗрди рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП рднреАред рдЗрд╕рдХреЗ рдЕрдЪреНрдЫреЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ рдЖрдЧ, рдХреЛрд╣рд░рд╛ рдФрд░ рдмрд╛рджрд▓ред рд╕рдЦреНрддреА рд╕реЗ рдмреЛрд▓рдирд╛, рд╕рдм рдХреБрдЫ рдорд╛рддреНрд░рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЧрдгрдирд╛рдУрдВ рдХреА рдЧрддрд┐ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА рдЖрдБрдЦреЗрдВ рдЗрд╕ рдкрд░ рдмрдВрдж рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдФрд░ рдпрд╣ рджрд┐рдЦрд╛рд╡рд╛ рдХрд░рдирд╛ рдХрд┐ рдпрд╣ рдирд╣реАрдВ рд╣реИред рд╣рдо рдЗрди рдХрдгреЛрдВ рдХреЗ рд╕рдВрдЪрдп рдХреЛ рдШрдирддреНрд╡ рдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВ рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рдХрд┐рд╕реА рддрд░рд╣ рдХреЗ 3 рдбреА рдЧреНрд░рд┐рдб (рдпрд╛ рдХреБрдЫ рдФрд░ рдЬрдЯрд┐рд▓, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдУрдкрдирд╡реАрдбреАрдмреА рдореЗрдВ) рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрддреЗ рд╣реИрдВред

рдЬрдм рдкреНрд░рдХрд╛рд╢ рдПрдХ рдЖрдпрддрди рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЬреЛрдбрд╝реА рдШрдЯрдирд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ рдЬрдм рдкреНрд░рдХрд╛рд╢ рдПрдХ рдХрдг рд╕реЗ рдЯрдХрд░рд╛рддрд╛ рд╣реИред рдпрд╣ рдпрд╛ рддреЛ рдмрд┐рдЦрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рджреВрд╕рд░реА рджрд┐рд╢рд╛ рдореЗрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╛ рдкреНрд░рдХрд╛рд╢ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдХрдг рджреНрд╡рд╛рд░рд╛ рдЕрд╡рд╢реЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рднрдВрдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╡рд╣ рдХрд╛рд░реНрдп рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдПрдХрд▓ рдкреНрд░рдХреАрд░реНрдгрди рдХрд╣рд▓рд╛рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ: рд╣рдо рдорд╛рди рд▓реЗрдВрдЧреЗ рдХрд┐ рдкреНрд░рдХрд╛рд╢ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдмрд┐рдЦрд░рд╛ рд╣реБрдЖ рд╣реИ, рдЬрдм рдкреНрд░рдХрд╛рд╢ рдПрдХ рдХрдг рд╕реЗ рдЯрдХрд░рд╛рддрд╛ рд╣реИ рдФрд░ рдХреИрдорд░реЗ рдХреА рдУрд░ рдЙрдбрд╝рддрд╛ рд╣реИред рдпрд╣реА рд╣реИ, рд╣рдо рдХрдИ рдмрд┐рдЦрд░рдиреЗ рдХреЗ рдкреНрд░рднрд╛рд╡реЛрдВ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреЛрд╣рд░рд╛, рдЬрд┐рд╕рдореЗрдВ рджреВрд░реА рдкрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдЖрдорддреМрд░ рдкрд░ рдЕрдзрд┐рдХ рдЕрд╕реНрдкрд╖реНрдЯ рджрд┐рдЦрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рдпрд╣ рдХрд╛рдлреА рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдпрд╣рд╛рдБ рдХреНрдпрд╛ рдПрдХ рд╣реА рдмрд┐рдЦрд░рдиреЗ рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ рдЬрдм рдХрд┐рд░рдг

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рдЗрд╕рдХреЗ рд▓рд┐рдП рдЫрджреНрдо рдХреЛрдб рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

for n steps along the camera ray:
   Calculate what % of your ray hit particles (i.e. were absorbed) and needs lighting
   for m lights:
      for k steps towards the light:
         Calculate % of light that were absorbe in this step
      Calculate lighting based on how much light is visible
Blend results on top of opaque objects pass based on % of your ray that made it through the volume

рдпрд╣реА рд╣реИ, рд╣рдо рдЬрдЯрд┐рд▓рддрд╛ рдУ (рдПрди * рдПрдо * рдХреЗ) рдХреЗ рд╕рд╛рде рдЧрдгрдирд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред рддреЛ GPU рдХреЗ рд▓рд┐рдП рдХрдбрд╝реА рдореЗрд╣рдирдд рдХрд░рдиреА рд╣реЛрдЧреАред

рд╣рдо рдЕрд╡рд╢реЛрд╖рдг рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдХреИрдорд░реЗ рдХреЗ рдмреАрдо рдХреЗ рд╕рд╛рде рд╡реЙрд▓реНрдпреВрдо рдореЗрдВ рдкреНрд░рдХрд╛рд╢ рдХреЗ рдЕрд╡рд╢реЛрд╖рдг рдХреЛ рджреЗрдЦреЗрдВ (рдпрд╛рдиреА, рдЕрднреА рддрдХ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрддреЛрдВ рдХреА рджрд┐рд╢рд╛ рдореЗрдВ рдХрд┐рд░рдг рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ)ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рджреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

  1. рд╡реЙрд▓реНрдпреВрдо рдХреЗ рдЕрдВрджрд░ рдХрд┐рд░рдгрд┐рдВрдЧ рдХрд░реЗрдВ
  2. рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдкрд░ рдЕрд╡рд╢реЛрд╖рдг / рдкреНрд░рдХрд╛рд╢ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ

рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдВрджреБ рдкрд░ рдХрд┐рддрдирд╛ рдкреНрд░рдХрд╛рд╢ рдЕрд╡рд╢реЛрд╖рд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмреБрдЧреБрдПрд░ - рд▓реИрдореНрдмрд░реНрдЯ - рдмреАрдпрд░ рдХрд╛рдиреВрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ , рдЬреЛ рдПрдХ рд╕рд╛рдордЧреНрд░реА рд╕реЗ рдЧреБрдЬрд░рддреЗ рд╕рдордп рдкреНрд░рдХрд╛рд╢ рдХреЗ рдХреНрд╖реАрдгрди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдЧрдгрдирд╛ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ рд╕рд░рд▓ рд╣реИ:

float BeerLambert(float absorptionCoefficient, float distanceTraveled)
{
    return exp(-absorptionCoefficient * distanceTraveled);
}

рдЕрд╡рд╢реЛрд╖рдг рдЧреБрдгрд╛рдВрдХ рдПрдХ рд╕рд╛рдордЧреНрд░реА рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкрд╛рд░рджрд░реНрд╢реА рдорд╛рддреНрд░рд╛ рдореЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкрд╛рдиреА рдореЗрдВ, рдпрд╣ рдореВрд▓реНрдп рдХрдо рд╣реЛрдЧрд╛, рдФрд░ рдХреБрдЫ рдореЛрдЯрд╛ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рджреВрдз, рдЧреБрдгрд╛рдВрдХ рдЕрдзрд┐рдХ рд╣реЛрдЧрд╛ред

рд╡реЙрд▓реНрдпреВрдо рдХрд┐рд░рдгрд┐рдВрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдмрд╕ рдмреАрдо рдХреЗ рд╕рд╛рде рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЖрдХрд╛рд░ рдХреЗ рдХрджрдо рдЙрдард╛рддреЗ рд╣реИрдВ рдФрд░ рд╣рд░ рдЪрд░рдг рдкрд░ рдЕрд╡рд╢реЛрд╖рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдЖрдк рд╕рдордЭ рдирд╣реАрдВ рдкрд╛ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреЗ рдмрдЬрд╛рдп рдирд┐рд╢реНрдЪрд┐рдд рдХрджрдо рдХреНрдпреЛрдВ рдЙрдард╛рдП рдЬрд╛рдПрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЧреЛрд▓реЗ рдХреЛ рдЯреНрд░реЗрд╕ рдХрд░рдирд╛, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдкрдХреЛ рдпрд╛рдж рд╣реИ рдХрд┐ рд╡реЙрд▓реНрдпреВрдо рдХреЗ рднреАрддрд░ рдШрдирддреНрд╡ рд╡рд┐рд╖рдо рд╣реИ, рддреЛ рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдиреАрдЪреЗ рд░рд╛рдИрдорд░рд┐рдВрдЧ рдФрд░ рд╕рдВрдЪрдп рдЕрд╡рд╢реЛрд╖рдг рдХреЛрдб рд╣реИред рдХреБрдЫ рдЪрд░ рдЗрд╕ рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП ShaderToy рдореЗрдВ рдкреВрд░реНрдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВред

float opaqueVisiblity = 1.0f;
const float marchSize = 0.6f;
for(int i = 0; i < MAX_VOLUME_MARCH_STEPS; i++) {
	volumeDepth += marchSize;
	if(volumeDepth > opaqueDepth) break;
	
	vec3 position = rayOrigin + volumeDepth*rayDirection;
	bool isInVolume = QueryVolumetricDistanceField(position) < 0.0f;
	if(isInVolume) 	{
		float previousOpaqueVisiblity = opaqueVisiblity;
		opaqueVisiblity *= BeerLambert(ABSORPTION_COEFFICIENT, marchSize);
		float absorptionFromMarch = previousOpaqueVisiblity - opaqueVisiblity;
		for(int lightIndex = 0; lightIndex < NUM_LIGHTS; lightIndex++) {
			float lightDistance = length((GetLight(lightIndex).Position - position));
			vec3 lightColor = GetLight(lightIndex).LightColor * GetLightAttenuation(lightDistance);  
			volumetricColor += absorptionFromMarch * volumeAlbedo * lightColor;
		}
		volumetricColor += absorptionFromMarch * volumeAlbedo * GetAmbientLight();
	}
}

рдФрд░ рдпрд╣рд╛рдБ рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИ:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рд▓рдЧрддрд╛ рд╣реИ рдХреИрдВрдбреА рдлреНрд▓реЙрд╕! рд╢рд╛рдпрдж рдХреБрдЫ рдкреНрд░рднрд╛рд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛! рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрддреНрдо-рдЫрд╛рдпрд╛рдХрд░рдг рдХреА рдХрдореА рд╣реИред рдкреНрд░рдХрд╛рд╢ рдЖрдпрддрди рдХреЗ рд╕рднреА рднрд╛рдЧреЛрдВ рдореЗрдВ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдкрд╣реБрдБрдЪрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рд╢рд╛рд░реАрд░рд┐рдХ рд░реВрдк рд╕реЗ рд╕рд╣реА рдирд╣реАрдВ рд╣реИ, рдЧрд╛рдпрд╛ рдмрд┐рдВрджреБ рдФрд░ рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрдд рдХреЗ рдмреАрдЪ рдХреА рдорд╛рддреНрд░рд╛ рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓реА рд░реЛрд╢рдиреА рдХреА рдПрдХ рдЕрд▓рдЧ рдорд╛рддреНрд░рд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧреАред

рд╕реНрд╡рдпрдВ рдЫрд╛рдпрд╛рдВрдХрди


рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рд╕рдмрд╕реЗ рдХрдард┐рди рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИред рд╣рдореЗрдВ рд╡рд╣реА рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ рдЬреИрд╕рд╛ рд╣рдордиреЗ рдХреИрдорд░реЗ рдХреЗ рдмреАрдо рдХреЗ рд╕рд╛рде рдЕрд╡рд╢реЛрд╖рдг рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдкреНрд░рдХрд╛рд╢ рдХреЗ рдмреАрдо рдХреЗ рд╕рд╛рдеред рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдВрджреБ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рдХрд╛рд╢ рдХреА рдорд╛рддреНрд░рд╛ рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдХреЛрдб рдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рдЗрд╕рдХреА рдирдХрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдЪрдПрд▓рдПрд╕рдПрд▓ рдХреЛ рд╣реИрдХ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рддреЛ рдпрд╣рд╛рдБ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦреЗрдЧрд╛:

float GetLightVisiblity(in vec3 rayOrigin, in vec3 rayDirection, in float maxT, in int maxSteps, in float marchSize) {
    float t = 0.0f;
    float lightVisiblity = 1.0f;
    for(int i = 0; i < maxSteps; i++) {                       
        t += marchSize;
        if(t > maxT) break;

        vec3 position = rayOrigin + t*rayDirection;
        if(QueryVolumetricDistanceField(position) < 0.0) {
            lightVisiblity *= BeerLambert(ABSORPTION_COEFFICIENT, marchSize);
        }
    }
    return lightVisiblity;
}

рд╕реЗрд▓реНрдл-рд╢реИрдбрд┐рдВрдЧ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд┐рд▓рддреЗ рд╣реИрдВ:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рдХрд┐рдирд╛рд░реЛрдВ рдХреЛ рдирд░рдо рдХрд░реЗрдВ


рдлрд┐рд▓рд╣рд╛рд▓, рдореИрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдкрдиреЗ рд╡реЙрд▓реНрдпреВрдо рдХреЛ рдХрд╛рдлреА рдкрд╕рдВрдж рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдж рдЧрдардмрдВрдзрди рдХреЗ рд╡реАрдПрдлрдПрдХреНрд╕ рд╡рд┐рднрд╛рдЧ рдХреЗ рдкреНрд░рддрд┐рднрд╛рд╢рд╛рд▓реА рдиреЗрддрд╛ рдЬреЗрдореНрд╕ рд╢рд╛рд░реНрдк рдХреЛ рджрд┐рдЦрд╛рдпрд╛ред рдЙрдиреНрд╣реЛрдВрдиреЗ рддреБрд░рдВрдд рджреЗрдЦрд╛ рдХрд┐ рд╡реЙрд▓реНрдпреВрдо рдХреЗ рдХрд┐рдирд╛рд░реЗ рдмрд╣реБрдд рддреЗрдЬ рджрд┐рдЦ рд░рд╣реЗ рдереЗред рдФрд░ рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рд╕рдЪ рд╣реИ - рдмрд╛рджрд▓ рдЬреИрд╕реА рд╡рд╕реНрддреБрдПрдВ рдЙрдирдХреЗ рдЖрд╕-рдкрд╛рд╕ рдХреЗ рдЕрдВрддрд░рд┐рдХреНрд╖ рдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ рдмрд┐рдЦрд░реА рд░рд╣рддреА рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдирдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдХреЛ рд╡реЙрд▓реНрдпреВрдо рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЦрд╛рд▓реА рдЬрдЧрд╣ рдХреЗ рд╕рд╛рде рдорд┐рд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдмрд╣реБрдд рдЪрд┐рдХрдиреА рдХрд┐рдирд╛рд░реЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЬреЗрдореНрд╕ рдиреЗ рдореБрдЭреЗ рдПрдХ рдорд╣рд╛рди рд╡рд┐рдЪрд╛рд░ рдХреА рдкреЗрд╢рдХрд╢ рдХреА - рдШрдирддреНрд╡ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╣рдо рдХрд┐рдирд╛рд░реЗ рдХреЗ рдХрд┐рддрдиреЗ рдХрд░реАрдм рд╣реИрдВред рдФрд░ рдЪреВрдВрдХрд┐ рд╣рдо рдПрдХ рд╕рдВрдХреЗрдд рдХреЗ рд╕рд╛рде рджреВрд░реА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ! рддреЛ рдЪрд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡реЙрд▓реНрдпреВрдо рдореЗрдВ рдХрд┐рд╕реА рднреА рдмрд┐рдВрджреБ рдкрд░ рдШрдирддреНрд╡ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

float GetFogDensity(vec3 position)
{   
    float sdfValue = QueryVolumetricDistanceField(position)
    const float maxSDFMultiplier = 1.0;
    bool insideSDF = sdfDistance < 0.0;
    float sdfMultiplier = insideSDF ? min(abs(sdfDistance), maxSDFMultiplier) : 0.0;
    return sdfMultiplier;
}

рдФрд░ рдлрд┐рд░ рд╣рдо рдЗрд╕реЗ рдЕрд╡рд╢реЛрд╖рдг рдорд╛рди рдореЗрдВ рдвреЛрддреЗ рд╣реИрдВ:

opaqueVisiblity *= BeerLambert(ABSORPTION_COEFFICIENT * GetFogDensity(position), marchSize);

рдФрд░ рдпрд╣рд╛рдБ рдРрд╕рд╛ рд╣реИ рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рдШрдирддреНрд╡ рдлрдВрдХреНрд╢рди


рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдШрдирддреНрд╡ рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдЖрдк рдЗрд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╡рд░рдг рдФрд░ рднрд╡реНрдпрддрд╛ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╕рд╛рдиреА рд╕реЗ рд╡реЙрд▓реНрдпреВрдо рдореЗрдВ рдереЛрдбрд╝рд╛ рд╢реЛрд░ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдореИрдВ fBM рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреБрдирдГ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдордиреЗ рд╡реЙрд▓реНрдпреВрдо рд╢реЗрдк рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдерд╛ред

float GetFogDensity(vec3 position)
{   
    float sdfValue = QueryVolumetricDistanceField(position)
    const float maxSDFMultiplier = 1.0;
    bool insideSDF = sdfDistance < 0.0;
    float sdfMultiplier = insideSDF ? min(abs(sdfDistance), maxSDFMultiplier) : 0.0;
   return sdfMultiplier * abs(fbm_4(position / 6.0) + 0.5);
}

рдФрд░ рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд┐рд▓рд╛:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рдЕрдкрд╛рд░рджрд░реНрд╢реА рдЖрддреНрдо-рдЫрд╛рдпрд╛рдВрдХрди


рд╡реЙрд▓реНрдпреВрдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рд╕реБрдВрджрд░ рд▓рдЧ рд░рд╣рд╛ рд╣реИ! рд▓реЗрдХрд┐рди рдереЛрдбрд╝рд╛ рдкреНрд░рдХрд╛рд╢ рдЕрднреА рднреА рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓реАрдХ рд╣реЛрддрд╛ рд╣реИред рдпрд╣рд╛рдВ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╣рд░реЗ рд░рдВрдЧ рдХрд╛ рд░рдВрдЧ рдХреИрд╕реЗ рд░рд┐рд╕рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдорд╛рддреНрд░рд╛ рдХреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрд╡рд╢реЛрд╖рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдпрддрди рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╡реЙрд▓реНрдпреВрдо рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╡реЗ рд╡реЙрд▓реНрдпреВрдо рдХреЗ рдХрд╛рд░рдг рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЫрд╛рдпрд╛рдВрдХрди рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рдирд╣реАрдВ рд░рдЦрддреЗ рд╣реИрдВред рдЗрд╕реЗ рдареАрдХ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ - рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЧреЗрдЯрд▓рд╛рдЗрдЯ рд╡рд┐рдЬрд┐рдмрд┐рд▓рд┐рдЯреА рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рдЫрд╛рдпрд╛рдВрдХрди рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдЗрд╕реЗ рдПрдХ рдЕрдкрд╛рд░рджрд░реНрд╢реА рд╡рд╕реНрддреБ рдХреЛ рд░реЛрд╢рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

рд╕реБрдВрджрд░ рдмрд╣реБрд░рдВрдЧреА рдЫрд╛рдпрд╛ рдмрдирд╛рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдЫрд╛рдпрд╛ рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдФрд░ рджреГрд╢реНрдп рдореЗрдВ рдорд╛рддреНрд░рд╛ рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡реЙрд▓реНрдпреВрдо рдХреЗ рдЪрд┐рдХрдиреА рдХрд┐рдирд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╣рдореЗрдВ рдирд░рдо рдЫрд╛рдпрд╛ рдорд┐рд▓рддреА рд╣реИ, рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐, рд╕рдЦреНрддреА рд╕реЗ рдмреЛрд▓рддреЗ рд╣реБрдП, рд╣рдо рд░реЛрд╢рдиреА рдХреЗ рдмрд┐рдВрджреБ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдмрд╕ рдЗрддрдирд╛ рд╣реА! рдпрд╣рд╛рдВ рдмрд╣реБрдд рдХреБрдЫ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕рд╛рджрдЧреА рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рддреЗ рд╣реБрдП, рдореБрдЭреЗ рдЬрд┐рд╕ рдЧреБрдгрд╡рддреНрддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╡рд╣ рд╣рд╛рд╕рд┐рд▓ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИред

рдЕрдиреБрдХреВрд▓рди


рдЕрдВрдд рдореЗрдВ, рдореИрдВ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдХреБрдЫ рд╕рдВрднрд╛рд╡рд┐рдд рдЕрдиреБрдХреВрд▓рди рд╕реВрдЪреА рджреВрдВрдЧрд╛:

  1. рдкреНрд░рдХрд╛рд╢ рд╕реНрд░реЛрдд рдХреА рджрд┐рд╢рд╛ рдореЗрдВ рдХрд┐рд░рдг рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдкреНрд░рдХрд╛рд╢ рдХреЗ рд╡рд┐рд▓реБрдкреНрдд рд╣реЛрдиреЗ рдХреЗ рдореВрд▓реНрдп рд╕реЗ рдЬрд╛рдВрдЪрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд╢ рдХреА рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдорд╛рддреНрд░рд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рд╡рд╛рд▓ рдкрд░ рдкрд╣реБрдВрдЪрддреА рд╣реИред рдореЗрд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдореИрдВ рдкреНрд░рдХрд╛рд╢ рдХреА рдЪрдордХ рдХреЛ рджреЗрдЦрддрд╛ рд╣реВрдВ, рд╕рд╛рдордЧреНрд░реА рдХреЗ рдПрд▓реНрдмрд┐рдбреЛ рд╕реЗ рдЧреБрдгрд╛ рдХрд░рддрд╛ рд╣реВрдВ, рдФрд░ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдХрд┐рд░рдг рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдп рдХрд╛рдлреА рдмрдбрд╝рд╛ рд╣реИред
  2. , , raymarching
  3. raymarching . , . , raymarching , .


рдмрд╕ рдЗрддрдирд╛ рд╣реА! рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ, рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реБрдЖ рдХрд┐ рдЖрдк рдЗрддрдиреА рдХрдо рдорд╛рддреНрд░рд╛ рдореЗрдВ рдХреЛрдб (рд▓рдЧрднрдЧ 500 рд▓рд╛рдЗрдиреЗрдВ) рд╢рд╛рд░реАрд░рд┐рдХ рд░реВрдк рд╕реЗ рд╕рд╣реА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рдерд╛ред

рдФрд░ рдПрдХ рдФрд░ рдзреНрдпрд╛рди рджреЗрдВ: рдпрд╣рд╛рдВ рдПрдХ рдордЬреЗрджрд╛рд░ рдмрджрд▓рд╛рд╡ рд╣реИ - рдореИрдВрдиреЗ рд╡рд┐рд╕реНрдлреЛрдЯ рдкреНрд░рднрд╛рд╡ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд╕рдбреАрдПрдл рджреВрд░реА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреНрд░рдХрд╛рд╢ рдЙрддреНрд╕рд░реНрдЬрди рдХреЛ рдЬреЛрдбрд╝рд╛ред рдЖрдЦрд┐рд░рдХрд╛рд░, рд╡рд┐рд╕реНрдлреЛрдЯ рдХрднреА рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред

ShaderToy рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ

All Articles