Реагировать на освещение.

Шейдеры и все-все-все.

Реагировать на освещение.

Сообщение mrcoder 02 ноя 2012, 14:17

Уважаемые гуру! Есть небольшая, но важная просьба.
Есть шейдер, который применяется к мешам игрового мира. Но к сожалению он не реагирует на источники света юнити.
При использовании практически любого стандартного шейдера к мешам - все ок.
Насколько я знаю нужно использовать сурфейс шейдер. Но переделать ни этот в сурфейс, ни в стандартный догбавить функцию этого - никак не получается. :((

По сути нужно две вещи в шейдере(которые в этом сделаны) - что бы текстура изменяла цвет в зависимости от цвета вершин и учитывалась альфа.
цвета вершин лежат в mesh.colors = dColors.ToArray();


Shader "ShaderForTerr" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Cutoff ("Cutoff", Range (0,0.1)) = .09
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// #pragma fragmentoption ARB_fog_exp2
#include "UnityCG.cginc"
sampler2D _MainTex;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 color : COLOR0;
};
struct indata
{
float4 vertex;
// float3 normal;
float4 texcoord;
float4 color;
};
v2f vert(indata v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_UV(0);
o.color = v.color;
return o;
}
half4 frag(v2f i) : COLOR
{
return half4(i.color*tex2D(_MainTex, i.uv).rgb, 1-tex2D(_MainTex, i.uv).a);
}
ENDCG
AlphaTest Less [_Cutoff]
}
}
}
Аватара пользователя
mrcoder
Старожил
 
Сообщения: 704
Зарегистрирован: 28 июн 2012, 22:40

Re: Реагировать на освещение.

Сообщение mrcoder 02 ноя 2012, 14:21

простейший сурфейс шейдер вот.. но как добавить сюда colors... несколько часов убил...
с альфой думаю разберусь.
заранее спасибо.
Shader "Example/Diffuse Texture" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
}
SubShader {
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
}
ENDCG
}
Fallback "Diffuse"
}
Аватара пользователя
mrcoder
Старожил
 
Сообщения: 704
Зарегистрирован: 28 июн 2012, 22:40

Re: Реагировать на освещение.

Сообщение Battle Angel Alita 02 ноя 2012, 15:10

как-то так
Синтаксис:
Используется glsl
  Shader "Example/Diffuse Texture" {
    Properties {
      _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert vertex:vert
      struct Input {
          float2 uv_MainTex;
          fixed4 color;
      };
      void vert (inout appdata_full v, out Input o) {
          o.color = v.color;
      }
      sampler2D _MainTex;
      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
          o.Albedo *= IN.color.rgb;
          //blah-blah-blah
      }
      ENDCG
    }
    Fallback "Diffuse"
  }
 
Мозг рака
Изображение
Аватара пользователя
Battle Angel Alita
UNIверсал
 
Сообщения: 476
Зарегистрирован: 25 ноя 2009, 14:52

Re: Реагировать на освещение.

Сообщение mrcoder 02 ноя 2012, 16:41

большущее спасибо! :ymparty: :ymparty: :ymparty:
:-* :-* :-* :-* :-* :-* :-* :-* :-* :-* :-*

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

еще раз большое спасибо. :ymparty:
Аватара пользователя
mrcoder
Старожил
 
Сообщения: 704
Зарегистрирован: 28 июн 2012, 22:40

Re: Реагировать на освещение.

Сообщение mrcoder 02 ноя 2012, 19:15

поторопился... информации об исходном цвете текстуры ведь нет. :(
в примерах и манулах почему то не нашлось как получить исходный(необработанный) цвет текстуры.

а нужно следующее(если получить чистую интенсивность затенения нельзя):
(исходный цвет оригинальной текстуры)/2 * ( IN.color.rgb) + tex2D (_MainTex, IN.uv_MainTex).rgb /2
теряем половину разности цветов, но зато будет желаемый результат.
а сейчас весь мир во мраке и формула действует только для освещенных участков, хотя свет уже просчитан в ручную.

не подскажите как получить в
void surf (Input IN, inout SurfaceOutput o) {

}
исходный цвет текстуры?
спасибо.

единственное что откопал - это возможность переписать(или расширить) дефолтный обработчик света.
но перебираю возможные варианты и убеждаюсь, что с ним ничего не выйдет почти наверняка.
half4 LightingWrapLambert (SurfaceOutput s, half3 lightDir, half atten) {
half NdotL = dot (s.Normal, lightDir);
half diff = NdotL * 0.5 + 0.5;
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
c.a = s.Alpha;
return c;
}
Аватара пользователя
mrcoder
Старожил
 
Сообщения: 704
Зарегистрирован: 28 июн 2012, 22:40

Re: Реагировать на освещение.

Сообщение Woolf 02 ноя 2012, 19:24

o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
o.Albedo *= IN.color.rgb;


так делать нельзя. Где написано о том, что читать из output структуры разрешено? Более того, на OpenGL в HLSL - прямо запрещено.

Вот так правильно:
Синтаксис:
Используется csharp
float4 colr=tex2D (_MainTex, IN.uv_MainTex);
o.Albedo =colr.rgb*IN.color.rgb;


не подскажите как получить исходный цвет текстуры?


Что такое исходный цвет тектстуры? Какая текстура во фрагментном шейдере? Только цвет текселя: tex2D (_MainTex, IN.uv_MainTex) - не оно?
Разработчик theFisherOnline - там, где клюёт
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Аватара пользователя
Woolf
Адепт
 
Сообщения: 7179
Зарегистрирован: 02 мар 2009, 16:59

Re: Реагировать на освещение.

Сообщение mrcoder 02 ноя 2012, 19:50

Woolf писал(а):
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
o.Albedo *= IN.color.rgb;

так делать нельзя. Где написано о том, что читать из output структуры разрешено? Более того, на OpenGL в HLSL - прямо запрещено.


вульф спасибо!
как чуял мой мозг что так делать не стоит... у себя я сразу написал
fixed4 colorxx = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = (colorxx.rgb/2) * (IN.color.rgb*2);
хм... я правда написал Fixed4 0_0, а не флоат... сейчас исправил на float4 от греха подальше.



Woolf писал(а):Что такое исходный цвет тектстуры? Какая текстура во фрагментном шейдере? Только цвет текселя: tex2D (_MainTex, IN.uv_MainTex) - не оно?

я очень выразился абстрактно. видимо речь о текселе и идет.
простыми словами - нужно получить цвет(любого участка мира), который еще не прошел обработку светом Lamberta. и уже этот цвет подсветить ламбертом. так как в mesh.colors цвета вершин уже рассчитаны скриптом.

свет тут - это фонарик прикрепленный к камере игрока, он должен лишь освешать темные участки мира, уже освешенного скриптами через цвета вершин.
сейчас же, вдали темень и только вокруг камеры игрока(источника света) осветляется единичным точечным светом.
Аватара пользователя
mrcoder
Старожил
 
Сообщения: 704
Зарегистрирован: 28 июн 2012, 22:40

Re: Реагировать на освещение.

Сообщение Battle Angel Alita 02 ноя 2012, 21:39

Woolf
не умничай, мало того что SurfaceOutput промежуточная структура, так она ещё компилится в ShaderLab а потом компилится в hlsl/glsl

mrcoder
чтоб не учитывать освещение надо или делать свою функцию расчёта света или писать в o.Emission
Мозг рака
Изображение
Аватара пользователя
Battle Angel Alita
UNIверсал
 
Сообщения: 476
Зарегистрирован: 25 ноя 2009, 14:52

Re: Реагировать на освещение.

Сообщение mrcoder 02 ноя 2012, 23:12

Battle Angel Alita писал(а):mrcoder
делать свою функцию расчёта света

через это?

half4 LightingWrapLambert (SurfaceOutput s, half3 lightDir, half atten)
{
}



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

даже не знаю как тут быть. :(
надо как то не прибавлять c.rgb = s.Albedo/2 + _LightColor0.rgb * (diff * atten * 2); , а умножать хитро что бы контрастность не терялась.
но умножение при отдалении будет погружать мир в далеке в полный мрак.

Shader "Custom/DynLightForTerr" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
}
SubShader {
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf WrapLambert vertex:vert

half4 LightingWrapLambert (SurfaceOutput s, half3 lightDir, half atten)
{
half NdotL = dot (s.Normal, lightDir);
half diff = NdotL ;
half4 c;
c.rgb = s.Albedo/2 + _LightColor0.rgb * (diff * atten * 2);
c.a = s.Alpha;
return c;
}

struct Input {
float2 uv_MainTex;
fixed4 color;
};
void vert (inout appdata_full v, out Input o) {
o.color = v.color;
}
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o) {
float4 colorxx = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = colorxx.rgb * IN.color.rgb;
clip(colorxx.a-0.8f);
}
ENDCG
}
Fallback "Diffuse"
}
У вас нет доступа для просмотра вложений в этом сообщении.
Аватара пользователя
mrcoder
Старожил
 
Сообщения: 704
Зарегистрирован: 28 июн 2012, 22:40


Вернуться в Shader Lab

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

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