Нечто вроде цветного SSAO

Эффекты постобработки

Нечто вроде цветного SSAO

Сообщение 4ufak 02 июл 2013, 21:59

Изображение
http://www.sendspace.com/file/ru3ia3

(В исходных файлах я писал «SSAL», хотя сейчас понимаю, что этому до SSAL — как до луны пешком. Зато dx11 не нужен.)
Аватара пользователя
4ufak
UNец
 
Сообщения: 39
Зарегистрирован: 23 мар 2011, 18:50
Откуда: Россия, Москва
  • ICQ

Re: Нечто вроде цветного SSAO

Сообщение NightFox 27 сен 2013, 20:37

Спасибо большое. Это напоминает SSDO. Т. е. у вас это получается SSAO+bounce.
NightFox
UNITрон
 
Сообщения: 194
Зарегистрирован: 12 апр 2013, 12:46

Re: Нечто вроде цветного SSAO

Сообщение gnoblin 27 сен 2013, 22:06

:-bd
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Нечто вроде цветного SSAO

Сообщение NightFox 28 сен 2013, 14:32

Ковырял вчера несколько часов. Нашёл причину почему на D3D11 не заводилось (сам я в шейдерах можно сказать не разбираюсь):

В SSALShader.shader нужно поменять строчку:
Код: Выделить всё
c.rgb += ao - vec3 (length (ao) / 3);
на:
Код: Выделить всё
c.rgb += ao - (length (ao) / 3);

А в SSALShaderAssistant.cginc:
Код: Выделить всё
float4 acf = vec4 (0.0);
на:
Код: Выделить всё
float4 acf = (0.0);


D3D11 почему-то не переваривает vec3 и vec4. Сравнил что получилось, разницы с этими vec и без них я не заметил, возможно в каких-то особых случаях разница есть, но в тех что я смотрел всё точно так же — пиксель в пиксель. На OpenGL тоже это не влияет.
NightFox
UNITрон
 
Сообщения: 194
Зарегистрирован: 12 апр 2013, 12:46

Re: Нечто вроде цветного SSAO

Сообщение NightFox 28 сен 2013, 19:34

Совсем забыл, надо ещё изменить (SSALShader.shader):
Код: Выделить всё
#define SAMPLE_COUNT 25
на
Код: Выделить всё
#define SAMPLE_COUNT 26

и расскомментировать строчку ниже:
Код: Выделить всё
//float3 ( 0.2448421,  -0.1610962,   0.1289366),
NightFox
UNITрон
 
Сообщения: 194
Зарегистрирован: 12 апр 2013, 12:46

Re: Нечто вроде цветного SSAO

Сообщение antanas 29 сен 2013, 16:46

Спасибо ! Действительно весьма крутая и простая в использовании вещь получилась , могёт добавить в сценку ту самую недостающую толику реализма . Тут же сразу же и пожелание/вопрос выскажу - а возможно ли (звериной хитростью понимаю что вроде как да) прикрутить к этой штуке контроль глубины по типу как человек сделал тут http://forum.unity3d.com/threads/195740 ... Obscurance со стандартным Ambient-Obscurance эффектом ? Это было бы крайне полезно в некоторых случаях особенно в случаях подобных тому что я описываю в том посте под ником antmashine. Ну в любом случае ще раз спасибо !
antanas
UNец
 
Сообщения: 1
Зарегистрирован: 28 сен 2013, 05:24

Re: Нечто вроде цветного SSAO

Сообщение NightFox 02 окт 2013, 00:13

Три хорошие новости.
antanas писал(а):Спасибо ! Действительно весьма крутая и простая в использовании вещь получилась , могёт добавить в сценку ту самую недостающую толику реализма . Тут же сразу же и пожелание/вопрос выскажу - а возможно ли (звериной хитростью понимаю что вроде как да) прикрутить к этой штуке контроль глубины по типу как человек сделал тут http://forum.unity3d.com/threads/195740 ... Obscurance со стандартным Ambient-Obscurance эффектом ? Это было бы крайне полезно в некоторых случаях особенно в случаях подобных тому что я описываю в том посте под ником antmashine. Ну в любом случае ще раз спасибо !

1. Есть такая тема. Я погуглил и нашёл две темы:
http://forum.unity3d.com/threads/120072 ... e-paramter
http://forum.unity3d.com/threads/83543- ... -parameter
Во втором уже два готовых решения (одно грубо, но дистанцию можно настроить, другое плавно, но настроить как понимаю надо через туман (Edit→Render Settings), кстати работает в том числе когда он выключен), только вот они меняют стандартный frag_ao и всё что его использует будет перекомпилировано. Так что лучше открывать на новом проекте и поменять ключевые строчки на другие и переименовать файлы, чтобы не было конфликтов (хотя может их и не будет, но в существующей сцене например ломается прикреплённый компонент SSAO).

2. Когда я там сравнивал с оригинальным скриптом для работы на D3D11, я сделал так чтобы он как можно меньше отличался от оригинального, но это на ошибку c D3D11 никак не повлияло и я уже потом об этом немного забыл. Потом заметил что «SSAL» потребляет в разы сильнее чем обычный SSAO это начало несколько напрягать и я вспомнил про «свою» версию скрипта, что если... ДА! догадка подтвердилась, когда я проверил со своей переделкой, производительность взлетела в разы! Ещё это помогло избавиться от одного глюка происходящего на мгновение при включении скрипта (вместо цветных свечений белые). Прикрепляю переделанный скрипт.

3. Кстати кому надоели предупреждения об ошибке синтаксиса, то в шейдерах можно заменить:
Код: Выделить всё
#pragma exclude_renderers gles
на
Код: Выделить всё
#pragma only_renderers opengl d3d9 d3d11
Почему такая фигня я не понял. Пробовал вписать в exclude_renderers все рендеры кроме например d3d9, но это не помогло.
А вот если указать какие именно рендеры использовать, то предупреждение пропадает. Странный глюк.


Остался только вопрос, как убрать ступенчатость при высоком уровне размытия?
Изображение
Явно лажа какая-то, а не размытие сделано в шейдере. Приходится балансировать между шумом и этой ступенчатостью.
У вас нет доступа для просмотра вложений в этом сообщении.
NightFox
UNITрон
 
Сообщения: 194
Зарегистрирован: 12 апр 2013, 12:46

Re: Нечто вроде цветного SSAO

Сообщение NightFox 02 окт 2013, 02:17

Ещё в версии с туманом, затратный кусок:
Код: Выделить всё
float fogFactor = (1-(1/exp((normalizedDepth * 100 * _FogDensity)*(normalizedDepth * 100 * _FogDensity))));
return saturate( (1-occ) + fogFactor);

Жрёт около полтора раза больше чем обычная версия и тем более больше той что с простым обрезанием.
Ради интереса вписал
Код: Выделить всё
float fogFactor = 0.1;

И производительность вновь на уровне, то есть дело именно в этом куске, а если быть точнее в «exp».
Можно как-нибудь можно упростить формулу чтобы она стала менее затратной? Какие-нибудь аналоги exp? Методом тыка узнал что есть exp2, работает чуть быстрее, но всё равно далеко до желаемой скорости.
Всё-таки добился вменяемой скорости при приблизительно такой же картинке:
Код: Выделить всё
float fogFactor = (1-(1/exp2((normalizedDepth * 50 * _FogDensity))));
Последний раз редактировалось NightFox 02 окт 2013, 02:57, всего редактировалось 1 раз.
NightFox
UNITрон
 
Сообщения: 194
Зарегистрирован: 12 апр 2013, 12:46

Re: Нечто вроде цветного SSAO

Сообщение gnoblin 02 окт 2013, 02:49

просто догадка: попробуй float заменить на fixed4 и убери домножения на 100 (внеси их в _FogDensity)
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Нечто вроде цветного SSAO

Сообщение NightFox 02 окт 2013, 02:58

gnoblin писал(а):просто догадка: попробуй float заменить на fixed4 и убери домножения на 100 (внеси их в _FogDensity)

Спасибо, сейчас попробую, хотя я выше уже добился почти такой же производительности как и в оригинале (я обновил сообщение). Умножение убрать нельзя, в настройках юнити туман строго зафиксирован до 1 и не более.
NightFox
UNITрон
 
Сообщения: 194
Зарегистрирован: 12 апр 2013, 12:46

Re: Нечто вроде цветного SSAO

Сообщение NightFox 02 окт 2013, 03:23

fixed4 ничего существенного не дало.

Лучше всего получилось так:
Код: Выделить всё
return saturate( (1-occ) + (1-(1.07/exp2((normalizedDepth * 100 * _FogDensity)))) );

Кстати:
Код: Выделить всё
return saturate( (2-(occ + 1.07/exp2(normalizedDepth * 100 * _FogDensity))) );
будет чуть медленнее чем выше.

Больше оптимизировать наверное нельзя, но этого уже более чем достаточно, совсем чуть-чуть медленнее оригинального SSAO.
NightFox
UNITрон
 
Сообщения: 194
Зарегистрирован: 12 апр 2013, 12:46

Re: Нечто вроде цветного SSAO

Сообщение NightFox 02 окт 2013, 14:41

Подскажите пожалуйста. Эти шейдеры используют frag_ao.cginc файлы, сами файлы почти не отличаются, хочу создать универсальный файл где бы не было повторов кода и при этом не потерялась производительность, но не понимаю как это именно сделать. Сейчас я сделал очень грубо — запихнул в один файл несколько «функций» с разными названиями:
Синтаксис:
Используется csharp
half frag_AO (v2f_ao i, int sampleCount, float3 samples[INPUT_SAMPLE_COUNT])
{
        // read random normal from noise texture
    half3 randN = tex2D (_RandomTexture, i.uvr).xyz * 2.0 - 1.0;    
   
    // read scene depth/normal
    float4 depthnormal = tex2D (_CameraDepthNormalsTexture, i.uv);
    float3 viewNorm;
    float depth;
    DecodeDepthNormal (depthnormal, depth, viewNorm);
    depth *= _ProjectionParams.z;
    float scale = _Params.x / depth;
   
    // accumulated occlusion factor
    float occ = 0.0;
    for (int s = 0; s < sampleCount; ++s)
    {
        // Reflect sample direction around a random vector
        half3 randomDir = reflect(samples[s], randN);
       
        // Make it point to the upper hemisphere
        half flip = (dot(viewNorm,randomDir)<0) ? 1.0 : -1.0;
        randomDir *= -flip;
        // Add a bit of normal to reduce self shadowing
        randomDir += viewNorm * 0.3;
       
        float2 offset = randomDir.xy * scale;
        float sD = depth - (randomDir.z * _Params.x);

                // Sample depth at offset location
        float4 sampleND = tex2D (_CameraDepthNormalsTexture, i.uv + offset);
        float sampleD;
        float3 sampleN;
        DecodeDepthNormal (sampleND, sampleD, sampleN);
        sampleD *= _ProjectionParams.z;
        float zd = saturate(sD-sampleD);
        if (zd > _Params.y) {
                // This sample occludes, contribute to occlusion
                occ += pow(1-zd,_Params.z); // sc2
                //occ += 1.0-saturate(pow(1.0 - zd, 11.0) + zd); // nullsq
                //occ += 1.0/(1.0+zd*zd*10); // iq
        }        
    }
    occ /= sampleCount;
    return 1-occ;
}

half frag_AO_DC (v2f_ao i, int sampleCount, float3 samples[INPUT_SAMPLE_COUNT])
{
        // read random normal from noise texture
        half3 randN = tex2D (_RandomTexture, i.uvr).xyz * 2.0 - 1.0;    
       
        // read scene depth/normal
        float4 depthnormal = tex2D (_CameraDepthNormalsTexture, i.uv);
        float3 viewNorm;
        float depth;
        DecodeDepthNormal (depthnormal, depth, viewNorm);
        depth *= _ProjectionParams.z;
        float scale = _Params.x / depth;
       

        // accumulated occlusion factor
        float occ = 0.0;
        for (int s = 0; s < sampleCount; ++s)
        {
                // Reflect sample direction around a random vector
                half3 randomDir = reflect(samples[s], randN);
               
                // Make it point to the upper hemisphere
                half flip = (dot(viewNorm,randomDir)<0) ? 1.0 : -1.0;
                randomDir *= -flip;
                // Add a bit of normal to reduce self shadowing
                randomDir += viewNorm * 0.3;
               
                float2 offset = randomDir.xy * scale;
                float sD = depth - (randomDir.z * _Params.x);

                // Sample depth at offset location
                float4 sampleND = tex2D (_CameraDepthNormalsTexture, i.uv + offset);
                float sampleD;
                float3 sampleN;
                DecodeDepthNormal (sampleND, sampleD, sampleN);
                sampleD *= _ProjectionParams.z;
                float zd = saturate(sD-sampleD);
                if (zd > _Params.y) {
                        // This sample occludes, contribute to occlusion
                        occ += pow(1-zd,_Params.z); // sc2
                        //occ += 1.0-saturate(pow(1.0 - zd, 11.0) + zd); // nullsq
                        //occ += 1.0/(1.0+zd*zd*10); // iq
                }        
        }
        occ /= sampleCount;

        // Ignore this pixel if behind cutoff depth.
        return (depth > _DepthCutoff) ? 1f : (1-occ);
}


half frag_AO_DC_fog (v2f_ao i, int sampleCount, float3 samples[INPUT_SAMPLE_COUNT])
{
        // read random normal from noise texture
        half3 randN = tex2D (_RandomTexture, i.uvr).xyz * 2.0 - 1.0;    
       
        // read scene depth/normal
        float4 depthnormal = tex2D (_CameraDepthNormalsTexture, i.uv);
        float3 viewNorm;
        float depth;
        DecodeDepthNormal (depthnormal, depth, viewNorm);
        float normalizedDepth = depth;
        depth *= _ProjectionParams.z;
        float scale = _Params.x / depth;
       

        // accumulated occlusion factor
        float occ = 0.0;
        for (int s = 0; s < sampleCount; ++s)
        {
                // Reflect sample direction around a random vector
                half3 randomDir = reflect(samples[s], randN);
               
                // Make it point to the upper hemisphere
                half flip = (dot(viewNorm,randomDir)<0) ? 1.0 : -1.0;
                randomDir *= -flip;
                // Add a bit of normal to reduce self shadowing
                randomDir += viewNorm * 0.3;
               
                float2 offset = randomDir.xy * scale;
                float sD = depth - (randomDir.z * _Params.x);

                // Sample depth at offset location
                float4 sampleND = tex2D (_CameraDepthNormalsTexture, i.uv + offset);
                float sampleD;
                float3 sampleN;
                DecodeDepthNormal (sampleND, sampleD, sampleN);
                sampleD *= _ProjectionParams.z;
                float zd = saturate(sD-sampleD);
                if (zd > _Params.y) {
                        // This sample occludes, contribute to occlusion
                        occ += pow(1-zd,_Params.z); // sc2
                        //occ += 1.0-saturate(pow(1.0 - zd, 11.0) + zd); // nullsq
                        //occ += 1.0/(1.0+zd*zd*10); // iq
                }        
        }
        occ /= sampleCount;

        // Ignore this pixel if behind cutoff depth.
        //return (depth > _DepthCutoff) ? 1f : (1-occ);
       
        //float fogFactor = (1-(1/exp((normalizedDepth * 100 * _FogDensity)*(normalizedDepth * 100 * _FogDensity))));
        //return saturate( (1-occ) + fogFactor );
        //return saturate( (1-occ) + (1-(1/exp2((normalizedDepth * _FogDensity) * 50))) );
        //return saturate( (2-(occ + 1.07/exp2(normalizedDepth * 100 * _FogDensity))) );
        return saturate( (1-occ) + (1-(1.07/exp2((normalizedDepth * 100 * _FogDensity)))) );
       
}

Как это можно сделать правильно?
NightFox
UNITрон
 
Сообщения: 194
Зарегистрирован: 12 апр 2013, 12:46

Re: Нечто вроде цветного SSAO

Сообщение [bm] 27 июн 2014, 10:02

Получился крутой ssao, вот только можно без цвета - черным?
Mafia Rush: universal iOS game _https://goo.gl/CKq4D Android _https://goo.gl/slFLXx
Shooter Ball: Android _https://goo.gl/21QyPw
skype: bmindfield
Аватара пользователя
[bm]
UNIверсал
 
Сообщения: 426
Зарегистрирован: 11 май 2010, 22:33
Откуда: Россия, Ижевск


Вернуться в Post-effects

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2