RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 941107
Accepted
Dmitrii
Dmitrii
Asked:2020-02-05 22:54:25 +0000 UTC2020-02-05 22:54:25 +0000 UTC 2020-02-05 22:54:25 +0000 UTC

两个着色器,屏幕空间中的一个纹理,对象上的另一个纹理

  • 772

有两个水着色器。两者都有一个字段_ReflectionTex ("Internal Reflection", 2D) = "" {}

当你将这些着色器挂在一个对象上并在这个字段中放置一个纹理时,画面就完全不同了——

第一个着色器 Oney 用此图像填充对象,并在其上拉伸。

第二个着色器 FX/Water 用图像填充屏幕空间——这个功能正是我们第一个着色器所需要的!

两个着色器的图像处理代码大致相同 - 它们在这里和那里都采用TEXTCOORD0,对其执行操作 half4 refl = tex2Dproj( _ReflectionTex, UNITY_PROJ_COORD(uv1) ); ,然后在原始纹理具有透明度的地方分配此纹理的值。一般来说,水中的倒影。但同样,效果完全不同。

我想让 Oney 着色器在保持其所有功能的同时,能够将纹理应用到屏幕空间(而不是一个对象),就像 FX / Water 着色器成功完成的那样

代码如下,为了节省一些空间,它被剪掉了一点。因此,如果缺少几个变量——正因为如此,源代码大约会大一倍半。

Shader "Oney" {  //Всем хорош, но не может в наложение текстур на экран. 
    Properties {
        _Color ("Color", Color) = (0.7016652,0.8427501,0.9264706,1)
        _Color_Waves ("Color_Waves", Color) = (0.1096453,0.3823529,0.2920773,1)
        _Normal_1 ("Normal_1", 2D) = "bump" {}
        _Normal_2 ("Normal_2", 2D) = "bump" {}
        _Waves ("Waves", 2D) = "white" {}
        _CubMap ("CubMap", Cube) = "_Skybox" {}
        _Intensity_Waves ("Intensity_Waves", Range(0, 50)) = 10
        _Speed ("Speed", Range(0, 1)) = 0.1
        _Intensity_Color ("Intensity_Color", Range(0, 10)) = 5
        _Spec ("Spec", Range(0, 2)) = 1
        _Gloss ("Gloss", Range(0, 2)) = 1
        _Reflection ("Reflection", Range(0, 2)) = 0
         _ReflectionTex ("Internal Reflection", 2D) = "" {}
    }
    SubShader {
        Tags {
            "RenderType"="Opaque"
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }


            CGPROGRAM

            uniform sampler2D _Normal_2; uniform float4 _Normal_2_ST;
            uniform float _Intensity_Color;
            uniform float4 _Color_Waves;
            uniform float _Speed;
            uniform samplerCUBE _CubMap;
            uniform float _Reflection;
            struct VertexInput {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
                float4 texcoord0 : TEXCOORD0;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
                float4 uv0 : TEXCOORD0;
                float4 posWorld : TEXCOORD1;
                float3 normalDir : TEXCOORD2;
                float3 tangentDir : TEXCOORD3;
                float3 bitangentDir : TEXCOORD4;
                LIGHTING_COORDS(5,6)
                UNITY_FOG_COORDS(7)
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.uv0 = v.texcoord0;
                o.normalDir = UnityObjectToWorldNormal(v.normal);
                o.tangentDir = normalize( mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );
                o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
                float4 node_9273 = _Time + _TimeEditor;
                float2 node_9735 = (o.uv0+(node_9273.r*_Speed)*float2(0,1));
                float4 _Waves_var = tex2Dlod(_Waves,float4(TRANSFORM_TEX(node_9735, _Waves),0.0,0));
                v.vertex.xyz += (_Waves_var.r*v.normal*_Intensity_Waves);
                o.posWorld = mul(unity_ObjectToWorld, v.vertex);
                float3 lightColor = _LightColor0.rgb;
                o.pos = UnityObjectToClipPos(v.vertex );
                UNITY_TRANSFER_FOG(o,o.pos);
                TRANSFER_VERTEX_TO_FRAGMENT(o)
                return o;
            }
            sampler2D _ReflectionTex;
            float4 frag(VertexOutput i) : COLOR {
                i.normalDir = normalize(i.normalDir);
                float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
                float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
                float4 node_1446 = _Time + _TimeEditor;
                float2 node_4184 = (i.uv0+node_1446.g*float2(0.0002,0.0001));
                float3 _Normal_1_var = UnpackNormal(tex2D(_Normal_1,TRANSFORM_TEX(node_4184, _Normal_1)));
                float2 node_5576 = (i.uv0+node_1446.g*float2(0.0002,-0.0001));
                float3 _Normal_2_var = UnpackNormal(tex2D(_Normal_2,TRANSFORM_TEX(node_5576, _Normal_2)));



                float3 normalLocal = (_Normal_1_var.rgb+_Normal_2_var.rgb);
                //Expiremental
                float4 uv1 = i.uv0;
                half4 refl = tex2Dproj( _ReflectionTex, UNITY_PROJ_COORD(uv1) );



                float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
                float3 viewReflectDirection = reflect( -viewDirection, normalDirection );
                float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
                float3 lightColor = _LightColor0.rgb;
                float3 halfDirection = normalize(viewDirection+lightDirection);

/// Final Color:
                float3 finalColor = diffuse + specular + emissive;
               fixed4 finalRGBA = fixed4(finalColor,1);
           finalRGBA.rgb = lerp( finalColor.rgb, refl.rgb, 1);              finalRGBA.a = refl.a;
                UNITY_APPLY_FOG(i.fogCoord, finalRGBA);
                return finalRGBA;
            }
            ENDCG

第二个着色器,FX/水

Shader "FX/Water" { // Умеет класть текстуру прямо на экран!
Properties {
    _WaveScale ("Wave scale", Range (0.002,0.15)) = 0.063
    _ReflDistort ("Reflection distort", Range (0,15)) = 0.44
    [NoScaleOffset] _Fresnel ("Fresnel (A) ", 2D) = "gray" {}
    [NoScaleOffset] _BumpMap ("Normalmap ", 2D) = "bump" {}
    WaveSpeed ("Wave speed (map1 x,y; map2 x,y)", Vector) = (19,9,-16,-7)
    [NoScaleOffset] _ReflectiveColor ("Reflective color (RGB) fresnel (A) ", 2D) = "" {}
    _HorizonColor ("Simple water horizon color", COLOR)  = ( .172, .463, .435, 1)
     _ReflectionTex ("Internal Reflection", 2D) = "" {}
}


// -----------------------------------------------------------
// Fragment program cards


Subshader {
    Tags { "WaterMode"="Refractive" "RenderType"="Opaque" }
    Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog




#include "UnityCG.cginc"

struct appdata {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
};

struct v2f {
    float4 pos : SV_POSITION;
    #if defined(HAS_REFLECTION) || defined(HAS_REFRACTION)
        float4 ref : TEXCOORD0;
        float2 bumpuv0 : TEXCOORD1;
        float2 bumpuv1 : TEXCOORD2;
        float3 viewDir : TEXCOORD3;
    #else
        float2 bumpuv0 : TEXCOORD0;
        float2 bumpuv1 : TEXCOORD1;
        float3 viewDir : TEXCOORD2;
    #endif
    UNITY_FOG_COORDS(4)
};

v2f vert(appdata v)
{
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);


    // scroll bump waves
    float4 temp;
    float4 wpos = mul (unity_ObjectToWorld, v.vertex);
    temp.xyzw = wpos.xzxz * _WaveScale4 + _WaveOffset;
    o.bumpuv0 = temp.xy;
    o.bumpuv1 = temp.wz;

    // object space view direction (will normalize per pixel)
    o.viewDir.xzy = WorldSpaceViewDir(v.vertex);

    #if defined(HAS_REFLECTION) || defined(HAS_REFRACTION)
    o.ref = ComputeNonStereoScreenPos(o.pos);
    #endif

    UNITY_TRANSFER_FOG(o,o.pos);
    return o;
}

sampler2D _ReflectionTex;



half4 frag( v2f i ) : SV_Target
{
    i.viewDir = normalize(i.viewDir);

    // combine two scrolling bumpmaps into one
    half3 bump1 = UnpackNormal(tex2D( _BumpMap, i.bumpuv0 )).rgb;
    half3 bump2 = UnpackNormal(tex2D( _BumpMap, i.bumpuv1 )).rgb;
    half3 bump = (bump1 + bump2) * 0.5;

    // fresnel factor
    half fresnelFac = dot( i.viewDir, bump );

    // perturb reflection/refraction UVs by bumpmap, and lookup colors

    float4 uv1 = i.ref; uv1.xy += bump * _ReflDistort;
    half4 refl = tex2Dproj( _ReflectionTex, UNITY_PROJ_COORD(uv1) );


    // final color is between refracted and reflected based on fresnel
    half4 color;

    half4 water = tex2D( _ReflectiveColor, float2(fresnelFac,fresnelFac) );
    color.rgb = lerp( water.rgb, refl.rgb, water.a );
    color.a = refl.a * water.a;


    UNITY_APPLY_FOG(i.fogCoord, color);
    return color;
}
ENDCG

    }
}

}
unity3d
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Dmitrii
    2020-02-07T18:38:48Z2020-02-07T18:38:48Z

    案例结果是在一个命令中,它将所有内容都转换为屏幕坐标

    o.ref = ComputeNonStereoScreenPos(o.pos);
    

    将它应用到第一个着色器的顶点部分,我们得到了我们需要的结果。只需要ref取一个类似的变量TEXTCOORD0

    o.uv0 = ComputeNonStereoScreenPos(o.uv0);
    

    因此,所需着色器的最终代码

    Shader "Oney" {  //Всем хорош, но не может в наложение текстур на экран. 
        Properties {
            _Color ("Color", Color) = (0.7016652,0.8427501,0.9264706,1)
            _Color_Waves ("Color_Waves", Color) = (0.1096453,0.3823529,0.2920773,1)
            _Normal_1 ("Normal_1", 2D) = "bump" {}
            _Normal_2 ("Normal_2", 2D) = "bump" {}
            _Waves ("Waves", 2D) = "white" {}
            _CubMap ("CubMap", Cube) = "_Skybox" {}
            _Intensity_Waves ("Intensity_Waves", Range(0, 50)) = 10
            _Speed ("Speed", Range(0, 1)) = 0.1
            _Intensity_Color ("Intensity_Color", Range(0, 10)) = 5
            _Spec ("Spec", Range(0, 2)) = 1
            _Gloss ("Gloss", Range(0, 2)) = 1
            _Reflection ("Reflection", Range(0, 2)) = 0
             _ReflectionTex ("Internal Reflection", 2D) = "" {}
        }
        SubShader {
            Tags {
                "RenderType"="Opaque"
            }
            Pass {
                Name "FORWARD"
                Tags {
                    "LightMode"="ForwardBase"
                }
    
    
                CGPROGRAM
    
                uniform sampler2D _Normal_2; uniform float4 _Normal_2_ST;
                uniform float _Intensity_Color;
                uniform float4 _Color_Waves;
                uniform float _Speed;
                uniform samplerCUBE _CubMap;
                uniform float _Reflection;
                struct VertexInput {
                    float4 vertex : POSITION;
                    float3 normal : NORMAL;
                    float4 tangent : TANGENT;
                    float4 texcoord0 : TEXCOORD0;
                };
                struct VertexOutput {
                    float4 pos : SV_POSITION;
                    float4 uv0 : TEXCOORD0;
                    float4 posWorld : TEXCOORD1;
                    float3 normalDir : TEXCOORD2;
                    float3 tangentDir : TEXCOORD3;
                    float3 bitangentDir : TEXCOORD4;
                    LIGHTING_COORDS(5,6)
                    UNITY_FOG_COORDS(7)
                };
                VertexOutput vert (VertexInput v) {
                    VertexOutput o = (VertexOutput)0;
                    o.uv0 = v.texcoord0;
                    o.normalDir = UnityObjectToWorldNormal(v.normal);
                    o.tangentDir = normalize( mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );
                    o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
                    float4 node_9273 = _Time + _TimeEditor;
                    float2 node_9735 = (o.uv0+(node_9273.r*_Speed)*float2(0,1));
                    float4 _Waves_var = tex2Dlod(_Waves,float4(TRANSFORM_TEX(node_9735, _Waves),0.0,0));
                    v.vertex.xyz += (_Waves_var.r*v.normal*_Intensity_Waves);
                    o.posWorld = mul(unity_ObjectToWorld, v.vertex);
                    float3 lightColor = _LightColor0.rgb;
                    o.uv0 = ComputeNonStereoScreenPos(o.uv0);<---Добавляем этот кусок кода сюда
                    o.pos = UnityObjectToClipPos(v.vertex );
                    UNITY_TRANSFER_FOG(o,o.pos);
                    TRANSFER_VERTEX_TO_FRAGMENT(o)
                    return o;
                }
                sampler2D _ReflectionTex;
                float4 frag(VertexOutput i) : COLOR {
                    i.normalDir = normalize(i.normalDir);
                    float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
                    float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
                    float4 node_1446 = _Time + _TimeEditor;
                    float2 node_4184 = (i.uv0+node_1446.g*float2(0.0002,0.0001));
                    float3 _Normal_1_var = UnpackNormal(tex2D(_Normal_1,TRANSFORM_TEX(node_4184, _Normal_1)));
                    float2 node_5576 = (i.uv0+node_1446.g*float2(0.0002,-0.0001));
                    float3 _Normal_2_var = UnpackNormal(tex2D(_Normal_2,TRANSFORM_TEX(node_5576, _Normal_2)));
    
    
    
                    float3 normalLocal = (_Normal_1_var.rgb+_Normal_2_var.rgb);
                    //Expiremental
                    float4 uv1 = i.uv0;
                    half4 refl = tex2Dproj( _ReflectionTex, UNITY_PROJ_COORD(uv1) );
    
    
    
                    float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals
                    float3 viewReflectDirection = reflect( -viewDirection, normalDirection );
                    float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
                    float3 lightColor = _LightColor0.rgb;
                    float3 halfDirection = normalize(viewDirection+lightDirection);
    
    /// Final Color:
                    float3 finalColor = diffuse + specular + emissive;
                   fixed4 finalRGBA = fixed4(finalColor,1);
               finalRGBA.rgb = lerp( finalColor.rgb, refl.rgb, 1);              finalRGBA.a = refl.a;
                    UNITY_APPLY_FOG(i.fogCoord, finalRGBA);
                    return finalRGBA;
    
    • -1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5