forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Эффекты/Шейдеры (http://forum.boolean.name/forumdisplay.php?f=170)
-   -   Шейдер имитации водной поверхности на 2d изображении (http://forum.boolean.name/showthread.php?t=15526)

pax 22.09.2011 18:35

Шейдер имитации водной поверхности на 2d изображении
 
На днях по баловался с синусами и косинусами, вот чего получилось
PHP код:

Shader "Custom/2dRipples" {
    
Properties {
        
_Color ("Text Color"Color) = (1,1,1,1
        
_MainTex ("Base (RGB)"2D) = "white" { }
        
_MaskTex ("Mask"2D) = "white" { }
        
_VericalSpeed ("Verical Speed"Range(0,10)) = 1
        _HorisontalSpeed 
("Horisontal Speed"Range(0,10)) = 1

        _VericalPeriod 
("Verical Period"Range(1,20)) = 1
        _HorisontalPeriod 
("Horisontal Period"Range(1,20)) = 1

        _VericalAmplitude 
("Verical Amplitude"Range(0,1)) = 0.5
        _HorisontalAmplitude 
("Horisontal Amplitude"Range(0,1)) = 0.5
    
}

        
SubShader {
        
Tags {
            
"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
        
Lighting Off Cull Off ZWrite Off Fog Mode Off }

        
Pass {
            
CGPROGRAM
            
#pragma vertex vert
            #pragma fragment frag
            #pragma fragmentoption ARB_precision_hint_fastest

            #include "UnityCG.cginc"

            
struct appdata_t {
                
float4 vertex POSITION;
                
float2 texcoord TEXCOORD0;
            };
            
struct v2f {
                
float4 vertex POSITION;
                
float2 texcoord TEXCOORD0;
            };

            
sampler2D _MainTex;
            
sampler2D _MaskTex;
            
uniform float4 _MainTex_ST;
            
uniform fixed4 _Color;
            
float _VericalSpeed;
            
float _HorisontalSpeed;

            
float _VericalPeriod;
            
float _HorisontalPeriod;

            
float _VericalAmplitude;
            
float _HorisontalAmplitude;

            
v2f vert (appdata_t v)
            {
                
v2f o;
                
o.vertex mul(UNITY_MATRIX_MVPv.vertex);
                
o.texcoord TRANSFORM_TEX(v.texcoord_MainTex);
                return 
o;
            }


            
fixed4 frag (v2f i) : COLOR
            
{
                
fixed2 uv i.texcoord;
                
fixed4 mask tex2D (_MaskTexi.texcoord);
                
uv.+= (mask.500) * sin(_Time._HorisontalSpeed 
                           
sin(uv._HorisontalPeriod)/_HorisontalAmplitude);
                
uv.+= (mask.500) * cos(_Time._VericalSpeed 
                           
sin(uv._VericalPeriod) * _VericalAmplitude);

                
fixed4 c tex2D (_MainTexuv) * _Color;
                return 
c;
            }

            
ENDCG 
        
}
    } 

    
FallBack Off


Пример работы:
http://shgames.ru/f/

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

Вторая текстура - маска, яркость которой используется для указания максимального отклонения от исходного uv на текстуре.

PS: Если у кого есть ссылки на подобные примеры (CG, HLSL, GLSL ) - поделитесь пожалуйста!

Mr_F_ 22.09.2011 18:50

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
а видео нет?

pax 22.09.2011 18:52

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Нет, да там ничего особенного, просто место на фотографии, где вода, немного колышется.

PS: лень установить UnityPlayer? )

Mr_F_ 22.09.2011 19:02

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Цитата:

PS: лень установить UnityPlayer? )
угу.

pax 22.09.2011 19:10

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Надо будет потом попробовать реализовать вот такой алгоритм
http://freespace.virgin.net/hugo.eli...cs/x_water.htm

.Squid 22.09.2011 21:54

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Что-то не очень.
Можно попробовать использовать не монохромную маску. Ну, на самом деле я не знаю ее разрядность, но имею виду, что она будет градиентной и показывать силу искажения. Тогда можно для этой же горной реки вблизи сделать более сильные искажения, чем вдали.
Ну и чисто тригонометрическими функциями добиться красивого эффекта вряд ли удастся, шум не помешал бы. Или более сложную функцию.
В блоке Pass просто кусок CG-шейдера, он не Unity-specific? Т.е. точно такой же код можно использовать в другом движке, поддерживающем CG? vert и frag - это зарезервированные имена? Там нет техник, как в HLSL?

pax 22.09.2011 22:14

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Цитата:

Сообщение от .Squid (Сообщение 203125)
В блоке Pass просто кусок CG-шейдера, он не Unity-specific? Т.е. точно такой же код можно использовать в другом движке, поддерживающем CG? vert и frag - это зарезервированные имена? Там нет техник, как в HLSL?

Это не новая технология шейдеров да, в данном случае Pass и есть "техника". Несколько пассов - несколько "техник". В директивах указывается, какая функция является вершинной, какая фрагментной ( #pragma vertex vert и #pragma fragment frag). На основе этих директив собирается шейдер.

Вот такая хренатень генерируется:
PHP код:

Shader "Custom/2dRipples" {
    
Properties {
        
_Color ("Text Color"Color) = (1,1,1,1
        
_MainTex ("Base (RGB)"2D) = "white" { }
        
_MaskTex ("Base (RGB)"2D) = "white" { }
        
_VericalSpeed ("Verical Speed"Range(0,10)) = 1
        _HorisontalSpeed 
("Horisontal Speed"Range(0,10)) = 1

        _VericalPeriod 
("Verical Period"Range(1,20)) = 1
        _HorisontalPeriod 
("Horisontal Period"Range(1,20)) = 1

        _VericalAmplitude 
("Verical Amplitude"Range(0,1)) = 0.5
        _HorisontalAmplitude 
("Horisontal Amplitude"Range(0,1)) = 0.5
    
}

        
SubShader {
        
Tags {
            
"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
        
Lighting Off Cull Off ZWrite Off Fog Mode Off }

        
Pass {
            
Program "vp" {
// Vertex combos: 1
//   opengl - ALU: 5 to 5
//   d3d9 - ALU: 5 to 5
SubProgram "opengl " {
Keywords { }
Bind "vertex" Vertex
Bind 
"texcoord" TexCoord0
Vector 5 
[_MainTex_ST]
"!!ARBvp1.0
# 5 ALU
PARAM c[6] = { program.local[0],
        state.matrix.mvp,
        program.local[5] };
MAD result.texcoord[0].xy, vertex.texcoord[0], c[5], c[5].zwzw;
DP4 result.position.w, vertex.position, c[4];
DP4 result.position.z, vertex.position, c[3];
DP4 result.position.y, vertex.position, c[2];
DP4 result.position.x, vertex.position, c[1];
END
# 5 instructions, 0 R-regs
"
}

SubProgram "d3d9 " {
Keywords { }
Bind "vertex" Vertex
Bind 
"texcoord" TexCoord0
Matrix 0 
[glstate_matrix_mvp]
Vector 4 [_MainTex_ST]
"vs_2_0
; 5 ALU
dcl_position0 v0
dcl_texcoord0 v1
mad oT0.xy, v1, c4, c4.zwzw
dp4 oPos.w, v0, c3
dp4 oPos.z, v0, c2
dp4 oPos.y, v0, c1
dp4 oPos.x, v0, c0
"
}

SubProgram "gles " {
Keywords { }
"!!GLES
#define SHADER_API_GLES 1
#define tex2D texture2D


#ifdef VERTEX
#define gl_ModelViewProjectionMatrix glstate_matrix_mvp
uniform mat4 glstate_matrix_mvp;

varying highp vec2 xlv_TEXCOORD0;

uniform highp vec4 _MainTex_ST;
attribute vec4 _glesMultiTexCoord0;
attribute vec4 _glesVertex;
void main ()
{
  gl_Position = (gl_ModelViewProjectionMatrix * _glesVertex);
  xlv_TEXCOORD0 = ((_glesMultiTexCoord0.xy * _MainTex_ST.xy) + _MainTex_ST.zw);
}



#endif
#ifdef FRAGMENT

varying highp vec2 xlv_TEXCOORD0;
uniform highp float _VericalSpeed;
uniform highp float _VericalPeriod;
uniform highp float _VericalAmplitude;
uniform highp vec4 _Time;
uniform sampler2D _MaskTex;
uniform sampler2D _MainTex;
uniform highp float _HorisontalSpeed;
uniform highp float _HorisontalPeriod;
uniform highp float _HorisontalAmplitude;
uniform lowp vec4 _Color;
void main ()
{
  lowp vec2 uv;
  uv = xlv_TEXCOORD0;
  lowp vec4 tmpvar_1;
  tmpvar_1 = texture2D (_MaskTex, xlv_TEXCOORD0);
  highp float tmpvar_2;
  tmpvar_2 = (uv.x + ((tmpvar_1.x / 500.0) * sin (((_Time.y * _HorisontalSpeed) + (sin ((uv.y * _HorisontalPeriod)) / _HorisontalAmplitude)))));
  uv.x = tmpvar_2;
  highp float tmpvar_3;
  tmpvar_3 = (uv.y + ((tmpvar_1.x / 500.0) * cos (((_Time.y * _VericalSpeed) + (sin ((uv.x * _VericalPeriod)) * _VericalAmplitude)))));
  uv.y = tmpvar_3;
  gl_FragData[0] = (texture2D (_MainTex, uv) * _Color);
}



#endif"
}

SubProgram "glesdesktop " {
Keywords { }
"!!GLES
#define SHADER_API_GLES 1
#define tex2D texture2D


#ifdef VERTEX
#define gl_ModelViewProjectionMatrix glstate_matrix_mvp
uniform mat4 glstate_matrix_mvp;

varying highp vec2 xlv_TEXCOORD0;

uniform highp vec4 _MainTex_ST;
attribute vec4 _glesMultiTexCoord0;
attribute vec4 _glesVertex;
void main ()
{
  gl_Position = (gl_ModelViewProjectionMatrix * _glesVertex);
  xlv_TEXCOORD0 = ((_glesMultiTexCoord0.xy * _MainTex_ST.xy) + _MainTex_ST.zw);
}



#endif
#ifdef FRAGMENT

varying highp vec2 xlv_TEXCOORD0;
uniform highp float _VericalSpeed;
uniform highp float _VericalPeriod;
uniform highp float _VericalAmplitude;
uniform highp vec4 _Time;
uniform sampler2D _MaskTex;
uniform sampler2D _MainTex;
uniform highp float _HorisontalSpeed;
uniform highp float _HorisontalPeriod;
uniform highp float _HorisontalAmplitude;
uniform lowp vec4 _Color;
void main ()
{
  lowp vec2 uv;
  uv = xlv_TEXCOORD0;
  lowp vec4 tmpvar_1;
  tmpvar_1 = texture2D (_MaskTex, xlv_TEXCOORD0);
  highp float tmpvar_2;
  tmpvar_2 = (uv.x + ((tmpvar_1.x / 500.0) * sin (((_Time.y * _HorisontalSpeed) + (sin ((uv.y * _HorisontalPeriod)) / _HorisontalAmplitude)))));
  uv.x = tmpvar_2;
  highp float tmpvar_3;
  tmpvar_3 = (uv.y + ((tmpvar_1.x / 500.0) * cos (((_Time.y * _VericalSpeed) + (sin ((uv.x * _VericalPeriod)) * _VericalAmplitude)))));
  uv.y = tmpvar_3;
  gl_FragData[0] = (texture2D (_MainTex, uv) * _Color);
}



#endif"
}

}
Program "fp" {
// Fragment combos: 1
//   opengl - ALU: 21 to 21, TEX: 2 to 2
//   d3d9 - ALU: 60 to 60, TEX: 2 to 2
SubProgram "opengl " {
Keywords { }
Vector 0 [_Time]
Vector 1 [_Color]
Float 2 [_VericalSpeed]
Float 3 [_HorisontalSpeed]
Float 4 [_VericalPeriod]
Float 5 [_HorisontalPeriod]
Float 6 [_VericalAmplitude]
Float 7 [_HorisontalAmplitude]
SetTexture 0 [_MaskTex2D
SetTexture 1 
[_MainTex2D
"!!ARBfp1.0
OPTION ARB_precision_hint_fastest;
# 21 ALU, 2 TEX
PARAM c[9] = { program.local[0..7],
        { 0.0020000001 } };
TEMP R0;
TEX R0.x, fragment.texcoord[0], texture[0], 2D;
MUL R0.y, fragment.texcoord[0], c[5].x;
SIN R0.y, R0.y;
RCP R0.z, c[7].x;
MUL R0.z, R0.y, R0;
MOV R0.y, c[3].x;
MAD R0.y, R0, c[0], R0.z;
MUL R0.x, R0, c[8];
SIN R0.y, R0.y;
MUL R0.y, R0.x, R0;
ADD R0.z, fragment.texcoord[0].x, R0.y;
MUL R0.y, R0.z, c[4].x;
SIN R0.y, R0.y;
MUL R0.w, R0.y, c[6].x;
MOV R0.y, c[2].x;
MAD R0.y, R0, c[0], R0.w;
COS R0.y, R0.y;
MUL R0.x, R0.y, R0;
ADD R0.w, fragment.texcoord[0].y, R0.x;
TEX R0, R0.zwzw, texture[1], 2D;
MUL result.color, R0, c[1];
END
# 21 instructions, 1 R-regs
"
}

SubProgram "d3d9 " {
Keywords { }
Vector 0 [_Time]
Vector 1 [_Color]
Float 2 [_VericalSpeed]
Float 3 [_HorisontalSpeed]
Float 4 [_VericalPeriod]
Float 5 [_HorisontalPeriod]
Float 6 [_VericalAmplitude]
Float 7 [_HorisontalAmplitude]
SetTexture 0 [_MaskTex2D
SetTexture 1 
[_MainTex2D
"ps_2_0
; 60 ALU, 2 TEX
dcl_2d s0
dcl_2d s1
def c8, -0.02083333, -0.12500000, 1.00000000, 0.50000000
def c9, -0.00000155, -0.00002170, 0.00260417, 0.00026042
def c10, 0.00200000, 0.15915491, 0.50000000, 0
def c11, 6.28318501, -3.14159298, 0, 0
dcl t0.xy
texld r2, t0, s0
mul r0.x, t0.y, c5
mad r0.x, r0, c10.y, c10.z
frc r0.x, r0
mad r0.x, r0, c11, c11.y
sincos r1.xy, r0.x, c9.xyzw, c8.xyzw
rcp r0.x, c7.x
mul r0.x, r1.y, r0
mov r0.y, c0
mad r0.x, c3, r0.y, r0
mad r0.x, r0, c10.y, c10.z
frc r0.x, r0
mad r0.x, r0, c11, c11.y
sincos r1.xy, r0.x, c9.xyzw, c8.xyzw
mul_pp r0.x, r2, c10
mul r1.x, r0, r1.y
add_pp r3.x, t0, r1
mul r1.x, r3, c4
mad r1.x, r1, c10.y, c10.z
frc r1.x, r1
mad r1.x, r1, c11, c11.y
sincos r2.xy, r1.x, c9.xyzw, c8.xyzw
mul r1.x, r2.y, c6
mov r0.y, c0
mad r1.x, c2, r0.y, r1
mad r1.x, r1, c10.y, c10.z
frc r1.x, r1
mad r1.x, r1, c11, c11.y
sincos r2.xy, r1.x, c9.xyzw, c8.xyzw
mul r0.x, r2, r0
add_pp r3.y, t0, r0.x
texld r0, r3, s1
mul r0, r0, c1
mov_pp oC0, r0
"
}

SubProgram "gles " {
Keywords { }
"!!GLES"
}

SubProgram "glesdesktop " {
Keywords { }
"!!GLES"
}

}

#LINE 73
 
        
}
    } 

    
FallBack Off



.Squid 23.09.2011 00:19

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
B HLSL вершинный и фрагментный шейдеры определяются снаружи техники, поэтому несколько техник могут использовать одинаковые шейдеры. Тут не так, насколько я понимаю?

pax 23.09.2011 01:25

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Цитата:

Сообщение от .Squid (Сообщение 203164)
B HLSL вершинный и фрагментный шейдеры определяются снаружи техники, поэтому несколько техник могут использовать одинаковые шейдеры. Тут не так, насколько я понимаю?

Тут можно использовать общий инклуд на уровне выше Pass, в котором определить общие функции и в каждом пасе указать нужную функцию через директивы. Возможно не один шейдер с несколькими пасами будет в результате, не вдавался в подробности. Но принцип похожий.

что-то типа:
PHP код:

Shader "Custom/NewShader" {
    
Properties {
        
_Color ("Text Color"Color) = (1,1,1,1
        
_MainTex ("Base (RGB)"2D) = "white" { }
        
_MaskTex ("Mask"2D) = "white" { }
        
_VericalSpeed ("Verical Speed"Range(0,10)) = 1
        _HorisontalSpeed 
("Horisontal Speed"Range(0,10)) = 1

        _VericalPeriod 
("Verical Period"Range(1,20)) = 1
        _HorisontalPeriod 
("Horisontal Period"Range(1,20)) = 1

        _VericalAmplitude 
("Verical Amplitude"Range(0,1)) = 0.5
        _HorisontalAmplitude 
("Horisontal Amplitude"Range(0,1)) = 0.5
    
}

        
SubShader {
        
Tags {
            
"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
        
Lighting Off Cull Off ZWrite Off Fog Mode Off }
        
CGINCLUDE
            
#include "UnityCG.cginc"

            
struct appdata_t {
                
float4 vertex POSITION;
                
float2 texcoord TEXCOORD0;
            };
            
struct v2f {
                
float4 vertex POSITION;
                
float2 texcoord TEXCOORD0;
            };

            
sampler2D _MainTex;
            
sampler2D _MaskTex;
            
uniform float4 _MainTex_ST;
            
uniform fixed4 _Color;
            
float _VericalSpeed;
            
float _HorisontalSpeed;

            
float _VericalPeriod;
            
float _HorisontalPeriod;

            
float _VericalAmplitude;
            
float _HorisontalAmplitude;

            
v2f vert (appdata_t v)
            {
                
v2f o;
                
o.vertex mul(UNITY_MATRIX_MVPv.vertex);
                
o.texcoord TRANSFORM_TEX(v.texcoord_MainTex);
                return 
o;
            }
        
ENDCG

       Pass 
{
            
CGPROGRAM
            
#pragma vertex vert
            #pragma fragment frag
            #pragma fragmentoption ARB_precision_hint_fastest


            
fixed4 frag (v2f i) : COLOR
            
{
                
fixed2 uv i.texcoord;
                
fixed4 mask tex2D (_MaskTexi.texcoord);
                
uv.+= (mask.500) * sin(_Time._HorisontalSpeed 
                           
sin(uv._HorisontalPeriod)/_HorisontalAmplitude);
                
uv.+= (mask.500) * cos(_Time._VericalSpeed 
                           
sin(uv._VericalPeriod) * _VericalAmplitude);

                
fixed4 c tex2D (_MainTexuv) * _Color;
                return 
c;
            }

            
ENDCG 
        
}

        
Pass {

            
Blend SrcAlpha OneMinusSrcAlpha 

            CGPROGRAM
            
#pragma vertex vert
            #pragma fragment frag
            #pragma fragmentoption ARB_precision_hint_fastest

            
fixed4 frag (v2f i) : COLOR
            
{
                
fixed4 c tex2D (_MainTex,  i.texcoord) * _Color;
                
c.0.25;
                return 
c;
            }

            
ENDCG 
        
}

    } 

    
FallBack Off


тут #pragma vertex vert указывает на общую функцию

.Squid 23.09.2011 02:13

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Ясно, спасибо. Хоть и понятно, но выглядит страшненько. Вероятно, просто дело привычки.

pax 23.09.2011 10:25

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Нашел в игре Atom Fishing шейдер как раз похожий, тоже на синусах/косинусах :-D , он в игре всего один оказался.
Сегодня вечером переведу на Unity, посмотрим. Тоже двухтекстурный, вторая тоже градиентная, как и я делал. Только жаль что ресурсы локаций в игре в своем формате, не подглядеть как у них эта градиентная текстура сделана.

Reizel 23.09.2011 19:18

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Цитата:

Сообщение от pax (Сообщение 203103)
Надо будет потом попробовать реализовать вот такой алгоритм
http://freespace.virgin.net/hugo.eli...cs/x_water.htm

Да это же Лапласова вода) у меня в генераторе такая юзается.
ПС статья

IGR 24.09.2011 11:44

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
Цитата:

"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"
а где можно подсмотреть список возможных тегов и их значений ??

Lestar 24.09.2011 11:58

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
http://unity3d.com/support/documenta...Reference.html

pax 10.10.2011 16:44

Ответ: Шейдер имитации водной поверхности на 2d изображении
 
В демке теперь есть дождик :)
http://shgames.ru/f/


Часовой пояс GMT +4, время: 15:06.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot