zoukankan      html  css  js  c++  java
  • shader 2 : use shaderToy in unity

    shadertoy 原型,https://www.shadertoy.com/view/XslGRr

    先说几个概念

      Shader language目前有3种主流语言:基于OpenGL的GLSL(OpenGL Shading Language,也称为GLslang),基于Direct3D的HLSL(High Level Shading Language),还有NVIDIA公司的Cg (C for Graphic)语言。
    其中unity使用的是GLSL,unity使用的是Cg,并且进一步封装,称为shaderLab。

    转unity代码如下:

    Shader "Shadertoy/Cloud" { 
        Properties{
            iMouse ("Mouse Pos", Vector) = (100, 100, 0, 0)
    //        iChannel0("iChannel0", 2D) = "white" {}  
    //        iChannelResolution0 ("iChannelResolution0", Vector) = (10, 10, 0, 0)
        }
    
        CGINCLUDE    
            #include "UnityCG.cginc"   
            #pragma target 3.0      
    
            #define vec2 float2
            #define vec3 float3
            #define vec4 float4
            #define mat2 float2x2
            #define mat3 float3x3
            #define mat4 float4x4
            #define iTime _Time.y
            // fmod用于求余数,比如fmod(1.5, 1.0) 返回0.5;
            #define mod fmod
            // 插值运算,lerp(a,b,w) return a + w*(a-b);
            #define mix lerp
            // fract(x): 取小数部分 
            #define fract frac
            #define texture2D tex2D
            // 屏幕的尺寸
            #define iResolution _ScreenParams
            // 屏幕中的坐标,以pixel为单位.(_iParam.scrPos.xy/_iParam.scrPos.w)在屏幕中归一化后的屏幕位置,即返回分量范围在(0, 1)的屏幕横纵坐标值。屏幕的左下角值为(0, 0),右上角值为(1, 1)。
            #define gl_FragCoord ((_iParam.scrPos.xy/_iParam.scrPos.w) * _ScreenParams.xy)
    
            #define PI2 6.28318530718
            #define pi 3.14159265358979
            #define halfpi (pi * 0.5)
            #define oneoverpi (1.0 / pi)
    
            fixed4 iMouse;
    //        sampler2D iChannel0;
    //        fixed4 iChannelResolution0;
    
            struct v2f {    
                float4 pos : SV_POSITION;    
                float4 scrPos : TEXCOORD0;   
            };              
    
            //ComputeScreenPos是在UnityCG.cginc中定义的函数,它就作用如名字一样,计算该顶点转换到屏幕上的位置
            v2f vert(appdata_base v) {  
                v2f o;
                o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                o.scrPos = ComputeScreenPos(o.pos);
                return o;
            }  
    
            vec4 main(vec2 fragCoord);
    
            fixed4 frag(v2f _iParam) : COLOR0 { 
                vec2 fragCoord = gl_FragCoord;
    //            vec2 pos =fragCoord.xy / iResolution.xy * 2. - 1.;
                return main(fragCoord);
            } 
             
            ////////////////////////////////////////////////////////////////////
            //  https://www.shadertoy.com/view/4sfGzS
            mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
            {
                vec3 cw = normalize(ta-ro);
                vec3 cp = vec3(sin(cr), cos(cr),0.0);
                vec3 cu = normalize( cross(cw,cp) );
                vec3 cv = normalize( cross(cu,cw) );
                return mat3( cu, cv, cw );
            }
    
            vec3 sundir = normalize( vec3(-1.0,0.0,-1.0) );
    
            #define MARCH(STEPS,MAPLOD) for(int i=0; i<STEPS; i++) { vec3  pos = ro + t*rd; if( pos.y<-3.0 || pos.y>2.0 || sum.a > 0.99 ) break; float den = MAPLOD( pos ); if( den>0.01 ) { float dif =  clamp((den - MAPLOD(pos+0.3*sundir))/0.6, 0.0, 1.0 ); sum = integrate( sum, dif, den, bgcol, t ); } t += max(0.05,0.02*t); }
    
            float iqhash( float n )
            {
                return fract(sin(n)*43758.5453);
            }
    
            float noise( vec3 x )
            {
            // The noise function returns a value in the range -1.0f -> 1.0f
            vec3 p = floor(x);
            vec3 f = fract(x);
    
            f       = f*f*(3.0-2.0*f);
            float n = p.x + p.y*57.0 + 113.0*p.z;
            return mix(mix(mix( iqhash(n+0.0  ), iqhash(n+1.0  ),f.x),
                           mix( iqhash(n+57.0 ), iqhash(n+58.0 ),f.x),f.y),
                       mix(mix( iqhash(n+113.0), iqhash(n+114.0),f.x),
                           mix( iqhash(n+170.0), iqhash(n+171.0),f.x),f.y),f.z);
            }
    
            float map5( in vec3 p )
            {
                vec3 q = p - vec3(0.0,0.1,1.0)*iTime;
    
                float f;
    
                f  = 0.50000*noise( q ); q = q*2.02;
                f += 0.25000*noise( q ); q = q*2.03;
                f += 0.12500*noise( q ); q = q*2.01;
                f += 0.06250*noise( q ); q = q*2.02;
                f += 0.03125*noise( q );
                return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
            }
            float map4( in vec3 p )
            {
                vec3 q = p - vec3(0.0,0.1,1.0)*iTime;
                float f;
                f  = 0.50000*noise( q ); q = q*2.02;
                f += 0.25000*noise( q ); q = q*2.03;
                f += 0.12500*noise( q ); q = q*2.01;
                f += 0.06250*noise( q );
                return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
            }
            float map3( in vec3 p )
            {
                vec3 q = p - vec3(0.0,0.1,1.0)*iTime;
                float f;
                f  = 0.50000*noise( q ); q = q*2.02;
                f += 0.25000*noise( q ); q = q*2.03;
                f += 0.12500*noise( q );
                return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
            }
            float map2( in vec3 p )
            {
                vec3 q = p - vec3(0.0,0.1,1.0)*iTime;
                float f;
                f  = 0.50000*noise( q ); q = q*2.02;
                f += 0.25000*noise( q );;
                return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
            }
    
            vec4 integrate( in vec4 sum, in float dif, in float den, in vec3 bgcol, in float t )
            {
                // lighting
                vec3 lin = vec3(0.65,0.7,0.75)*1.4 + vec3(1.0, 0.6, 0.3)*dif;        
                vec4 col = vec4( mix( vec3(1.0,0.95,0.8), vec3(0.25,0.3,0.35), den ), den );
                col.xyz *= lin;
                col.xyz = mix( col.xyz, bgcol, 1.0-exp(-0.003*t*t) );
                // front to back blending    
                col.a *= 0.4;
                col.rgb *= col.a;
                return sum + col*(1.0-sum.a);
            }
    
            vec4 raymarch( in vec3 ro, in vec3 rd, in vec3 bgcol, in int2 px )
            {
                vec4 sum = vec4(0.0,0.0,0.0,0.0);
    
                float t = 0.0;//0.05*texelFetch( iChannel0, px&255, 0 ).x;
    
                MARCH(30,map5);
                MARCH(30,map4);
                MARCH(30,map3);
                MARCH(30,map2);
                //clamp(x,min,max),min(max(x, min), max),
                //if  min < x < max , return x;
                //if x < min , return min;
                //if x > max , return max;
                return clamp( sum, 0.0, 1.0 );
            }
    
            //得到像素点的颜色值
            vec4 render( in vec3 ro, in vec3 rd, in int2 px )
            {
                // background sky 
                // dot 点积,各分量分别相乘 后 相加    
                float sun = clamp( dot(sundir,rd), 0.0, 1.0 );
                vec3 col = vec3(0.6,0.71,0.75) - rd.y*0.2*vec3(1.0,0.5,1.0) + 0.15*0.5;
                col += 0.2*vec3(1.0,.6,0.1)*pow( sun, 8.0 );
    
                // clouds    
                vec4 res = raymarch( ro, rd, col, px );
                col = col*(1.0-res.w) + res.xyz;
                
                // sun glare 
                // pow(x, y): x的y次方;   
                col += 0.2*vec3(1.0,0.4,0.2)*pow( sun, 3.0 );
    
                return vec4( col, 1.0 );
            }
    
            vec4 main(vec2 fragCoord) {
                //iResolution:screen size
                //fragCoord:在屏幕上的位置,单位pixel
                 vec2 p = (-iResolution.xy + 2.0*fragCoord.xy)/ iResolution.y;
    
                vec2 m = iMouse.xy/iResolution.xy;
            
                //camera
                vec3 ro = 4.0*normalize(vec3(sin(3.0*m.x), 0.4*m.y, cos(3.0*m.x)));
                vec3 ta = vec3(0.0, -1.0, 0.0);
                mat3 ca = setCamera( ro, ta, 0.0 );
                //ray
                vec3 rd = mul(ca , normalize( vec3(p.xy,1.5)));
                //fragCoord屏幕像素位置.
                vec2 pos = fragCoord.xy / iResolution.xy;
                return render( ro, rd, int2(fragCoord-0.5) ); 
            }
        ////////////////////////////////////////////////////////////////////
    
        ENDCG    
    
        SubShader {    
            Pass {    
                CGPROGRAM    
    
                #pragma vertex vert    
                #pragma fragment frag    
                #pragma fragmentoption ARB_precision_hint_fastest     
    
                ENDCG    
            }    
        }     
        FallBack Off    
    }

    参考了乐乐(candycat)的博客,想深入学习shader的可以多看看她的博客和书,很多干货,然后就是https://msdn.microsoft.com/en-us/library/windows/apps/dn166865.aspx,GLSL转HLSL参考文档。

    还有一个人一定要说,shaderToy网站上的iq,创造了好多shader,效果非常非常赞。

    最后有两个东西没解决,textureLod,和texelFetch这两个函数怎么映射到unity?

  • 相关阅读:
    改善ERP的用户体验,个性化用户界面(Jquery 提供源码)
    一个美国富人在洗手间里陪女佣孩子吃晚餐的故事
    easyui datagrid 批量 提交 json 数据到服务器
    XML基础
    Asp.Net 上传大文件专题(1)概述:上传大文件的难点
    Asp.Net 上传大文件专题(3)从请求流中获取数据并保存为文件[下]
    Asp.Net上传大文件系列
    Asp.Net 上传大文件专题(3)从请求流中获取数据并保存为文件[上]
    XM操作类
    Asp.Net 上传大文件专题(4)利用ajax技术显示上传进度
  • 原文地址:https://www.cnblogs.com/leeplogs/p/7327551.html
Copyright © 2011-2022 走看看