Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Center UV co-ordinates, GLSL > CG/HLSL

Discussion in 'Shaders' started by Richop, Jan 20, 2017.

  1. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Hi,

    Been messing around with shaders for a little while now, trying to understand the language and getting used to different errors.

    I have successfully ported a few simple shaderToy shaders into Unity, but I have a problem in centering the UV co-ordinates, the results I get are usually a quarter of the shader. Screen Shot 2017-01-20 at 21.11.55.png

    Code (CSharp):
    1. float time = _Time.y * 1.;                                                // adjust time
    2.             //float2 fragCoord =
    3.             //float2 p = (-_ScreenParams.xy + 2.0*fragCoord)/_ScreenParams.x;        // center coordinates
    4.             i.uv.y = 1-i.uv.y;
    5.             float2 p = i.uv;
    I think it's because I'm just feeding i.uv, and not calculating the double and center bit.

    Here's the whole code to a 1/4 of a shader, it's all good if you've got four quads, but not the best solution!

    If anyone could point me in the right direction to help center this shader, I would be very appreciative!

    Code (CSharp):
    1. Shader "Paintings/Base"{
    2.     Properties{
    3.     _MainTex ("Texture", 2D) = "white" {}
    4.     }
    5.     SubShader{
    6.  
    7.         Pass{
    8.             CGPROGRAM
    9.             #pragma vertex vert
    10.             #pragma fragment frag
    11.             #pragma target 3.0
    12.             #include "UnityCG.cginc"
    13.  
    14.             struct appdata{
    15.                 float4 vertex : POSITION;
    16.                 float2 uv : TEXCOORD0;
    17.             };
    18.  
    19.             struct v2f{
    20.                 float2 uv : TEXCOORD0;
    21.                 float4 vertex : SV_POSITION;
    22.                 float4 screenCoord : TEXCOORD1;
    23.             };
    24.  
    25.             v2f vert (appdata v){
    26.                 v2f o;
    27.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    28.                 o.uv = v.uv;
    29.                 o.screenCoord.xy = ComputeScreenPos(o.vertex);
    30.                 return o;
    31.             }
    32.  
    33.             //sampler2D _MainTex;
    34.  
    35.             fixed4 frag (v2f i) : SV_Target
    36.             {
    37.             float time = _Time.y * 1.;                                                // adjust time
    38.             //float2 fragCoord =
    39.             //float2 p = (-_ScreenParams.xy + 2.0*fragCoord)/_ScreenParams.x;        // center coordinates
    40.             i.uv.y = 1-i.uv.y;
    41.             float2 p = i.uv;
    42.             ////////////////////////////////////
    43.             // deform technique from iq: https://www.shadertoy.com/view/Xdf3Rn
    44.             float r2 = dot(p,p);
    45.                float r = sqrt(r2);
    46.                float2 uv = p/r2;  
    47.             // animate  
    48.             uv += 10.0 * cos( float2(0.6,0.3) + float2(0.1,0.13) * 2. * sin(time) );
    49.             // uv = p; // switch back to normal coords to test drawing
    50.             ////////////////////////////////////
    51.    
    52.             // custom drawing
    53.             uv += float2(0., 2. * cos(uv.y * 8.));                                    // warp coordinates a little more
    54.             uv = abs(sin(uv * 0.3));                                                // draw horizontal stripes
    55.             float color = smoothstep(0.2, 0.8, abs(sin(time + uv.y * 3.)));
    56.             color = min(color, smoothstep(0.1, 0.95, abs(sin(time + uv.y * 4.))) );
    57.             color += 0.75;                                                            // brighten everything
    58.             float3 col = float3(                                                    // oscillate color components
    59.                 0.6 + 0.1 * cos(time + color * 1.),
    60.                 0.5 * color,
    61.                 0.9 + 0.2 * sin(time + color * 1.1)
    62.             );
    63.             // reverse vignette
    64.             col *= r*1.5 * color;
    65.                col += pow(length(p)/2., 2.);
    66.             return float4( col, 1.0 );
    67.    
    68.             }
    69.             ENDCG
    70.         }
    71.     }
    72. }
    73.  
    and the original shader:

    https://www.shadertoy.com/view/4lGXzG
     
  2. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Code (CSharp):
    1. float2 p = (2 * i.uv) - 1 / 1;
    Don't understand it, but seems to work. Took out reference to screen positions, doubled and divided, by a number that's the same to get the middle.
     
  3. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    This shader still doesn't like me with that trick, by the time the kaliedoscope rotates around, the picture goes out of sync, looks like the shader is manipulating the wrong parts of the picture.

    Code (CSharp):
    1. Shader "Paintings/FreeBase2"{
    2.     //Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    3.     Properties
    4.     {
    5.     //_MainTex ("Texture", 2D) = "white" {}
    6.     _Color ("Color", Color) = (1,1,1,1)
    7.     _Blend ("Blend", Range (0, 1) ) = 0
    8.     //_MainTex ("Texture 1", 2D) = ""
    9.     _MainTex ("Color (RGB) Alpha (A)", 2D) = "white"
    10.     _Texture2 ("Color (RGB) Alpha (A)", 2D) = "white"
    11.     //_Texture2 ("Texture 2", 2D) = ""
    12.     _SrcBlend ("_SrcBlend", Float) = 1
    13. //    _DstBlend ("_DstBlend", Float) = 0
    14.     }
    15.  
    16.  
    17.  
    18.     SubShader{
    19.         Tags {"RenderType"="Transparent"  "Queue"="Transparent" }
    20.         Blend SrcAlpha OneMinusSrcAlpha
    21.         Pass{
    22.  
    23.             CGPROGRAM
    24.             #pragma vertex vert
    25.             #pragma fragment frag
    26.             #pragma shader_feature _ _RENDERING_CUTOUT _RENDERING_FADE
    27. //            Tags {
    28. //                "LightMode" = "ForwardBase"
    29. //            }
    30.             //Blend [_SrcBlend] [_DstBlend]
    31.  
    32.  
    33.            
    34.             #include "UnityCG.cginc"
    35.  
    36.  
    37.             struct appdata
    38.             {
    39.                 float4 vertex : POSITION;
    40.                 fixed4 color : COLOR;
    41.                 float2 uv : TEXCOORD0;
    42.             };
    43.  
    44.             struct v2f
    45.             {
    46.                 float2 uv : TEXCOORD0;
    47.                 float4 vertex : SV_POSITION;
    48.                 fixed4 color : COLOR;
    49.                 float4 screenCoord : TEXCOORD1;
    50.             };
    51.  
    52. //            struct Input {
    53. //             float2 uv_MainTex;
    54. //             };
    55.              uniform float4 _Color;
    56.             v2f vert (appdata v)
    57.             {
    58.                 v2f o;
    59.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    60.                 o.color = v.color;
    61.                 //o.Alpha = _Color.a;
    62.                 o.uv = v.uv;
    63.                 //o.screenCoord.xy = ComputeScreenPos(o.vertex);
    64.                 return o;
    65.             }
    66.  
    67.             sampler2D _MainTex;
    68.             sampler2D _Texture2;
    69.             float _Blend;
    70.  
    71. //              void surf (Input IN)
    72. //              {
    73. //             fixed4 mainCol = tex2D(_MainTex, IN.uv_MainTex);
    74. //              fixed4 texTwoCol = tex2D(_Texture2, IN.uv_MainTex);
    75. //              fixed4 output = lerp(mainCol, texTwoCol, _Blend);
    76. //              o.Albedo = output.rgb;
    77. //              o.Alpha = output.a;
    78. //             }
    79.  
    80.            
    81.             fixed4 frag (v2f i) : SV_Target
    82.             {
    83.                 const float PI = 3.141592658;
    84.                 //const float TAU = 2.0 * PI;
    85.                 const float TAU = 2.0 * PI;
    86.                 const float sections = 8.0;
    87.                 //{
    88.                   //float2 pos = float2(i.screenCoord.xy - 0.5 * _ScreenParams.xy) / _ScreenParams.y;
    89.                   //float2 pos = i.uv;
    90.                   //float2 pos = (2 * i.uv) - 1 / 1;
    91.                   //float2 pos = 2 * i.uv - 1 / float2(1,1);
    92.                   //float2 pos = (2 * i.uv) - 4 / 4;
    93.                   float2 pos = float2(i.uv.xy / 1 -.5)*2.;
    94.                   float rad = length(pos);
    95.                   float angle = atan2(pos.x, pos.y);
    96.  
    97.                   float ma = fmod(angle, TAU/sections);
    98.                   ma = abs(ma - PI/sections);
    99.  
    100.                   float x = cos(ma) * rad;
    101.                   float y = sin(ma) * rad;
    102.    
    103.                   float time = _Time.y/10.0;
    104.                   fixed4 oricol = tex2D (_MainTex,float2(x+time, y-time)).a;
    105.                    fixed4 col = tex2D (_Texture2,float2(x+time, y-time)).a;
    106.                    float comp = smoothstep( 0.1, 0.9, sin(0.5) );
    107.                    col = lerp(col,oricol, _Blend);
    108.                    //return float4(col);
    109.                   return float4(col) * _Color;
    110.                   //tex2D(_MainTex, float2(x+time, y-time));
    111.  
    112.             }
    113.  
    114.  
    115.             ENDCG
    116.         }
    117.     }
    118. }
    119.  
     

    Attached Files:

  4. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Screen Shot 2017-01-20 at 22.47.14.png

    Different code same skewed effect, that's still not quite right, is there something wrong with part of the maths?

    Code (CSharp):
    1. Shader "ShaderToy/NewShader3"{
    2.     Properties
    3.     {
    4.         _MainTex ("Texture", 2D) = "white" {}
    5.     }
    6.     SubShader{
    7.  
    8.         Pass{
    9.             CGPROGRAM
    10.             #pragma vertex vert
    11.             #pragma fragment frag
    12.            
    13.             #include "UnityCG.cginc"
    14.  
    15.             struct appdata{
    16.                 float4 vertex : POSITION;
    17.                 float2 uv : TEXCOORD0;
    18.             };
    19.  
    20.             struct v2f{
    21.                 float2 uv : TEXCOORD0;
    22.                 float4 vertex : SV_POSITION;
    23.                 float4 screenCoord : TEXCOORD1;
    24.             };
    25.  
    26.             v2f vert (appdata v){
    27.                 v2f o;
    28.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    29.                 o.uv = v.uv;
    30.                 o.screenCoord.xy = ComputeScreenPos(o.vertex);
    31.                 return o;
    32.             }
    33.  
    34.             sampler2D _MainTex;
    35.  
    36.        
    37.            
    38.             fixed4 frag (v2f i) : SV_Target
    39.             {
    40.  
    41.             const float PI = 3.141592658;
    42.             const float TAU = 2.0 * PI;
    43.             const float sections = 10.0;
    44.  
    45.               float2 pos = (i.uv*2)-2 / 2;
    46.  
    47.               float rad = length(pos);
    48.               float angle = atan2(pos.y, pos.x);
    49.  
    50.               float ma = fmod(angle, TAU/sections);
    51.               ma = abs(ma - PI/sections);
    52.  
    53.               float x = cos(ma) * rad;
    54.               float y = sin(ma) * rad;
    55.    
    56.               float time = _Time.y/10.0;
    57.  
    58.               return tex2D(_MainTex, float2(x-time, y-time));
    59.             }
    60.                
    61.             ENDCG
    62.         }
    63.     }
    64. }
    65.  
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    The commented out line you have from the original shadertoy shader:
    float2 p = (-_ScreenParams.xy + 2.0*fragCoord)/_ScreenParams.x;

    In shadertoy the fragCoord is the screen pixel coordinate, so that code converts the pixel coordinate to a -1 to 1 range along the x with a square aspect.

    The UVs for a basic quad are from 0.0 to 1.0 in both x and y, so you just need to do this:
    float2 p = i.uv * 2.0 - 1.0;

    That results in the same -1 to 1 range as the original shader is expecting.
     
    PrimalCoder and Richop like this.
  6. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    So screenParams is a constant value, fragCoord is the screen pixel coordinate, equivalent to the uv on a plane/quad, I have another bit from a shadertoy, that states screenCoord, would you treat it differently to uv, I tried:

    Code (CSharp):
    1. float2 pos = float2(i.screenCoord.xy - 0.5 * _ScreenParams.xy) / _ScreenParams.y;
    2. // becomes
    3. float2 pos = float2(i.uv.xy - 0.5 * 1) / 1;
    4.  
    I'm not sure if it's that part messing up the kaildoscope effect, I've attached the shader, instead of just the code...
    Screen Shot 2017-01-21 at 16.09.10.png
     

    Attached Files:

  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Note all of these lines are mathematically exactly same:
    (2 * uv) - 1 / 1
    (uv * 2) - 2 / 2
    (uv - 0.5 / 1) * 2

    They all result in:
    uv * 2 - 1

    If the uv range is 0.0 to 1.0 all of those bits of math will change it to -1.0 to 1.0

    However this line is different
    (uv - 0.5 * 1) / 1

    The multiply and divide by one both do nothing, that line is exactly the same as:
    uv - 0.5

    Which means that 0.0 to 1.0 range is now a -0.5 to 0.5 range. The visual results are fairly similar since 0.0 is now centered, but the visual result is slightly "zoomed in" compared to the above options. This is all kind of basic PEMDAS. If you're having trouble here I would suggest spending some time refreshing yourself by going through a few Khan Academy courses on basic math, arithmetic, and algebra, because ultimately shaders are about lots and lots of math.

    So, again, the original ShaderToy shaders are all getting pixel positions as an input to the function. That means if the area on screen being rendered is 128x80 pixels the fragCoord range will be from 0 to 127 and 0 to 79, and iResolution is vec2(128, 80). In Unity the basic quad's UVs are from 0.0 to 1.0 for both x and y from one side of the quad to the other. The screen position you get from ComputeScreenPos() is also from 0.0 to 1.0, just from one edge of the area being rendered to the other, which is probably why when you were trying to use _ScreenParams.xy (which you figured out correctly is the equivalent of ShaderToy's iResolution.xy) you weren't getting the results you were expecting.

    Now as for what's happening with your kalidescope, I believe this is a subtle HLSL (what Unity uses) vs GLSL (what ShaderToy uses) difference. The fmod and mod functions are not the same! They're both "modulo" functions, and with positive numbers they produce identical results. The problem is with negative numbers HLSL's fmod will output a positive number where GLSL's mod will output a different negative number.

    Both are correct, just different. However the GLSL implementation is usually what people actually want. There's two solutions. One is to implement your own GLSL style "mod" function in your shader, which if you want you can search for online. The other is, in this case at least, add tau to the angle variable before using fmod. The output of atan2 is a -pie to pie range, so adding tau should get the same results out of the sin and cos functions.
     
    Richop likes this.
  8. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Yeah I apologise for the scribbles, my maniacal re-stating the exact same thing over and over! I'm in no way an academic, but love the some of the videos about Maths like khan academies on youtube, specifically the Hart's Vi/George have inspired me in unreasonably large quantities!

    Ahh thank you so much, you don't know how much of a legend you are! That's quite a subtle difference, I've even come across someone stating this exact same thing when searching around, about negative numbers in mod functions giving un-expected results. Thank you so much. I have no idea how you managed to work out that just add Tau bit, I think I may need to get on more of those Khan videos!!
     
  9. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    I'm sorry to bother, but I've tried writing the GLSL function of mod and am getting unexpected results..

    Is this what it is supposed to be:

    Code (CSharp):
    1.     float myMod(float x, float y)
    2.         {
    3.               return x - y * floor(x/y);
    4.         }  
    5.  
    I've tried on a shader, and get this:
    Screen Shot 2017-01-22 at 17.39.40.png

    Compared to with fmod:
    Screen Shot 2017-01-22 at 17.40.07.png
    Fmod is clearly doing half correct, and then getting messed up with repeating when numbers go in the negative range. But seems myMod is messing it up completely!?

    I'm not sure if the end result could be right, but the image is incorrect because I've commented out the rotation part, (because it didn't work) so I might have to change to individual functions, it didn't seem like such a contributing factor. Anyways here's the shader:

    Code (CSharp):
    1. Shader "Paintings/Base"{
    2.     Properties{
    3.         _MainTex ("Texture", 2D) = "white" {}
    4.     }
    5.     SubShader{
    6.  
    7.         Pass{
    8.             CGPROGRAM
    9.             #pragma vertex vert
    10.             #pragma fragment frag
    11.            
    12.             #include "UnityCG.cginc"
    13.  
    14.             struct appdata{
    15.                 float4 vertex : POSITION;
    16.                 float2 uv : TEXCOORD0;
    17.             };
    18.  
    19.             struct v2f{
    20.                 float2 uv : TEXCOORD0;
    21.                 float4 vertex : SV_POSITION;
    22.                 float4 screenCoord : TEXCOORD1;
    23.             };
    24.  
    25.             v2f vert (appdata v){
    26.                 v2f o;
    27.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    28.                 o.uv = v.uv;
    29.                 o.screenCoord.xy = ComputeScreenPos(o.vertex);
    30.                 return o;
    31.             }
    32.  
    33.             sampler2D _MainTex;
    34.  
    35.             float sdBox( float3 p, float3 b )
    36.             {
    37.               float3 d = abs(p) - b;
    38.               return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
    39.             }
    40.  
    41.         float sdCross(in float3 p)
    42.         {
    43.               float da = sdBox(p.xyz,float3(4.0,0.0,1.0));
    44.               float db = sdBox(p.yzx,float3(1.0,2.0,2.0));
    45.               float dc = sdBox(p.zxy,float3(0.5,1.0,sin(_Time.y*4.0)+2.5));
    46.               return min(da,min(db,dc));
    47.         }
    48.  
    49.         float realMod(float x, float y) { return x - y*float(int(x)/int(y)); }
    50.  
    51.         float myMod(float x, float y)
    52.         {
    53.               return x - y * floor(x/y);
    54.         }  
    55.  
    56.         float opRep(float3 p, float3 c) {
    57.             float3 q = fmod(p,c)-0.5*c;
    58.             return sdCross(q);
    59.         }
    60. //
    61. //            float opRep(float3 p, float3 c) {
    62. //            float3 q = fmod(p,c)-0.5*c;
    63. //            return sdCross(q);
    64. //        }
    65.  
    66.         float trace(float3 o, float3 r) {
    67.             float t = 0.0;
    68.             for (int i = 0; i < 32; i++) {
    69.                 float3 p = o + r * t;
    70.                 float d = opRep(p, float3(6.0, 6.0, 6.0));
    71.                 t += d * 1.0;
    72.             }
    73.             return t;
    74.         }
    75.  
    76.         float2x2 rotation(float theta)
    77.         {
    78.             return float2x2(cos(theta), -sin(theta), sin(theta), cos(theta));
    79.         }
    80.            
    81.             fixed4 frag (v2f i) : SV_Target
    82.             {
    83.  
    84.                 float2 uv = i.uv;
    85.                    uv = uv * 2.0 - 1.0;
    86.                     //uv.x *= 1 / 1;
    87.                 float3 r = normalize(float3(uv, 1.0));
    88.                 //r.xz *= rotation(sin(_Time.y) * 0.2);
    89.                 //r.xy *= rotation(cos(_Time.y) * 0.2);
    90.                 float3 o = float3(0.0, _Time.y, _Time.y * 10.0);
    91.                 float t = trace(o, r);
    92.                 float fog = 1.0 / (1.0 + t * t * 0.001);
    93.                 float3 fc = float3(1.0-fog,1-fog,1-fog);
    94.                 return float4(fc ,1.0);
    95.             }
    96.             ENDCG
    97.         }
    98.     }
    99. }
    100.  
     
  10. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Don't worry sorry I figured it out...

    Code (CSharp):
    1.     float3 myMod(float3 x, float3 y)
    2.         {
    3.               return x - y * floor(x/y);
    4.         }    
    C is weird.
     
  11. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    You can also do this:
    #define myMod(x, y) (x - y * floor(x / y))

    That's a macro definition rather than a function. That'll work equally with two floats or two float4 or anything in between. It'll even properly handle x being a vector and y being a float! No need to write multiple versions of the function to handle all cases!

    And yes, the lack of ; at the end of that define line is intentional. It means when you use it in code you just use it like you would a normal function either mid line or with a semi-colon afterward, otherwise it has to be used by itself and without a semi-colon after it.


    Note: the inverse of x as a float and y as a vector might also "work", as well as mixed vector sizes (like a float2 and float4), but it's not recommended as it'll be down to the shader compiler to decide how and if it works. If you wrote out multiple versions of the function for the different cases the same rules would apply.
     
  12. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Excellent, thank you very much, that has been working like a charm, that's a really handy tip to know!

    Just out of interest do you know if you can pass a value from the surf to the vert, or frag/vert? I've tried setting (I guess global) variables but can't seem to access them in any meaningful way... Screen Shot 2017-01-24 at 07.18.18.png
    That's what I've got to so far, and where i'm stuck at the moment, I have noise being made in the shader, and i'd like to pass an element from the color (_Col) value, like one of the r,g,b components to offset the verts on the y axis.

    Here's what I got:
    Code (CSharp):
    1. Shader "Custom/2 - Lit Vertex Displacement/Normals" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    5.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    6.         _Metallic ("Metallic", Range(0,1)) = 0.0
    7.  
    8.         _Speed("Speed",Range(0.1,4)) = 1
    9.         _Amount("Amount", Range(0.1,10)) = 3
    10.         _Displacement("Displacement", Range( 0, 20 )) = 9.3
    11.     }
    12.     SubShader {
    13.         Tags { "RenderType"="Opaque" }
    14.         LOD 200
    15.        
    16.         CGPROGRAM
    17.  
    18.         #pragma surface surf Standard fullforwardshadows vertex:vert addshadow
    19.  
    20.         #pragma target 3.0
    21.  
    22.         sampler2D _MainTex;
    23.  
    24.         struct Input {
    25.             float2 uv_MainTex;
    26.         };
    27.  
    28.         half _Glossiness;
    29.         half _Metallic;
    30.         fixed4 _Color;
    31.         uniform float3 _Col;
    32.         uniform float _Extract;
    33.         half _Speed;
    34.         half _Amount;
    35.         half _Displacement;
    36.                 const float2 m = float2( 0.80,  0.60 );
    37.  
    38.         float hash( float2 p )
    39.         {
    40.             float h = dot(p,float2(127.1,311.7));
    41.             return -1.0 + 2.0*frac(sin(h)*43758.5453123);
    42.         }
    43.  
    44.         float noise( in float2 p )
    45.         {
    46.             float2 i = floor( p );
    47.             float2 f = frac( p );
    48.            
    49.             float2 u = f*f*(3.0-2.0*f);
    50.  
    51.             return lerp( lerp( hash( i + float2(0.0,0.0) ),
    52.                              hash( i + float2(1.0,0.0) ), u.x),
    53.                         lerp( hash( i + float2(0.0,1.0) ),
    54.                              hash( i + float2(1.0,1.0) ), u.x), u.y);
    55.         }
    56.  
    57.         float fbm( float2 p )
    58.         {
    59.             float f = 0.0;
    60.             f += 0.5000*noise( p ); p = m*p*2.02;
    61.             f += 0.2500*noise( p ); p = m*p*2.03;
    62.             f += 0.1250*noise( p ); p = m*p*2.01;
    63.             f += 0.0625*noise( p );
    64.             return f/0.9375;
    65.         }
    66.  
    67.         float2 fbm2( in float2 p )
    68.         {
    69.             return float2( fbm(p.xy), fbm(p.yx) );
    70.         }
    71.  
    72.         float3 map( float2 p )
    73.         {  
    74.             p *= 2.9;
    75.  
    76.             float f = dot( fbm2( 1.0*(0.5*_Time.y + p + fbm2(-0.5*_Time.y+1.0*(p + fbm2(4.0*p)))) ), float2(1.0,-1.0) );
    77.  
    78.             float bl = smoothstep( -0.8, 0.8, f );
    79.  
    80.             float ti = smoothstep( -1.0, 1.0, fbm(p) );
    81.  
    82.             return lerp( lerp( float3(0.50,0.00,0.00),
    83.                              float3(1.00,0.5,0.35), ti ),
    84.                              float3(0.00,0.00,0.02), bl );
    85.         }
    86.         float3 makeMeNoise(float2 uv)
    87.         {
    88.                   float2 p =  4 * uv;
    89.                 float e = 0.0016;
    90.  
    91.                 float3 colc = map( p               ); float gc = dot(colc,float3(0.333, 0.333, 0.333));
    92.                 float3 cola = map( p + float2(e,0.0) ); float ga = dot(cola,float3(0.333, 0.333, 0.333));
    93.                 float3 colb = map( p + float2(0.0,e) ); float gb = dot(colb,float3(0.333, 0.333, 0.333));
    94.    
    95.                 float3 nor = normalize( float3(ga-gc, e, gb-gc ) );
    96.  
    97.                 _Col = colc;
    98.                 _Col += float3(0.1,0.1,8.3)*1.0*abs(3.0*gc-ga-gb);
    99.                 _Col *= 0.5+0.2*nor.y*nor.y;
    100.                     _Col += 0.05*nor.y*nor.y*nor.y;
    101.    
    102.    
    103.                 float2 q = uv;
    104.                 _Col *= pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.1);
    105.                 //_Extract = _Col.r;// damnit??
    106.                 return _Col;
    107.         }
    108.  
    109. //        float4 getNewVertPosition( float4 p )
    110. //        {
    111. //            p.x += sin( _Time.y * _Speed + p.y * _Amount ) * _Distance;
    112. //            return p;
    113. //        }
    114.  
    115. //        void disp (inout appdata v)
    116. //            {
    117. //                float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;
    118. //                v.vertex.xyz += v.normal * d;
    119. //            }
    120.  
    121.         float4 getNewVertPosition( float4 p )
    122.         {
    123.             //float d = makeMeNoise(p.xy).y; // How do I pass the functions from MakeMeNoise at same time as making color,
    124. //            // I'm calling makeMeNoise twice and above probably passing wrong values.
    125.             //p += _Col.g*_Displacement;
    126.             return p;
    127.         }
    128.  
    129.             // Does it matter the order of the surf/vert elements? Can I get the color value to depthmap it
    130.         // instead of passing through the same fuctions and calling MakeMeNoise, can I have a public ColorValue??
    131.  
    132.         void vert( inout appdata_full v )
    133.         {
    134.             //float d = _Col.y * _Displacement; // How to do I access wht Col is from here?
    135.             //d+=_Col.y * _Displacement;
    136.             float d = makeMeNoise(v.vertex.xy).z * _Displacement;
    137.             v.vertex.xyz += v.normal * d;
    138.             //v.vertex.z += _Displacement ;
    139.             float4 vertPosition = getNewVertPosition( v.vertex );
    140.  
    141.             // calculate the bitangent (sometimes called binormal) from the cross product of the normal and the tangent
    142.             float4 bitangent = float4( cross( v.normal, v.tangent ), 0 );
    143.  
    144.             // how far we want to offset our vert position to calculate the new normal
    145.             float vertOffset = 0.01;
    146.  
    147.             float4 v1 = getNewVertPosition( v.vertex + v.tangent * vertOffset );
    148.             float4 v2 = getNewVertPosition( v.vertex + bitangent * vertOffset );
    149.  
    150.             // now we can create new tangents and bitangents based on the deformed positions
    151.             float4 newTangent = v1 - vertPosition;
    152.             float4 newBitangent = v2 - vertPosition;
    153.  
    154.             // recalculate the normal based on the new tangent & bitangent
    155.             v.normal = cross( newTangent, newBitangent );
    156.  
    157.             v.vertex = vertPosition;
    158.         }
    159.             void surf (Input IN, inout SurfaceOutputStandard o)
    160.  
    161.         {
    162.             // Albedo comes from a texture tinted by color
    163.                 //return float4( col, 1.0 );
    164.                 _Col = makeMeNoise(IN.uv_MainTex);
    165.  
    166.                 fixed4 c = _Color;
    167.                 c.rgb = _Col;
    168.                 o.Albedo = c.rgb;
    169.             // Metallic and smoothness come from slider variables
    170.                 o.Metallic = _Metallic;
    171.                 o.Smoothness = _Glossiness;
    172.                 o.Alpha = c.a;
    173.         }
    174.         ENDCG
    175.     }
    176.     FallBack "Diffuse"
    177. }
     
  13. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    No.

    Unity's ShaderLab has the vertex shader and fragment shader defined in a single file for convenience, but on the GPU they're completely separate things that have no knowledge of each other. Data can only be passed from the vertex shader to the fragment shader via the vertex output semantics one vertex at a time. The fragment shader can only output a color (and optionally depth, color is optional too actually) for a single pixel at a time to the current render target. Any other "global" value you set in the shader only exists for the computation of each individual vertex or pixel, and then thrown away.

    You may want to read this, all 5 parts.
    http://www.alanzucconi.com/2015/06/10/a-gentle-introduction-to-shaders-in-unity3d/
     
  14. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Ahh thank you for clearing that up for me, that's so annoying they're in the same file but can't see each other, I would have thought I could have accessed a variable as I thought it was still living somewhere in memory. Although I did read something yesterday about their being no stack and heap in GLSL (http://gamedev.stackexchange.com/qu...-variables-outside-of-the-main-function-scope) and the variables just live in registers, so I thought it may be the same in HLSL.

    I've just read the intro to shaders, it's really well written, and a couple of tricks, I take it if I change all my floats to halfs I might get a boost in performance from not using a high precision 32bit float?

    Still got some going to solve my problem, and might need to think outside of the box to solve this one.

    The way I've seen it done is with a heightmap usually, and use the texture look up table to feed into 2dTexLOD and displace vertex.z by one of the rgba values, simple. To solve with what I have i'd have to render out the length of animation, write a script to move through the height texture folder at the same time as the colour animation in the shader, or just do it all through exported textures, manually rendering out from the shader. Could work but not ideal on size, kinda defeats the point.

    The other option I was thinking about and (I don't know if it would work now you say Vert and Surf are uncommunicative) is to re-arrange the order of events, still only call makemeNoise from one place, but pass the whole lot on out of it with a custom data struct maybe. Does the vertex modifier have an idea of UV coords? I assume it would.
    Screen Shot 2017-01-24 at 18.25.33.png
     
  15. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Possibly. Depends heavily on the platform and hardware. If you're on desktop using Nvidia, AMD, or Intel GPUs, probably not. If you're on mobile using Mali, Adreno, or PowerVR it's absolutely help ... as long as you don't mix floats and halfs together.
    A float is a 32 bit floating point number, a half is a 16 bit floating point number, and a fixed is roughly a 12 bit floating point number (though it's implementation is actually only defined as needing a precision of "at least" 1/256 across the range of -2.0 to 2.0). Some GPUs, usually mobile, have unique hardware paths to handle numbers of lower precision that use less power and / or less time to calculate. Desktop GPUs generally haven't had this extra hardware, and just compute everything using the same hardware path ... effectively on desktop all number types are 32 bit once in the shader so the float, half, fixed denotations aren't as relevant.

    Another issue with understanding shaders is that they're both more and less linear than you might think. Like I said before, and Alan's tutorial illustrates, the order of the processing is linear. However there is more than one vertex, and more than one pixel being processed at any one time, often in parallel, and not necessarily in an order that makes immediate sense.

    Lets take a basic example of a single quad being rendered to the screen. It has two triangles, a vertex shader, and a fragment shader. Before it can start rendering anything it needs to process the three vertices from one triangle. Then it takes the output of those vertex shaders and finds the pixels it covers. Then it starts rendering the pixels with the fragment shader using data interpolated from the vertices. The order it processes the vertices might be one after another, or all three at once, or in larger batches of many vertices that include other triangles, that's up to the GPU and the drivers. Similarly the pixels aren't rendered just top to bottom, left to right, but at least in batches of 4 (2x2) in parallel together, but also possibly in larger batches, or seemingly randomly distributed 2x2 blocks across the screen. It might also be processing the vertices for the next triangle at the same time as rendering the pixels out, or even a completely different mesh and / or shader!

    When you look at the specs for something like an Nvidia or AMD GPU you'll see it has something like "512 shader cores". That effectively means it could be processing fragment shader for 512 pixels at the same time, or maybe 256 vertices and 256 pixels, or any other combination. And there's no guarantee that all of those pixels are using the same fragment shader, or that they all start and finish at the same time, so they could be out of phase (think row row row your boat). So, a "global" value that you set in your vertex shader that you want to be used by your fragment shader ... from which vertex do you want that data from? It's impossible to know which last set it, or if it might change while the fragment shader is running so it's a different value depending on if you access it at the start of the shader or the end. It could even change while the fragment shader is reading the value meaning you get something completely random!

    Now in reality this kind of collision never happens, because GPUs (usually) don't allow it. However those are the same issues that other massively parallel computing systems have to deal with. This is why we don't all have CPUs with 100 cores in them by now, because just getting 4 cores to work together efficiently with general purpose code is a hassle. GPUs and shader code were designed with the expected limitations of massive parallelism in place.

    I recommend you get to the fourth page of Alan's tutorial. The vertex modifier in a surface shader is basically just a function called at the start of the surface shader's vertex shader to let you modify data that came from the mesh, including the UVs. If the vertex shader doesn't know about the UVs, the fragment shader can't either because all it knows is what the vertex shader told it (and any "uniform", ie unchanging, values from the material). It's not that the vertex modifier and surf functions are "uncommunicative", it's that the data only goes one direction from the vertex shader (where the vertex modifier function is called) to the fragment shader (where the surf function is called) via those explicit output semantics.
     
    PrimalCoder likes this.
  16. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Ahh ok thanks that clears that up, maybe eventually halfs will be relevant for VR, at the moment I'm not sure I have to implement limitations as my own machines gpu is a nvidia gtx 760 or something, so it's seems it'll all be put into 32bits, so shouldn't worry much now. I have read somewhere about putting float/fixed/half and the compiler didn't spit up anything, so it's starting to kind of make sense.

    I remember seeing a graph some time ago, about how the less parallelizable a problem the less effective a massive parallel computing array becomes, there are certain problems you can parallelize and in those cases you can chuck loads of cores and it will perform better, but in cases where the problem isn't parallelizable and has to be iterated, I guess that would be serial computing then chucking a load of cores doesn't help at all. Most of computing on CPU's is like step by step instruction based, execute in this order, so it's pointless chucking 100 cores in a cpu, as it wouldn't make you solve the problem any faster. (I maybe badly remembering all that, apologies)

    So is there a way I can embed or pull out the data from the stream that I'm passing from vert to surf/frag? Maybe call the noise function in vert, pass out two sets of UV/tex coords with the colour embedded inside.

    I could re-write to test to see if I can just make the function work just as a distortion on a plane, but I'm wondering if i've stumbled down the wrong path writing a surface shader, as I did start doing this as a frag/vert shader to begin with and then for some reason assumed you couldn't do vector displacement.
     
  17. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    You can pass all kinds of arbitrary data from the vertices to the fragment shader, and nearly any function you can run in the fragment shader you can run in the vertex shader too. So yes, try just running the noise function in your vertex modifier function or vertex shader. There is literally nothing a surface shader can do that a vertex fragment shader can't since, as I mentioned before, surface shaders are vertex fragment shaders.

    There's actually a ton you can do with vertex fragment shaders you can't do with surface shaders though... but you're probably not at that point yet.

    If you want to stick with surface shaders check out this page:
    https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html
    Scroll down to the "Custom data computed per-vertex" example.
     
  18. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Ahh that's ace to hear, was starting to think I may have started going down the wrong path with surface shaders, good to know they they are essentially the same thing.

    Not at the point yet, would that include stuff like raymarching? In all fairness I just want to make demos eventually, just ridiculous generative graphics, I've been messing around with games, but more of an musician/artist so naturally got drawn into finding out about demoscene, now I know how to tunnel and deform planes, make a bit of noise, just need to deform a plane with the noise and I've got some goopy awesomeness! I really would like to find out how far you can push shaders!! It's just GLSL resources are abundant, hlsl are a bit scattered.

    That was exactly the page I was studying last night, and saw the per vertex example, so do you reckon the important thing here is UNITY_INITIALIZE_OUTPUT in the vert and specifying out, that looks like how it's passing data out of it. In theory could I have a custom Input struct that returns the noise colour values for the frag shader, pass it out as o or something.

    I think in theory I've got it there, let me mess around for a while and see if I can get something working, I've initialised output and, made it go black, so it's step in the right direction!!
     
  19. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Surface shaders exists to simplify the use Unity's built in lighting systems and shading models. If you don't plan on using Unity's lighting there's no reason to use surface shaders. You could do raymarching in a surface shader, and some people do for things like parallax occlusion mapping or relief mapping techniques (both of which are minor variations of raymarching implementations).

    It's more subtle stuff like alpha to coverage rendering or mixing tessellation and custom per vertex data. Just limitations in the Surface Shader generation code that they didn't add support to handle.

    Nope. That's just a helping macro for setting all values to zero so the shader compiler doesn't complain if you forget to set something in the output struct. I generally don't use it in my own shaders since it can hide errors.

    I really suggest you finish all 5 parts of that tutorial I linked to earlier. A lot of this is on page 4.
     
  20. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    I know I should just start over from a frag/vert shader with the structs aI would but I just love hacking my way to an epiphany, learning through doing, or in my case failing until success!

    Come on I think I'm only one epiphany away now!

    Code (CSharp):
    1. Shader "Custom/NewGoop" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    5.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    6.         _Metallic ("Metallic", Range(0,1)) = 0.0
    7.         _Displacement("Displacement", Range( 0, 200 )) = 9.3
    8.     }
    9.     SubShader {
    10.         Tags { "RenderType"="Opaque" }
    11.         LOD 200
    12.        
    13.         CGPROGRAM
    14.  
    15.         #pragma surface surf Standard fullforwardshadows vertex:vert addshadow
    16.  
    17.         #pragma target 3.0
    18.  
    19.         sampler2D _MainTex;
    20.  
    21.         struct Input
    22.         {
    23.             float2 uv_MainTex;
    24.             float3 noiseFunc;
    25.         };
    26.  
    27.         half _Glossiness;
    28.         half _Metallic;
    29.         fixed4 _Color;
    30.         float3 _Col;
    31.         half _Displacement;
    32.         const float2 m = float2( 0.80,  0.60 );
    33.  
    34.         float hash( float2 p )
    35.         {
    36.             float h = dot(p,float2(127.1,311.7));
    37.             return -1.0 + 2.0*frac(sin(h)*43758.5453123);
    38.         }
    39.  
    40.         float noise( in float2 p )
    41.         {
    42.             float2 i = floor( p );
    43.             float2 f = frac( p );
    44.            
    45.             float2 u = f*f*(3.0-2.0*f);
    46.  
    47.             return lerp( lerp( hash( i + float2(0.0,0.0) ),
    48.                              hash( i + float2(1.0,0.0) ), u.x),
    49.                         lerp( hash( i + float2(0.0,1.0) ),
    50.                              hash( i + float2(1.0,1.0) ), u.x), u.y);
    51.         }
    52.  
    53.         float fbm( float2 p )
    54.         {
    55.             float f = 0.0;
    56.             f += 0.5000*noise( p ); p = m*p*2.02;
    57.             f += 0.2500*noise( p ); p = m*p*2.03;
    58.             f += 0.1250*noise( p ); p = m*p*2.01;
    59.             f += 0.0625*noise( p );
    60.             return f/0.9375;
    61.         }
    62.  
    63.         float2 fbm2( in float2 p )
    64.         {
    65.             return float2( fbm(p.xy), fbm(p.yx) );
    66.         }
    67.  
    68.         float3 map( float2 p )
    69.         {  
    70.             p *= 2.9;
    71.  
    72.             float f = dot( fbm2( 1.0*(0.5*_Time.y + p + fbm2(-0.5*_Time.y+1.0*(p + fbm2(4.0*p)))) ), float2(1.0,-1.0) );
    73.  
    74.             float bl = smoothstep( -0.8, 0.8, f );
    75.  
    76.             float ti = smoothstep( -1.0, 1.0, fbm(p) );
    77.  
    78.             return lerp( lerp( float3(0.50,0.00,0.00),
    79.                              float3(1.00,0.5,0.35), ti ),
    80.                              float3(0.00,0.00,0.02), bl );
    81.         }
    82.         float3 makeMeNoise(float2 uv)
    83.         {
    84.                   float2 p =  4 * uv;
    85.                 float e = 0.0016;
    86.                 float3 colc = map( p               ); float gc = dot(colc,float3(0.333, 0.333, 0.333));
    87.                 float3 cola = map( p + float2(e,0.0) ); float ga = dot(cola,float3(0.333, 0.333, 0.333));
    88.                 float3 colb = map( p + float2(0.0,e) ); float gb = dot(colb,float3(0.333, 0.333, 0.333));
    89.                 float3 nor = normalize( float3(ga-gc, e, gb-gc ) );
    90.  
    91.                 _Col = colc;
    92.                 _Col += float3(0.1,0.1,8.3)*1.0*abs(3.0*gc-ga-gb);
    93.                 _Col *= 0.5+0.2*nor.y*nor.y;
    94.                     _Col += 0.05*nor.y*nor.y*nor.y;
    95.    
    96.                 float2 q = uv;
    97.                 _Col *= pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.1);
    98.                 //_Extract = _Col.r;// damnit??
    99.                 return _Col;
    100.         }
    101.  
    102.         float4 getNewVertPosition( float4 p )
    103.         {
    104.             return p;
    105.         }
    106.  
    107.         void vert( inout appdata_full v, out Input o)
    108.         {
    109.             UNITY_INITIALIZE_OUTPUT(Input,o); // Init output
    110.             o.noiseFunc = makeMeNoise(v.vertex); // make noiseFunc
    111.             float3 nois = o.noiseFunc;
    112.             float d = nois.z * _Displacement;
    113.             v.vertex.xyz += v.normal * d;
    114.             float4 vertPosition = getNewVertPosition( v.vertex );
    115.             // calculate the bitangent (sometimes called binormal) from the cross product of the normal and the tangent
    116.             float4 bitangent = float4( cross( v.normal, v.tangent ), 0 );
    117.             // how far we want to offset our vert position to calculate the new normal
    118.             float vertOffset = 0.01;
    119.             float4 v1 = getNewVertPosition( v.vertex + v.tangent * vertOffset );
    120.             float4 v2 = getNewVertPosition( v.vertex + bitangent * vertOffset );
    121.             // now we can create new tangents and bitangents based on the deformed positions
    122.             float4 newTangent = v1 - vertPosition;
    123.             float4 newBitangent = v2 - vertPosition;
    124.             // recalculate the normal based on the new tangent & bitangent
    125.             v.normal = cross( newTangent, newBitangent );
    126.             v.vertex = vertPosition;
    127.         }
    128.             void surf (Input IN, inout SurfaceOutputStandard o)
    129.  
    130.         {
    131.             // Albedo comes from a texture tinted by color
    132.                 //return float4( col, 1.0 );
    133.                 _Col *= IN.noiseFunc;
    134.                 fixed4 c = _Color;
    135.                 c.rgb = _Col;
    136.                 o.Albedo = c.rgb;
    137.             // Metallic and smoothness come from slider variables
    138.                 o.Metallic = _Metallic;
    139.                 o.Smoothness = _Glossiness;
    140.                 o.Alpha = c.a;
    141.         }
    142.         ENDCG
    143.     }
    144.     FallBack "Diffuse"
    145. }
    I've set it up like the custom vertex data example, o.noiseFunc in mine is equivalent to customColour on this page: https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html

    I get down to surf and looks like I'm passing the value in the same way as the example but I'm not getting the colour come through. I suspect it's 114, as I'm passing v.vertex instead of a uv value.

    I've just had a crack at the frag/vert one:

    Code (CSharp):
    1.  
    2.  Shader"Paintings/Base"{
    3. Properties{
    4.  _MainTex ("Texture", 2D) = "white" {}
    5.  }
    6. SubShader{
    7.  
    8. Pass{
    9. CGPROGRAM
    10. #pragmavertexvert
    11. #pragmafragmentfrag
    12.  
    13.  #include "UnityCG.cginc"
    14.  
    15. struct appdata{
    16. float4vertex : POSITION;
    17. float2 uv : TEXCOORD0;
    18. float4 noiseFunc : TEXCOORD2; //isthisright??
    19.  };
    20.  
    21. struct v2f
    22.  {
    23. float2 uv : TEXCOORD0;
    24. float4vertex : SV_POSITION;
    25. float4 screenCoord : TEXCOORD1;
    26. float4 noiseFunc : TEXCOORD2; //isthisright??
    27.  };
    28.  
    29. constfloat2 m = float2( 0.80, 0.60 );
    30. float3 _Col;
    31. half _Displacement;
    32.  
    33. float hash( float2 p )
    34.  {
    35. float h = dot(p,float2(127.1,311.7));
    36. return -1.0 + 2.0*frac(sin(h)*43758.5453123);
    37.  }
    38.  
    39. float noise( infloat2 p )
    40.  {
    41. float2 i = floor( p );
    42. float2 f = frac( p );
    43.  
    44. float2 u = f*f*(3.0-2.0*f);
    45.  
    46. returnlerp( lerp( hash( i + float2(0.0,0.0) ),
    47.  hash( i + float2(1.0,0.0) ), u.x),
    48. lerp( hash( i + float2(0.0,1.0) ),
    49.  hash( i + float2(1.0,1.0) ), u.x), u.y);
    50.  }
    51.  
    52. float fbm( float2 p )
    53.  {
    54. float f = 0.0;
    55.  f += 0.5000*noise( p ); p = m*p*2.02;
    56.  f += 0.2500*noise( p ); p = m*p*2.03;
    57.  f += 0.1250*noise( p ); p = m*p*2.01;
    58.  f += 0.0625*noise( p );
    59. return f/0.9375;
    60.  }
    61.  
    62. float2 fbm2( infloat2 p )
    63.  {
    64. returnfloat2( fbm(p.xy), fbm(p.yx) );
    65.  }
    66.  
    67. float3 map( float2 p )
    68.  {
    69.  p *= 2.9;
    70.  
    71. float f = dot( fbm2( 1.0*(0.5*_Time.y + p + fbm2(-0.5*_Time.y+1.0*(p + fbm2(4.0*p)))) ), float2(1.0,-1.0) );
    72.  
    73. float bl = smoothstep( -0.8, 0.8, f );
    74.  
    75. float ti = smoothstep( -1.0, 1.0, fbm(p) );
    76.  
    77. returnlerp( lerp( float3(0.50,0.00,0.00),
    78. float3(1.00,0.5,0.35), ti ),
    79. float3(0.00,0.00,0.02), bl );
    80.  }
    81. float3 makeMeNoise(float2 uv)
    82.  {
    83. float2 p = 4 * uv;
    84. float e = 0.0016;
    85.  
    86. float3 colc = map( p ); float gc = dot(colc,float3(0.333, 0.333, 0.333));
    87. float3 cola = map( p + float2(e,0.0) ); float ga = dot(cola,float3(0.333, 0.333, 0.333));
    88. float3 colb = map( p + float2(0.0,e) ); float gb = dot(colb,float3(0.333, 0.333, 0.333));
    89.  
    90. float3 nor = normalize( float3(ga-gc, e, gb-gc ) );
    91.  
    92.  _Col = colc;
    93.  _Col += float3(0.1,0.1,8.3)*1.0*abs(3.0*gc-ga-gb);
    94.  _Col *= 0.5+0.2*nor.y*nor.y;
    95.  _Col += 0.05*nor.y*nor.y*nor.y;
    96.  
    97.  
    98. float2 q = uv;
    99.  _Col *= pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.1);
    100. return _Col;
    101.  }
    102.  
    103. float4 getNewVertPosition( float4 p )
    104.  {
    105. return p;
    106.  }
    107.  
    108.  v2f vert (appdata v)
    109.  {
    110.  v2f o;
    111.  o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    112.  o.uv = v.uv;
    113.  
    114.  o.noiseFunc.xyz = makeMeNoise(o.uv);
    115. float3 nois = o.noiseFunc.xyz;
    116. float d = nois.x;
    117. //v.vertex.xyz+=v.normal*d;
    118.  v.vertex.xyz += d;
    119. //v.vertex.z+=_Displacement;
    120. float4 vertPosition = getNewVertPosition( v.vertex );
    121.  
    122. ////calculatethebitangent(sometimescalledbinormal)fromthecrossproductofthenormalandthe tangent
    123. //float4bitangent=float4(cross(v.normal,v.tangent),0);
    124. //
    125. ////howfarwewanttooffsetourvertpositiontocalculatethenew normal
    126. //floatvertOffset=0.01;
    127. //
    128. //float4v1=getNewVertPosition(v.vertex+v.tangent*vertOffset);
    129. //float4v2=getNewVertPosition(v.vertex+bitangent*vertOffset);
    130. //
    131. ////nowwecancreatenewtangentsandbitangentsbasedonthedeformed positions
    132. //float4newTangent=v1-vertPosition;
    133. //float4newBitangent=v2-vertPosition;
    134. //
    135. ////recalculatethenormalbasedonthenewtangent& bitangent
    136. //v.normal=cross(newTangent,newBitangent);
    137.  
    138.  v.vertex = vertPosition;
    139.  o.screenCoord.xy = ComputeScreenPos(o.vertex);
    140. return o;
    141.  }
    142.  
    143. sampler2D _MainTex;
    144.  
    145. fixed4 frag (v2f i) : SV_Target
    146.  {
    147. float2 uv = i.uv;
    148. float3 col = i.noiseFunc;
    149. //float3col=(1,1,1);
    150. returnfloat4(col,1);
    151.  
    152.  }
    153. ENDCG
    154.  }
    155.  }
    156. }
    157.  
    It compiles, haven't tested it yet though!
     
  21. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    yay I did something very close:

    Screen Shot 2017-01-25 at 00.23.09.png

    problem is it's really spikey, might be the number of verts on the mesh itself, so will try upping that to begin with, but my process seems to take away a lot of the original definition of the noise function, changes the colour and definition considerably. Will experiment some more to see if I can get better results.

    Code (CSharp):
    1. Shader "Paintings/Base"{
    2.     Properties{
    3.     _MainTex ("Texture", 2D) = "white" {}
    4.     _Displacement("Displacement", Range( 0, 200 )) = 9.3
    5.     }
    6.     SubShader{
    7.  
    8.         Pass{
    9.             CGPROGRAM
    10.             #pragma vertex vert
    11.             #pragma fragment frag
    12.          
    13.             #include "UnityCG.cginc"
    14.  
    15.             struct appdata{
    16.                 float4 vertex : POSITION;
    17.                 float2 uv : TEXCOORD0;
    18.                 //float4 noiseFunc : COLOUR0; // is this right??
    19.                 float4 noiseFunc : COLOUR;
    20.             };
    21.  
    22.             struct v2f
    23.             {
    24.                 float2 uv : TEXCOORD0;
    25.                 float4 vertex : SV_POSITION;
    26.                 float4 screenCoord : TEXCOORD1;
    27.                 float4 noiseFunc : COLOUR; // is this right??
    28.             };
    29.  
    30.         const float2 m = float2( 0.80,  0.60 );
    31.         float3 _Col;
    32.         half _Displacement;
    33.  
    34.         float hash( float2 p )
    35.         {
    36.             float h = dot(p,float2(127.1,311.7));
    37.             return -1.0 + 2.0*frac(sin(h)*43758.5453123);
    38.         }
    39.  
    40.         float noise( in float2 p )
    41.         {
    42.             float2 i = floor( p );
    43.             float2 f = frac( p );
    44.          
    45.             float2 u = f*f*(3.0-2.0*f);
    46.  
    47.             return lerp( lerp( hash( i + float2(0.0,0.0) ),
    48.                              hash( i + float2(1.0,0.0) ), u.x),
    49.                         lerp( hash( i + float2(0.0,1.0) ),
    50.                              hash( i + float2(1.0,1.0) ), u.x), u.y);
    51.         }
    52.  
    53.         float fbm( float2 p )
    54.         {
    55.             float f = 0.0;
    56.             f += 0.5000*noise( p ); p = m*p*2.02;
    57.             f += 0.2500*noise( p ); p = m*p*2.03;
    58.             f += 0.1250*noise( p ); p = m*p*2.01;
    59.             f += 0.0625*noise( p );
    60.             return f/0.9375;
    61.         }
    62.  
    63.         float2 fbm2( in float2 p )
    64.         {
    65.             return float2( fbm(p.xy), fbm(p.yx) );
    66.         }
    67.  
    68.         float3 map( float2 p )
    69.         {
    70.             p *= 1.9;
    71.  
    72.             float f = dot( fbm2( 1.0*(0.5*_Time.y + p + fbm2(-0.5*_Time.y+1.0*(p + fbm2(4.0*p)))) ), float2(1.0,-1.0) );
    73.  
    74.             float bl = smoothstep( -0.8, 0.8, f );
    75.  
    76.             float ti = smoothstep( -1.0, 1.0, fbm(p) );
    77.  
    78.             return lerp( lerp( float3(0.50,0.00,0.00),
    79.                              float3(1.00,0.5,0.35), ti ),
    80.                              float3(0.00,0.00,0.02), bl );
    81.         }
    82.         float3 makeMeNoise(float2 uv)
    83.         {
    84.                   float2 p =  32 * uv;
    85.                 float e = 0.0016;
    86.  
    87.                 float3 colc = map( p               ); float gc = dot(colc,float3(0.333, 0.333, 0.333));
    88.                 float3 cola = map( p + float2(e,0.0) ); float ga = dot(cola,float3(0.333, 0.333, 0.333));
    89.                 float3 colb = map( p + float2(0.0,e) ); float gb = dot(colb,float3(0.333, 0.333, 0.333));
    90.  
    91.                 float3 nor = normalize( float3(ga-gc, e, gb-gc ) );
    92.  
    93.                 _Col = colc;
    94.                 _Col += float3(0.1,0.1,8.3)*1.0*abs(3.0*gc-ga-gb);
    95.                 _Col *= 0.5+0.2*nor.y*nor.y;
    96.                     _Col += 0.05*nor.y*nor.y*nor.y;
    97.                 float2 q = uv;
    98.                 //_Col *= pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.1);
    99.                 return _Col;
    100.         }
    101.  
    102.         float4 getNewVertPosition( float4 p )
    103.         {
    104.             return p;
    105.         }
    106.  
    107.             v2f vert (appdata v)
    108.             {
    109.                 v2f o;
    110.             o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    111.  
    112.             o.uv = v.uv;
    113.  
    114.             o.noiseFunc.xyz = makeMeNoise(o.uv);
    115.             float4 nois = o.noiseFunc;
    116.             float d = nois.y * _Displacement;
    117.             //v.vertex.xyz += v.normal * d;
    118.             o.vertex.y += d;
    119.             //v.vertex.z += _Displacement ;
    120.             float4 vertPosition = getNewVertPosition( o.vertex );
    121.  
    122. //            // calculate the bitangent (sometimes called binormal) from the cross product of the normal and the tangent
    123. //            float4 bitangent = float4( cross( v.normal, v.tangent ), 0 );
    124. //
    125. //            // how far we want to offset our vert position to calculate the new normal
    126. //            float vertOffset = 0.01;
    127. //
    128. //            float4 v1 = getNewVertPosition( v.vertex + v.tangent * vertOffset );
    129. //            float4 v2 = getNewVertPosition( v.vertex + bitangent * vertOffset );
    130. //
    131. //            // now we can create new tangents and bitangents based on the deformed positions
    132. //            float4 newTangent = v1 - vertPosition;
    133. //            float4 newBitangent = v2 - vertPosition;
    134. //
    135. //            // recalculate the normal based on the new tangent & bitangent
    136. //            v.normal = cross( newTangent, newBitangent );
    137.  
    138.             o.vertex = vertPosition;
    139.             o.screenCoord.xy = ComputeScreenPos(o.vertex);  
    140.                 return o;
    141.             }
    142.  
    143.              sampler2D _MainTex;
    144.          
    145.             float4 frag (v2f i) : SV_Target
    146.             {
    147.                 float2 uv = i.uv;
    148.                 float2 q = uv;
    149.                 float3 col = i.noiseFunc;
    150.                 //float3 col = (1,1,1);
    151.                 col*= pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.1);
    152.                 return float4(col,1);
    153.  
    154.             }
    155.             ENDCG
    156.         }
    157.     }
    158. }
    159.  
     
  22. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Tried with another noise generating shader, this time sampling from tex2Dlod, I can get to displace successfully but end up slightly ruining the original effect of the color.

    Code (CSharp):
    1. Shader "Paintings/Base"{
    2.     Properties
    3.     {
    4.     _MainTex ("Texture", 2D) = "white" {}
    5.     _Displacement("Displacement", Range( 0, 200 )) = 9.3
    6.     }
    7.     SubShader{
    8.  
    9.         Pass{
    10.             CGPROGRAM
    11.             #pragma vertex vert
    12.             #pragma fragment frag
    13.          
    14.             #include "UnityCG.cginc"
    15.      
    16.             struct appdata{
    17.                 float4 vertex : POSITION;
    18.                 float2 uv : TEXCOORD0;
    19.                 float4 noiseFunc : COLOUR; // is this right??
    20.             };
    21.  
    22.             struct v2f{
    23.                 float2 uv : TEXCOORD0;
    24.                 float4 vertex : SV_POSITION;
    25.                 float4 screenCoord : TEXCOORD1;
    26.                 float4 noiseFunc : COLOUR; // is this right??
    27.             };
    28.  
    29.             #define mat2 float2x2
    30.             half _Displacement;
    31.             sampler2D _MainTex;
    32.             const float2 mtx1 = float2( 0.80,  0.60);
    33.             const float2 mtx2 = float2( -0.60,  0.80 );
    34.  
    35.             float noise( in float2 x )
    36.             {
    37.                 float2 p = floor(x);
    38.                 float2 f = frac(x);
    39.                 f = f*f*(3.0-2.0*f);
    40.                 float e = tex2Dlod(_MainTex, float4(p.x+0.5,p.y+0.5,0,0) /256).r;
    41.                 float b = tex2Dlod(_MainTex, float4(p.x+1.5,p.y+0.5,0,0) /256).r;
    42.                 float c = tex2Dlod(_MainTex, float4(p.x+0.5,p.y+1.5,0,0) /256).r;
    43.                 float d = tex2Dlod(_MainTex, float4(p.x+1.5,p.y+1.5,0,0) /256).r;
    44.                 return lerp(lerp( e, b,f.x), lerp( e, d,f.x),f.y);
    45.             }
    46.  
    47.             //const mat2 mtx = mat2( 0.80,  0.60, -0.60,0.80);
    48.             float fbm4( float2 p )
    49.             {
    50.                 float f = 0.0;
    51.  
    52.                 f += 0.5000*(-1.0+2.0*noise( p )); p = mtx2*p*3.02;
    53.                 f += 0.2500*(-1.0+2.0*noise( p )); p = mtx2*p*3.03;
    54.                 f += 0.1250*(-1.0+2.0*noise( p )); p = mtx2*p*3.01;
    55.                 f += 0.0625*(-1.0+2.0*noise( p ));
    56.  
    57.                 return f/0.9375;
    58.             }
    59.  
    60.             float fbm6( float2 p )
    61.             {
    62.                 float f = 0.0;
    63.  
    64.                 f += 0.500000*noise( p ); p = mtx2*p*2.02;
    65.                 f += 0.250000*noise( p ); p = mtx2*p*2.03;
    66.                 f += 0.125000*noise( p ); p = mtx2*p*2.01;
    67.                 f += 0.062500*noise( p ); p = mtx2*p*2.04;
    68.                 f += 0.031250*noise( p ); p = mtx2*p*2.01;
    69.                 f += 0.015625*noise( p );
    70.  
    71.                 return f/0.96875;
    72.             }
    73.  
    74.             float func( float2 q, out float2 o, out float2 n )
    75.             {
    76.                 float ql = length( q );
    77.                 q.x += 0.05*sin(0.01*_Time.y+ql*1.1);
    78.                 q.y += 0.5*sin(0.0093*_Time.y+ql*1.2);
    79.                 q *= 0.7 + 0.2*cos(0.1*_Time.y);
    80.  
    81.                 q = (q+0.1)*0.5;
    82.  
    83.                 o.x = 0.5 + 0.5*fbm4( float2(1.0*q*float2(1.0,1.0)          )  );
    84.                 o.y = 0.5 + 0.5*fbm4( float2(1.0*q*float2(1.0,1.0)+float2(5.2,5.2))  );
    85.  
    86.                 float ol = length( o );
    87.                 o.x += 0.2*sin(0.11*_Time.y*ol)/ol;
    88.                 o.y += 0.2*sin(0.13*_Time.y*ol)/ol;
    89.  
    90.  
    91.                 n.x = fbm6( float2(8.0*o*float2(1.0,1.0)+float2(1.2,1.2))  );
    92.                 n.y = fbm6( float2(8.0*o*float2(1.0,1.0)+float2(5.7,5.7))  );
    93.  
    94.                 float2 p = (1)*q + (1)*n;
    95.  
    96.                 float f = 0.5 + 0.5*fbm4( p );
    97.  
    98.                 f = lerp( f, f*f*f*3.5, f*abs(n.x) );
    99.  
    100.                 float g = 0.5+0.5*sin(4.0*p.x)*sin(4.0*p.y);
    101.                 f *= 1.0-0.5*pow( g, 8.0 );
    102.                 return f;
    103.             }
    104.  
    105.             float funcs( in float2 q )
    106.             {
    107.                 float2 t1, t2;
    108.                 return func(q,t1,t2);
    109.             }
    110.  
    111.             float4 MakeMeNoise ( float2 uv )
    112.             {
    113.                     float2 p = uv;
    114.                     float2 q = (1.0 + 64.0*uv);
    115.                     //float q = p-1 * 2;
    116.  
    117.                     float2 o, n;
    118.                     float f = func(q, o, n);
    119.                     float3 col = float3(0.0,0.0,0.0);
    120.  
    121.  
    122.                     col = lerp( float3(0.2,0.1,0.4), float3(0.3,0.05,0.05), f );
    123.                     col = lerp( col, float3(0.9,0.9,0.9), dot(n,n) );
    124.                     col = lerp( col, float3(0.5,0.2,0.2), 0.5*o.y*o.y );
    125.                     col = lerp( col, float3(0.0,0.2,0.4), 0.5*smoothstep(1.2,1.3,abs(n.y)+abs(n.x)) );
    126.  
    127.                     col *= f*2.0;
    128.                 #if 1
    129.                     float2 ex = float2( 1.0 / 1, 0.0 );
    130.                     float2 ey = float2( 0.0, 1.0 / 1 );
    131.                     float3 nor = normalize( float3( funcs(q+ex) - f, ex.x, funcs(q+ey) - f ) );
    132.                 #else
    133.                     float3 nor = normalize( float3( dFdx(f)*1, 1.0, dFdy(f)*1 ) );  
    134.                 #endif
    135.                     float3 lig = normalize( float3( 0.9, -0.2, -0.4 ) );
    136.                     float dif = clamp( 0.3+0.7*dot( nor, lig ), 0.0, 1.0 );
    137.  
    138.                     float3 bdrf;
    139.                     bdrf  = float3(0.85,0.90,0.95)*(nor.y*0.5+0.5);
    140.                     bdrf += float3(0.15,0.10,0.05)*dif;
    141.  
    142.                     bdrf  = float3(0.85,0.90,0.95)*(nor.y*0.5+0.5);
    143.                     bdrf += float3(0.15,0.10,0.05)*dif;
    144.  
    145.                     col *= bdrf;
    146.                     float4 co;
    147.                     co.xyz = col;
    148.                     return co;
    149.             }
    150.  
    151.             v2f vert (appdata v){
    152.                 v2f o;
    153.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    154.                 o.uv = v.uv;
    155.  
    156.                 o.noiseFunc.xyz = MakeMeNoise(o.uv);
    157.                 float4 nois = o.noiseFunc;
    158.                 float d = nois.r * _Displacement;
    159.                 o.vertex.y += d;
    160.  
    161.                 o.screenCoord.xy = ComputeScreenPos(o.vertex);
    162.                 return o;
    163.             }
    164.  
    165.      
    166.              
    167.             fixed4 frag (v2f i) : SV_Target
    168.             {
    169.     i.noiseFunc.xyz = MakeMeNoise(i.uv); //Commentthislineouttosee smudgey
    170.     float3 col = i.noiseFunc;
    171.     float2 p = i.uv;
    172.     col = float3(0.2,0.0,0.2)-col;
    173.  
    174.     col = col*col;
    175.  
    176.     col *= float3(0.6,0.25,1.2);
    177.  
    178.     //col *= 0.5 + 0.5 * sqrt(16.0*p.x*p.y*(1.0-p.x)*(1.0-p.y));
    179.  
    180.     return float4( col, 1.0 );
    181.  
    182.             }
    183.             ENDCG
    184.         }
    185.     }
    186. }
    187.  
     
    Last edited: Jan 25, 2017
  23. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Sorry to bother again, been going through a tutorial and hit a brick wall and not sure why as I followed down to a t/

    http://flafla2.github.io/2016/10/01/raymarching.html

    I got down to end of step 3 and nothing appeared, gave in a downloaded the package and ended up with:
    crazyLinesRays.JPG
    I chucked in the lovelyRayMarch shader below, nothing special it's identical to the tester on the website, visualizes ray directions with colors, but I haven't got it to work at all.

    I'm on 5.5.0f3, on PC set to standalone in build settings, is there anything i'm doing wrong?

    Does this code work on anyone elses machine or unity version?...

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. //using System.Collections.Generic;
    4.  
    5. [ExecuteInEditMode]
    6. [RequireComponent(typeof(Camera))]
    7. [AddComponentMenu("Effects/Raymarch(Generic)")]
    8. public class TutorialRaymarch : SceneViewFilter
    9. {
    10.     [SerializeField]
    11.     private Shader _EffectShader;
    12.  
    13.     public Material EffectMaterial
    14.     {
    15.         get
    16.         {
    17.             if (!_EffectMaterial && _EffectShader)
    18.             {
    19.                 _EffectMaterial = new Material (_EffectShader);
    20.                 _EffectMaterial.hideFlags = HideFlags.HideAndDontSave;
    21.             }
    22.             return _EffectMaterial;
    23.         }
    24.     }
    25.     private Material _EffectMaterial;
    26.  
    27.     public Camera CurrentCamera
    28.     {
    29.         get
    30.         {
    31.             if   (!_CurrentCamera)
    32.                    _CurrentCamera = GetComponent<Camera> ();
    33.             return _CurrentCamera;
    34.         }
    35.     }
    36.     private Camera _CurrentCamera;
    37.  
    38.     [ImageEffectOpaque]
    39.     void OnRenderImage(RenderTexture source, RenderTexture destination)
    40.     {
    41.         if (!_EffectMaterial)
    42.         {
    43.             //Graphics.Blit (source, destination, EffectMaterial, 0);
    44.             Graphics.Blit (source, destination);
    45.             return;
    46.         }
    47.  
    48.         EffectMaterial.SetMatrix ("_FrustrumCornersES", GetFrustrumCorners (CurrentCamera));
    49.         EffectMaterial.SetMatrix ("_CameraInvViewMatrix", CurrentCamera.cameraToWorldMatrix);
    50.         EffectMaterial.SetVector ("_CameraWS", CurrentCamera.transform.position);
    51.  
    52.  
    53.         Graphics.Blit(source, destination, EffectMaterial, 0);
    54.     }
    55.  
    56.     private Matrix4x4 GetFrustrumCorners(Camera cam)
    57.     {
    58.         float camFOV = cam.fieldOfView;
    59.         float camAspect = cam.aspect;
    60.         Matrix4x4 frustrumCorners = Matrix4x4.identity;
    61.         float fovWHalf = camFOV * 0.5f;
    62.         float tan_fov = Mathf.Tan (fovWHalf * Mathf.Deg2Rad);
    63.  
    64.         Vector3 toRight = Vector3.right * tan_fov * camAspect;
    65.         Vector3 toTop = Vector3.up * tan_fov;
    66.  
    67.         Vector3 topLeft = (-Vector3.forward - toRight + toTop);
    68.         Vector3 topRight = (-Vector3.forward + toRight + toTop);
    69.         Vector3 bottomRight = (-Vector3.forward + toRight - toTop);
    70.         Vector3 bottomLeft = (-Vector3.forward - toRight - toTop);
    71.  
    72.         frustrumCorners.SetRow (0, topLeft);
    73.         frustrumCorners.SetRow (1, topRight);
    74.         frustrumCorners.SetRow (2, bottomRight);
    75.         frustrumCorners.SetRow(3,bottomLeft);
    76.  
    77.         return frustrumCorners;
    78.     }
    79.  
    80.     static void CustomGraphicsBlit(RenderTexture source, RenderTexture dest, Material fxMaterial, int passNr)
    81.     {
    82.         RenderTexture.active = dest;
    83.         fxMaterial.SetTexture ("_MainTex", source);
    84.  
    85.         GL.PushMatrix ();
    86.         GL.LoadOrtho ();
    87.  
    88.         fxMaterial.SetPass (passNr);
    89.         GL.Begin (GL.QUADS);
    90.         GL.MultiTexCoord2 (0, 0.0f, 0.0f);
    91.         GL.Vertex3 (0.0f, 0.0f, 3.0f);
    92.  
    93.         GL.MultiTexCoord2 (0, 1.0f, 0.0f);
    94.         GL.Vertex3 (1.0f, 0.0f, 2.0f);
    95.  
    96.         GL.MultiTexCoord2 (0, 1.0f, 1.0f);
    97.         GL.Vertex3 (1.0f, 1.0f, 1.0f);
    98.  
    99.         GL.MultiTexCoord2 (0, 0.0f, 1.0f);
    100.         GL.Vertex3 (0.0f, 1.0f, 0.0f);
    101.  
    102.         GL.End ();
    103.         GL.PopMatrix ();
    104.  
    105.     }
    106.  
    107. }
    108.  
    Extends from : http://framebunker.com/blog/viewing-image-effects-in-the-scene-view/
    ...
    Code (CSharp):
    1. using UnityEngine;
    2. #if UNITY_EDITOR
    3. using UnityEditor;
    4. #endif
    5.  
    6. public class SceneViewFilter : MonoBehaviour {
    7. #if UNITY_EDITOR
    8.     bool hasChanged = false;
    9.  
    10.     public virtual void OnValidate ()
    11.     {
    12.         hasChanged = true;
    13.     }
    14.    
    15.     static SceneViewFilter  ()
    16.     {
    17.         SceneView.onSceneGUIDelegate += CheckMe;
    18.     }
    19.  
    20.     static void CheckMe (SceneView sv)
    21.     {
    22.         if (Event.current.type != EventType.Layout)
    23.             return;
    24.         if (!Camera.main)
    25.             return;
    26.         // Get a list of everything on the main camera that should be synced.
    27.         SceneViewFilter[] cameraFilters = Camera.main.GetComponents<SceneViewFilter> ();
    28.         SceneViewFilter[] sceneFilters = sv.camera.GetComponents<SceneViewFilter> ();
    29.  
    30.         // Let's see if the lists are different lengths or something like that.
    31.         // If so, we simply destroy all scene filters and recreate from maincame
    32.         if (cameraFilters.Length != sceneFilters.Length)
    33.         {
    34.             Recreate (sv);
    35.             return;
    36.         }
    37.         for (int i = 0; i < cameraFilters.Length; i++)
    38.         {
    39.             if (cameraFilters[i].GetType() != sceneFilters[i].GetType())
    40.             {
    41.                 Recreate (sv);
    42.                 return;
    43.             }
    44.         }
    45.  
    46.         // Ok, WHICH filters, or their order hasn't changed.
    47.         // Let's copy all settings for any filter that has changed.
    48.         for (int i = 0; i < cameraFilters.Length; i++)
    49.         if (cameraFilters[i].hasChanged || sceneFilters[i].enabled != cameraFilters[i].enabled)
    50.         {
    51.             EditorUtility.CopySerialized (cameraFilters[i], sceneFilters[i]);
    52.             cameraFilters[i].hasChanged = false;
    53.         }
    54.     }
    55.  
    56.     static void Recreate (SceneView sv)
    57.     {
    58.         SceneViewFilter filter;
    59.         while (filter = sv.camera.GetComponent<SceneViewFilter> ())
    60.             DestroyImmediate (filter);
    61.  
    62.         foreach (SceneViewFilter f in Camera.main.GetComponents<SceneViewFilter> ())
    63.         {
    64.             SceneViewFilter newFilter = sv.camera.gameObject.AddComponent (f.GetType()) as SceneViewFilter;
    65.             EditorUtility.CopySerialized (f, newFilter);
    66.         }
    67.     }
    68. #endif
    69. }
    ShaderCode:
    Code (CSharp):
    1. Shader "Hidden/LovelyRayMarcher"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.         // No culling or depth
    10.         //Cull Off ZWrite Off ZTest Always
    11.  
    12.         Pass
    13.         {
    14.             CGPROGRAM
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.            
    18.             #include "UnityCG.cginc"
    19.  
    20.             uniform float4x4 _FrustrumCornersES;
    21.             uniform sampler2D _MainTex;
    22.             uniform float4 _MainTex_TexelSize;
    23.             uniform float4x4 _CameraInvViewMatrix;
    24.  
    25.             struct appdata
    26.             {
    27.                 float4 vertex : POSITION;
    28.                 float2 uv : TEXCOORD0;
    29.             };
    30.  
    31.             struct v2f
    32.             {
    33.                 float2 uv : TEXCOORD0;
    34.                 float4 pos : SV_POSITION;
    35.                 float3 ray : TEXCOORD1;
    36.             };
    37.  
    38.             v2f vert (appdata v)
    39.             {
    40.                 v2f o;
    41.  
    42.                 half index = v.vertex.z;
    43.                 v.vertex.z = 0.1;
    44.  
    45.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    46.  
    47.                 o.uv = v.uv;
    48.  
    49. //                #if UNITY_UV_STARTS_AT_TOP
    50. //                if (_MainTex_TexelSize.y < 0)
    51. //                o.uv.y = 1 - o.uv.y;
    52. //                #endif
    53.  
    54.                 o.ray = _FrustrumCornersES[(int)index].xyz;
    55.  
    56.                 o.ray = mul(_CameraInvViewMatrix,o.ray);
    57.  
    58.                 return o;
    59.             }
    60.  
    61.             fixed4 frag (v2f i) : SV_Target
    62.             {
    63.                 //fixed4 col = tex2D(_MainTex, i.uv);
    64.                 fixed4 col = fixed4(i.ray, 1);
    65.                 // just invert the colors
    66.                 //col = 1 - col;
    67.                 return col;
    68.             }
    69.             ENDCG
    70.         }
    71.     }
    72. }
    73.  
     
  24. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    Scrap that, I made a mistake spelling Frustrum wrong and not putting CustomGraphicsBlit line in! Now on with some sdf fun!!
     
  25. Richop

    Richop

    Joined:
    Mar 18, 2016
    Posts:
    136
    @bgolus Thanks for the links to Alan's blog, that's place has a wealth of knowledge, actually delved in past the intro to shaders and then onto other links and wow, this is helped get my head around volumetric raymarching and sdf craziness!

    here's where I've got to now, almost got Inigo's Flames from ShaderToy working in Unity:



    Just reversed and I've mapped the something from camera incorrectly, but I'm stoked of getting this far from only finding out about raymarching a few days ago!

    Code (CSharp):
    1. Shader "Hidden/LovelyRayMarcher"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.         // No culling or depth
    10.         Cull Off ZWrite Off ZTest Always
    11.  
    12.         Pass
    13.         {
    14.             CGPROGRAM
    15.             #pragma vertex vert
    16.             #pragma fragment frag
    17.             #pragma target 3.0
    18.             #include "UnityCG.cginc"
    19.  
    20.             uniform sampler2D _CameraDepthTexture;
    21.             uniform float4x4 _FrustumCornersES;
    22.             uniform float3 _CameraWS;
    23.             uniform sampler2D _MainTex;
    24.             uniform float4 _MainTex_TexelSize;
    25.             uniform float4x4 _CameraInvViewMatrix;
    26.  
    27.             struct appdata
    28.             {
    29.                 float4 vertex : POSITION;
    30.                 float2 uv : TEXCOORD0;
    31.             };
    32.  
    33.             struct v2f
    34.             {
    35.                 float4 pos : SV_POSITION;
    36.                 float2 uv : TEXCOORD0;
    37.                 float3 ray : TEXCOORD1;
    38.             };
    39.  
    40.             v2f vert (appdata v)
    41.             {
    42.                 v2f o;
    43.  
    44.                 half index = v.vertex.z;
    45.                 v.vertex.z = 0.1;
    46.  
    47.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    48.  
    49.                 o.uv = v.uv;
    50.  
    51.                 #if UNITY_UV_STARTS_AT_TOP
    52.                 if (_MainTex_TexelSize.y < 0)
    53.                 o.uv.y = 1 - o.uv.y;
    54.                 #endif
    55.  
    56.                 o.ray = _FrustumCornersES[(int)index].xyz;
    57.                 //o.ray /= abs(o.ray.z);
    58.                 o.ray = mul(_CameraInvViewMatrix,o.ray);
    59.  
    60.                 return o;
    61.             }
    62.  
    63.             float noise( in float3 x )
    64.             {
    65.                 float3 p = floor(x);
    66.                 float3 f = frac(x);
    67.                 f = f*f*(3.0-2.0*f);
    68.                 float2 uv = (p.xy+float2(37.0,17.0)*p.z) + f.xy;
    69.                 float2 rg = tex2D( _MainTex, (uv+ 0.5)/256.0 ).yx;
    70.                     return lerp( rg.x, rg.y, f.z );
    71.             }
    72.  
    73.             float4 map( in float3 p )
    74.             {
    75.                 float3 r = p; p.y += 0.6;
    76.                     // invert space
    77.                 //p = -4.0*p/dot(p,p);
    78.                 // twist space
    79.                 float an = -1.0*sin(0.1*_Time.y + length(p.xz) + p.y);
    80.                 float co = cos(an);
    81.                 float si = sin(an);
    82.                    p.xz = float4(co,-si,si,co)*p.xz;
    83.    
    84.                 // distort
    85.                 p.xz += -1.0 + 2.0*noise( p*1.1 );
    86.                 // pattern
    87.                 float f;
    88.                 float3 q = p*0.85                   - float3(0.0,1.0,0.0)*_Time.y*0.12;
    89.                 f  = 0.50000*noise( q ); q = q*2.02 - float3(0.0,1.0,0.0)*_Time.y*0.12;
    90.                 f += 0.25000*noise( q ); q = q*2.03 - float3(0.0,1.0,0.0)*_Time.y*0.12;
    91.                 f += 0.12500*noise( q ); q = q*2.01 - float3(0.0,1.0,0.0)*_Time.y*0.12;
    92.                 f += 0.06250*noise( q ); q = q*2.02 - float3(0.0,1.0,0.0)*_Time.y*0.12;
    93.                 f += 0.04000*noise( q ); q = q*2.00 - float3(0.0,1.0,0.0)*_Time.y*0.12;
    94.                 float den = clamp( (-r.y-0.6 + 4.0*f)*1.2, 0.0, 1.0 );
    95.                 float3 col = 1.2*lerp( float3(1.0,0.8,0.6), 0.9*float3(0.3,0.2,0.35), den ) ;
    96.                 col += 0.05*sin(0.05*q);
    97.                 col *= 1.0 - 0.8*smoothstep(0.6,1.0,sin(0.7*q.x)*sin(0.7*q.y)*sin(0.7*q.z))*float3(0.6,1.0,0.8);
    98.                     col *= 1.0 + 1.0*smoothstep(0.5,1.0,1.0-length( (frac(q.xz*0.12)-0.5)/0.5 ))*float3(1.0,0.9,0.8);
    99.                 col = lerp( float3(0.8,0.32,0.2), col, clamp( (r.y+0.1)/1.5, 0.0, 1.0 ) );
    100.                 return float4( col, den );
    101.             }
    102.  
    103.  
    104. //            fixed4 raymarch(float3 ro, float rd, float t, float3 bg, float4 sum)
    105. //            {
    106. //            fixed4 ret = fixed4(0,0,0,0);
    107. //            float4 col = float4(1,1,1,1);
    108. //              for( int i=0; i<128; i++ )
    109. //                    {
    110. //                        if( sum.a > 0.99 ) break;
    111. //                        float3 pos = ro + t*rd;
    112. //                        col = map( pos );
    113. //                        col.a *= 0.5;
    114. //                        col.rgb = lerp( bg, col.rgb, exp(-0.002*t*t*t) ) * col.a;
    115. //                        sum = sum + col*(1.0 - sum.a);
    116. //                        t += 0.05;
    117. //                        }
    118. //            return col;
    119. //            }
    120.  
    121.             fixed4 frag (v2f i) : SV_Target
    122.             {
    123.                 //fixed4 col = tex2D(_MainTex, i.uv);
    124.                 //float3 rd = normalize(i.ray.xyz);
    125.                 //float3 ro = _CameraWS;
    126.                 //fixed3 col = tex2D(_MainTex,i.uv);
    127.                 //fixed4 add = raymarch(ro,rd);
    128.                 //fixed4 col = fixed4(i.ray, 1);
    129.                 //return col;
    130.  
    131.     float2 q = i.uv;
    132.     //float2 p = (-1.0 + 2.0*q) * float2( 1.0, 1.0 );
    133.     float2 p = q;
    134.     //--------------------------------------
    135.     // cameran  
    136.     //--------------------------------------
    137.     float an = -0.07*_Time.y + 3.0;
    138.  
    139.     float3 ro = normalize(_CameraWS);
    140.     ro.y += 1.0;
    141.     float3 ta = float3(0.0, 0.5, 0.0);
    142.     float cr = -0.4*cos(0.02*_Time.y);
    143.    
    144.     // build rayn
    145.     float3 ww = normalize( ta - ro );
    146.     float3 uu = normalize( cross( float3(sin(cr),cos(cr),0.0), ww ) );
    147.     float3 vv = normalize( cross(ww,uu) );
    148.     //float3 rd = normalize( p.x*uu + p.y*vv + 2.5*ww );
    149.     float3 rd = normalize(i.ray.xyz);
    150.  
    151.     //--------------------------------------
    152.     // raymarch
    153.     //--------------------------------------
    154.        float4 sum = float4(0.0,0.0,0.0,0.0);
    155.     float3 bg = float3(0.4,0.5,0.5)*1.3;
    156.     float t = 0.05*tex2D( _MainTex, p).x;
    157.  
    158.      for( int i=0; i<128; i++ )
    159.                     {
    160.                         if( sum.a > 0.99 ) break;
    161.                         float3 pos = ro + t*rd;
    162.                         float4 col = map( pos );
    163.                         col.a *= 0.5;
    164.                         col.rgb = lerp( bg, col.rgb, exp(-0.002*t*t*t) ) * col.a;
    165.                         sum = sum + col*(1.0 - sum.a);
    166.                         t += 0.05;
    167.                         }
    168.      //  float3 col = tex2D(_MainTex,p);
    169.     //   fixed4 add = raymarch(ro, rd, t, bg, sum);
    170.     float3 col = clamp( lerp( bg, sum.xyz/(0.001+sum.w), sum.w ), 0.0, 1.0 );
    171.     // dithering
    172.     //col = clamp( lerp( bg, sum.xyz/(0.001+sum.w), sum.w ), 0.0, 1.0 );
    173.     // return fixed4 (col,1.0);
    174.     //--------------------------------------
    175.     // contrast + vignetting
    176.     //--------------------------------------
    177.     col = col*col*(3.0-2.0*col)*1.4 - 0.4;
    178.     col *= 0.25 + 0.75*pow( 16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y), 0.1 );
    179.     return float4( col, 1.0 );
    180.  
    181.             }
    182.             ENDCG
    183.         }
    184.     }
    185. }
    186.  
    So incredibly happy!!