water shader

水 shader
_WaveMap(“Normal”)
_Tiling

_WaveBumpScale
_WavaBumpSpeed() 水流动的方向

_DeepTex 获取深度 r通道(深度因素) g透明度因素(用深度图计算软边的时候需要) 用实时软边的话,透明度用_Color0.a

  1. _Color0 反射颜色 a通道控制透明度
    _Color1 折射颜色 a 通道控制折射的强度

    // 最基本的颜色通过Fresnel来混合两个基本颜色
    //fixed fresnel = pow(saturate(dot(viewDir, bump)), 0.3);
    fixed fresnel = saturate(dot(viewDir, bump));
    fixed3 finalColor = lerp(_Color0,_Color1,fresnel);

    出自
    fixed fresnel = _FresnelScale + (1 - _FresnelScale) * pow(1 - dot(worldView, worldNormal), 5);
    lerp(diffuse, reflection, saturate(fresnel))

    也有版本color0和color1分别为深色、浅色,根据深度混合

  2. 折射:
    vs里,计算坐标:
    o.pos = UnityObjectToClipPos(v.vertex);

    // 屏幕位置
    o.scrPos = ComputeScreenPos(o.pos);
    函数具体分析可见:https://chengkehan.github.io/ComputeScreenPos.html

    unity注释:Computes texture coordinate for doing a screenspace-mapped texture sample. Input is clip space position.
    COMPUTE_EYEDEPTH(o.scrPos.z);

    // grabUV
    o.uvgrab =ComputeGrabScreenPos(o.pos);
    unity注释:Computes texture coordinate for sampling a GrabPass texure. Input is clip space position.
    冯乐乐书说:我们通过内置的ComputeGrabScreenPos函数来得到对应被抓取的屏幕图像的采样坐标。可以在UnityCG.cginc文件中看到其定义:他的主要代码和ComputeScreenPos基本类似,最大的不同是针对平台差异造成的采样坐标问题

    inline float4 ComputeGrabScreenPos (float4 pos) {
    #if UNITY_UV_STARTS_AT_TOP
    float scale = -1.0;
    #else
    float scale = 1.0;
    #endif
    float4 o = pos * 0.5f;
    o.xy = float2(o.x, o.y*scale) + o.w;
    o.zw = pos.zw;
    return o;
    }
    inline float4 ComputeNonStereoScreenPos(float4 pos) {
    float4 o = pos * 0.5f;
    #if defined(UNITY_HALF_TEXEL_OFFSET)
    o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w * _ScreenParams.zw;
    #else
    o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w;
    #endif
    o.zw = pos.zw;
    return o;
    }

    inline float4 ComputeScreenPos (float4 pos) {
    float4 o = ComputeNonStereoScreenPos(pos);
    #ifdef UNITY_SINGLE_PASS_STEREO
    o.xy = TransformStereoScreenSpaceTex(o.xy, pos.w);
    #endif
    return o;
    }

    fs中,bump是法线空间,在法线空间下计算折射偏移
    i.uvgrab.xy += bump.xy * _DistortionFactor * i.uvgrab.w * _GrabTexture_TexelSize.xy;
    fixed3 grapColor = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    水折射偏移 grapColor即为折射光颜色。

    然后将2种颜色混合后的结构与折射颜色混合

  3. 软边 获取深度(实时软边还是用深度图)
    遇到bug,有的地方sceneZ小于objectZ,发现是由于没有深度贴图的原因。

half4 projTC = UNITY_PROJ_COORD(i.scrPos);    
    #ifdef USE_SOFTEDGE
    // 边缘查找             
    //float sceneZ      = LinearEyeDepth (tex2Dproj(_LastCameraDepthTexture, UNITY_PROJ_COORD(i.scrPos)).r);
    //srcPosRe.x *=_ScreenParams.x/_ScreenParams.y;

    float sceneZ        = LinearEyeDepth (tex2Dproj(_LastCameraDepthTexture, projTC).r);
    float objectZ       = i.scrPos.z;

    // 通过深度混合扭曲后的GrapTexture
    depthFactor   = saturate((sceneZ - objectZ) / _DepthFactor);//saturate(objectZ / _DepthFactor);
    #else
        fixed3 waterMap =tex2D(_MainTex, TRANSFORM_TEX(i.uv.xy, _MainTex)).rgb;
        depthFactor = saturate(waterMap.r+_InvRanges.y);
        _Color0.a *=saturate(waterMap.g*_InvRanges.z +_InvRanges.x);
    #endif
  1. 高光相关
    _SpecColor
    _Shininess 高光相关

  2. 反射
    _Cubemap
    _CubemapInstensity

实时反射 _ReflectionTex

fixed3 reflDir      = reflect(-viewDir, bump);
                fixed3 reflCol;
    fixed3 reflection1 =texCUBE(_Cubemap, reflDir).rgb *_CubemapInstensity;
    half refDis = _RefDisFactor  * projTC.w * _ReflectionTex_TexelSize.xy;

                projTC.x += bump.x *refDis;
                //projTC.y += 0.5*bump.y *refDis;       
                fixed4 reflection2 = tex2Dproj(_ReflectionTex, projTC);

                reflCol =lerp(reflection1.rgb,reflection2.rgb,reflection2.a*depthFactor);

//天空盒和实时反射贴图 通过深度和反射贴图的a通道混合

非实时反射
reflCol =texCUBE(_Cubemap, reflDir).rgb *_CubemapInstensity;

然后计算 反射的比例
finalColor +=reflCol*_ReflectVal*depthFactor;

  1. finalCol += spec;
    然后 finalCol *= _InvRanges.w.
    加雾效 透明度是_Color0.a.
    输出

几部分混合:
1. color0和color1用viewDotN混合;
2. 将GrabCol和得到的通过depthFactor混合;
3. 反射和已有相加,反射的强度用depthFactor和_ReflectVal控制;cubemap和实时反射用depthFactor和实时反射贴图的a通道控制。
4. 最后加上高光反射。

原来的水的版本:
(1)深度计算:

// Calculate the depth difference at the current pixel
float depth = tex2Dproj(_CameraDepthTexture, IN.proj0).r;
depth = LinearEyeDepth(depth);
depth -= IN.proj0.z;

深度和几个参数都有关系(ranges的x控制透明度、高光强度,折射偏移、折射和反射混合的菲涅尔,y控制两个颜色混合的参数,z控制折射的混合,折射也被y控制)

        // Calculate the color tint
        half4 col;
        col.rgb = lerp(_Color1.rgb, _Color0.rgb, ranges.y);
        col.a = ranges.x;

// Initial material properties
o.Alpha = col.a;
o.Specular = col.a;
o.Gloss = _Shininess;
IN.proj0.xy += o.Normal.xy * 0.5;
half3 reflection = tex2Dproj(_ReflectionTex, IN.proj0).rgb;
reflection = lerp(reflection * col.rgb, reflection, fresnel * _ReflectionTint);
//反射还用到ReflectionTint控制。

//折射用ranges.z 和ranges。控制
// High-quality refraction uses the grab pass texture
IN.proj1.xy += o.Normal.xy * _GrabTexture_TexelSize.xy * (20.0 * IN.proj1.z * col.a);
half3 refraction = tex2Dproj(_GrabTexture, IN.proj1).rgb;
refraction = lerp(refraction, refraction * col.rgb, ranges.z);
// Color the refraction based on depth
refraction = lerp(lerp(col.rgb, col.rgb * refraction, ranges.y), refraction, ranges.y);

//折射和反射的混合也和深度有关
// Always assume 20% reflection right off the bat, and make the fresnel fade out slower so there is more refraction overall
fresnel = fresnel fresnel;
fresnel = (0.8 * fresnel + 0.2) * col.a;

        // Calculate the initial material color
        o.Albedo = lerp(refraction, reflection, fresnel) + foam;
### 回答1: Unity stylized water shader是一种在Unity游戏引擎中使用的水渲染效果。这种水渲染效果不仅可以模拟真实的水体效果,还能够通过调整参数和使用特定的材质来实现卡通或艺术风格的水体效果。 Unity stylized water shader使用了一些特殊的技术和算法来实现其独特的效果。其中一个关键的技术是反射和折射,能够让水体在不同角度和不同光照条件下呈现出不同的颜色和形状。还有一个重要的技术是波纹效果,可以通过调整参数来创建逼真的波动效果,使水体看起来更加生动。 除了基本的水体效果,Unity stylized water shader还可以通过添加特定的材质和纹理来实现不同的艺术风格。例如,可以使用卡通风格的材质来创建漫画或动画风格的水体效果,或者使用手绘风格的纹理来仿真手绘的效果。这种灵活性使得开发者能够根据游戏的风格和需求来自定义水体的外观。 总之,Unity stylized water shader是一种功能强大的水渲染效果,能够在Unity游戏引擎中实现逼真或者艺术风格的水体效果。开发者可以通过调整参数和使用特定的材质来实现自己想要的效果,从而提升游戏的视觉体验和吸引力。 ### 回答2: Unity风格化水渲染器是一种用于模拟真实或艺术化水体效果的着色器。它可以在Unity游戏引擎中使用,并可用于创建各种风格的水体,例如卡通风格、像素风格或艺术性风格。 Unity风格化水渲染器通过在水表面上添加纹理、光照和反射效果来模拟水的外观。它可以实现波纹、透明度、折射以及反射等特性,从而使水体看起来更加逼真和具有视觉吸引力。 创造一个unity风格化水渲染器通常需要以下几个步骤: 首先,你需要创建一个水体模型或平面,用于表示水的表面。可以使用Unity内置的工具或第三方建模软件来创建模型或平面。 然后,你需要在着色器中定义一个用于绘制水体的材质。这个材质将用于控制水的外观和效果。你可以设置颜色、纹理、水的透明度以及其他特性。 接下来,你需要编写一个着色器程序,用于渲染水体。这个程序将定义如何根据材质和模型来绘制水体。你可以使用Unity内置的着色器语言或其他编程语言来编写着色器程序。 最后,在Unity中将水体模型或平面应用给所创建的材质和着色器。这样,水体就可以在场景中显示出来,并且可以通过调整材质和着色器参数来修改它的外观和效果。 Unity风格化水渲染器是一个功能强大且灵活的工具,可以帮助游戏开发者实现各种风格的水体效果。通过调整材质和着色器参数,开发者可以创建出独特而生动的水景,提升游戏的视觉效果和沉浸感。 ### 回答3: Unity风格化水渲染器是一种在Unity引擎中使用的shader,用于创造逼真的水体效果。它通过模拟水体的折射、反射、波纹等特征,使得水的表现更加真实。风格化水渲染器通过调整shader的参数来控制水的外观,可根据不同的需求实现不同的风格,如卡通风格、像素化效果等。 在创建风格化水渲染器时,需要首先定义水体的颜色、透明度、反射强度等基本属性。然后,可以使用贴图来增加水体的细节,如生成波纹效果的法线贴图、用于反射效果的立方体贴图等。通过在shader中使用这些贴图,可以让水体看起来更加生动。 除了基本属性和贴图外,风格化水渲染器还可以通过添加其他特效来增强水体的真实感。例如,可以添加镜面反射效果,使得水面上的物体能够在水中倒影出来。同时,还可以添加光照效果,使得水的颜色随着光照的变化而变化,增加真实感。 总的来说,Unity风格化水渲染器是一种用于在Unity引擎中创建逼真水体效果的shader。通过调整shader的参数、使用贴图和添加特效,可以实现不同风格的水体表现。这个渲染器有助于增强游戏或虚拟现实应用中水体场景的真实感,提高用户体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值