Страница 1 из 2

Вода. Эффект глубины

СообщениеДобавлено: 26 июн 2010, 23:14
Woolf
По созданию воды есть много уроков и туторов, но мало где поднимается вопрос об эффекте глубины.

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

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

Делаем следующее.

1. Берём вот этот http://rghost.ru/1993340 написанный мною скрипт и распаковываем его куда либо в свой проект.

Он же:
WaterLightmapDeep.js
Код: Выделить всё
// by Woolf/R-Age

var fogDensity = 0.00;
var fogColor : Color;
var depthAmbient = 1.50;

var terrainSize : Vector3;
var terrainCollider : Collider;
var texture : Texture2D;
var waterLevel = 10.00;


 

@ContextMenu ("Apply Fog")
function ApplyFog ()
{
   var x = 0.00;
   var y = 0.00;
   while(x < texture.width)
   {
      y = 0.00;
      while(y < texture.height)
      {
         vect = Vector3(parseFloat(x / texture.width) * terrainSize.x, parseFloat(terrainSize.z) , parseFloat(y / texture.height) * terrainSize.y);
         var hit : RaycastHit;
         
         if(terrainCollider.Raycast(Ray(vect, Vector3.up * -terrainSize.z), hit, terrainSize.z))
         {
            depth = waterLevel - hit.point.y;
      
                 if(depth > 0)
            {
               lightCol = texture.GetPixel(x,y);
               curCol = Color.Lerp(lightCol, Color.gray, depthAmbient * depth * fogDensity);
               fog = Vector3(Mathf.Pow(fogColor.r, depth * fogDensity), Mathf.Pow(fogColor.g, depth * fogDensity), Mathf.Pow(fogColor.b, depth * fogDensity));
               texture.SetPixel(x,y, Color(curCol.r * fog.x * lightCol.a, curCol.g * fog.y * lightCol.a, curCol.b * fog.z * lightCol.a, curCol.a));
            }
         }
         y++;
      }
      x++;   
   }
   

   texture.Apply();
}



2. Кидаем скрипт на свой террейн

3. В настройках террейна (иконка с шестерёнкой) указываем Lighting : lightmap
4. Рассчитываем лайтмапу какого хотите разрешения
5. Настраиваем параметры скрипта

Изображение

Fog Density - интенсивность тумана, влияет на прозрачность вашей воды
Fog color - тут что хотите, но я рекомендую цвета ставить тёмные
Depth Ambient - м.. хитромудрый параметр, влияет на подсветку мелких участков, поэксперементируйте )
Terrain Size - вот тут надо указать размеры вашего террейна, X,Y: ширина и длина, Z - высота

Изображение

в коллайдер - коллайдер от террейна
в лайтмап - кидаем лайтмапу терайна,
WaterLevel - устанавливаем высоту (параметр Y) вашей воды, можете посмотреть его у вашего объекта воды.



5. ВНИМАНИЕ - БАГ! сохраняем проект, выходим из редактора. Не знаю почему, но без этих шаманских танцев - не работает.
6. Запускаем редактор, выбираем террейн, выбираем скрипт WaterLightmapDeep, правой кнопкой на заголовок, выбираем Apply Fog
в зависимости от мощности компа и размеров лайтмапы скрипт может работать от 5 до 120 секунд.
по окончанию работы вуаля:

Изображение

Ну чем мог - тем помог, вопросы задавайте сюда.

Re: Вода. Эффект глубины

СообщениеДобавлено: 27 июн 2010, 03:28
gnoblin
Спс за урок!

Предлагаю разместить копию на blogs.unity3d.ru

Можешь отредактировать пост и включить скрипт в тело сообщения?
(если rghost сломается, все будем плакать :D )

Re: Вода. Эффект глубины

СообщениеДобавлено: 27 июн 2010, 14:40
Woolf
Скрипт добавил, а блоги вести - органически не перевариваю, уж извините..

Re: Вода. Эффект глубины

СообщениеДобавлено: 01 окт 2010, 15:45
LiteLight
А как рассчитать лайтмапу в 3.0?

Re: Вода. Эффект глубины

СообщениеДобавлено: 01 окт 2010, 16:05
DbIMok

Re: Вода. Эффект глубины

СообщениеДобавлено: 01 окт 2010, 16:29
LiteLight
(3A4OT)
Научите меня искать в документации нужное

Re: Вода. Эффект глубины

СообщениеДобавлено: 01 окт 2010, 16:39
DbIMok
легко:
1. Help - Unity Manual
2. Ctrl+F - Lightmapping

Re: Вода. Эффект глубины

СообщениеДобавлено: 01 окт 2010, 16:40
LiteLight
Ни работаит :((

Re: Вода. Эффект глубины

СообщениеДобавлено: 01 окт 2010, 22:18
Pyx
Работает,в Reference ищите.

Re: Вода. Эффект глубины

СообщениеДобавлено: 19 окт 2010, 00:39
Woolf
Хм.. Действительно в3.0 не работает..

UnityException: Texture 'LightmapFar-0' is not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings.LightMapper.ApplyFog () (at Assets/GameAssets/Scripts/Other/LightMapper.js:34)

Я чего-то не понял, где искать эти параметры импорта и как мне получить доступ к лайтмап текстуре.

Re: Вода. Эффект глубины

СообщениеДобавлено: 19 окт 2010, 01:17
Paul Siberdt
Тыркните в текстуру и смотрите в инспектор. :-B

Re: Вода. Эффект глубины

СообщениеДобавлено: 21 окт 2010, 22:13
Woolf
Да. Действительно.
Переписал скрипт.

Теперь технология такая:
1) Рендерим лайтмапу
2) Заходим в свойства лайтмапы, адвансед, Устанавливаем енейбл рид/врайт, формат ARGB32
3) Скрипт на террейн, настраиваем
4) Правой кнопкой на скрипт, генерим дно.
5) Любуемся

6) Вертаем настройки лайтмапы взад, на всякий случай.

Было
Изображение

Стало
Изображение

Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;

public class WaterLightMapper : MonoBehaviour
{

        public float WaterClarity = 1.5f;//Прозрачность воды (в метрах)
        public float DeepDistance = 0.5f;//На какой глубине начинать затенение
       
        public Color WaterColor;//Цвет воды
        public GameObject Water = null; //ГО воды
        public Vector3 terrainSize;     // Размер террейна. Ширина, Длина, Высота
        public Collider terrainCollider = null; // Коллайдер террейна
        public Texture2D texmap = null; //Лайтмапа     
       
        private float WaterLevel = 0f;
       
        [ContextMenu("Generate Waterdeep map")]
        public void generate ()
        {
                //Теперь сам генератор               
                int x = 0;
                int y = 0;
                int cnt=0;
                WaterLevel = Water.transform.position.y;
               
                while (x < texmap.width) {
                        y = 0;
                        while (y < texmap.height) {
                               
                                float dtx = (float)x / (float)texmap.width * (float)terrainSize.x + terrainCollider.transform.position.x;
                                float dty = (float)y / (float)texmap.height * (float)terrainSize.y + terrainCollider.transform.position.z;
                               
                                float depth = getDepth (new Vector3 (dtx, terrainSize.z + terrainCollider.transform.position.y, dty));
                               
                       
                                if (depth-DeepDistance > 0) {
                                        // Ниже уровня воды и DeepDistance
                                        Color col=texmap.GetPixel (x, y);
                                        float r;
                                        float g;
                                        float b;                       
                                       
                                        if (depth>WaterClarity+DeepDistance) {
                                          //Глубина больше прозрачности, затемняем грунт
                                               
                                          float mixkf=(WaterClarity+DeepDistance)/depth; // КФ смешивания с учётом освещенности 
                                          r=WaterColor.r*mixkf;
                                          g=WaterColor.g*mixkf;
                                          b=WaterColor.b*mixkf;
                                               
                                        } else {
                                                //Плавно сводим цвет дна к цвету воды     
                                                float mixkf=depth/(WaterClarity+DeepDistance); // КФ смешивания    
                                                r=(col.r-(1-WaterColor.r)*mixkf);
                                                g=(col.g-(1-WaterColor.g)*mixkf);
                                                b=(col.<img src="./images/smilies/66.gif" alt="b-(" title="Beat up" />1-WaterColor.b)*mixkf);
                                               
                                               
                                                if (r>1f) r=1f;
                                                if (g>1f) g=1f;
                                                if (b>1f) b=1f;
                                               
                                                if (r<0f) r=0f;
                                                if (g<0f) g=0f;
                                                if (b<0f) b=0f;                                        
                                               
                                        }
                                       
                                       

                                       
                                        texmap.SetPixel (x, y, new Color (r, g, b, col.a));
                                        cnt++;
                                }
                               
                                y++;
                        }
                        x++;
                }
               
                texmap.Apply ();
                Debug.Log("Pixels "+cnt);  
        }
       
       
       
        private float getDepth (Vector3 pos)
        {
                float res = -1;
               
                Ray ray = new Ray (pos, Vector3.down);
                RaycastHit hit = new RaycastHit ();
               
                if (terrainCollider.Raycast (ray, out hit, terrainSize.z)) {
                        res = WaterLevel - hit.point.y;
                }
                //Debug.Log(res);  
                return res;
        }
}

 

Re: Вода. Эффект глубины

СообщениеДобавлено: 21 окт 2010, 22:28
Neodrop
тег syntax сделает ваш код куда более читаемым. ;)

Re: Вода. Эффект глубины

СообщениеДобавлено: 16 июл 2015, 12:23
darkmonk21
А как можна в юнити 5 так сделать?

Re: Вода. Эффект глубины

СообщениеДобавлено: 16 июл 2015, 16:24
Woolf
А в 5ке уже давно есть вода с эффектом глубины нормальным и не нужны подобные фейковые