统一使用着色器实现水效果,但我需要着色器三角形的法线和位置而不是网格

Unity using shader for water effect but I need the normal and location of the shader triangle not the mesh

我正在开发一个游戏,我买了一个水着色器,我现在正赶时间学习它。我正在用水和船做游戏。我需要船只响应光线投射命中位置的水着色器顶点法线。坦率地说,我只是不知道自己在做什么,我将不胜感激任何帮助。 着色器

Shader "StylizedWater/Mobile"
{
    Properties
    {
        [HDR]_WaterColor("Water Color", Color) = (0.1176471,0.6348885,1,0)
        [HDR]_WaterShallowColor("WaterShallowColor", Color) = (0.4191176,0.7596349,1,0)
        _Wavetint("Wave tint", Range( -1 , 1)) = 0
        [HDR]_RimColor("Rim Color", Color) = (1,1,1,0.5019608)
        _NormalStrength("NormalStrength", Range( 0 , 1)) = 0.25
        _Transparency("Transparency", Range( 0 , 1)) = 0.75
        _Glossiness("Glossiness", Range( 0 , 1)) = 0.85
        [Toggle]_Worldspacetiling("Worldspace tiling", Float) = 1
        _NormalTiling("NormalTiling", Range( 0 , 1)) = 0.9
        _EdgeFade("EdgeFade", Range( 0.01 , 3)) = 0.2448298
        _RimSize("Rim Size", Range( 0 , 20)) = 5
        _Rimfalloff("Rim falloff", Range( 0.1 , 50)) = 3
        _Rimtiling("Rim tiling", Float) = 0.5
        _FoamOpacity("FoamOpacity", Range( -1 , 1)) = 0.05
        _FoamSpeed("FoamSpeed", Range( 0 , 1)) = 0.1
        _FoamSize("FoamSize", Float) = 0
        _FoamTiling("FoamTiling", Float) = 0.05
        _Depth("Depth", Range( 0 , 100)) = 30
        _Wavesspeed("Waves speed", Range( 0 , 10)) = 0.75
        _WaveHeight("Wave Height", Range( 0 , 1)) = 0.5366272
        _WaveFoam("Wave Foam", Range( 0 , 10)) = 0
        _WaveSize("Wave Size", Range( 0 , 10)) = 0.1
        _WaveDirection("WaveDirection", Vector) = (1,0,0,0)
        [NoScaleOffset][Normal]_Normals("Normals", 2D) = "bump" {}
        [NoScaleOffset]_Shadermap("Shadermap", 2D) = "black" {}
        [Toggle(_USEINTERSECTIONFOAM_ON)] _UseIntersectionFoam("UseIntersectionFoam", Float) = 0
        [Toggle]_ENABLE_VC("ENABLE_VC", Float) = 0
        [Toggle(_LIGHTING_ON)] _LIGHTING("LIGHTING", Float) = 0
        [Toggle]_Unlit("Unlit", Float) = 0
        _Metallicness("Metallicness", Range( 0 , 1)) = 0
        [Toggle(_NORMAL_MAP_ON)] _NORMAL_MAP("NORMAL_MAP", Float) = 0
        [Toggle]_USE_VC_INTERSECTION("USE_VC_INTERSECTION", Float) = 0
        [Toggle]_EnableDepthTexture("EnableDepthTexture", Float) = 1
        [HideInInspector] __dirty( "", Int ) = 1
    }

    SubShader
    {
        Tags{ "RenderType" = "Transparent"  "Queue" = "Transparent+0" "IgnoreProjector" = "True" "ForceNoShadowCasting" = "True" }
        LOD 200
        Cull Back
        CGPROGRAM
        #include "UnityPBSLighting.cginc"
        #include "UnityShaderVariables.cginc"
        #include "UnityCG.cginc"
        #pragma target 3.0
        #pragma multi_compile __ _LIGHTING_ON
        #pragma multi_compile __ _NORMAL_MAP_ON
        #pragma shader_feature _USEINTERSECTIONFOAM_ON
        #pragma fragmentoption ARB_precision_hint_fastest
        #pragma exclude_renderers xbox360 psp2 n3ds wiiu 
        #pragma surface surf StandardCustomLighting alpha:fade keepalpha noshadow nolightmap  nodynlightmap nodirlightmap nometa noforwardadd vertex:vertexDataFunc 
        struct Input
        {
            float3 worldPos;
            float4 screenPos;
            float4 vertexColor : COLOR;
            float2 vertexToFrag713;
            float2 vertexToFrag714;
            float3 worldRefl;
            INTERNAL_DATA
            float3 vertexToFrag746;
            float3 worldNormal;
        };

        struct SurfaceOutputCustomLightingCustom
        {
            half3 Albedo;
            half3 Normal;
            half3 Emission;
            half Metallic;
            half Smoothness;
            half Occlusion;
            half Alpha;
            Input SurfInput;
            UnityGIInput GIData;
        };

        uniform sampler2D _Normals;
        uniform sampler2D _Shadermap;
        uniform half _WaveHeight;
        uniform float _ENABLE_VC;
        uniform float _Worldspacetiling;
        uniform float _WaveSize;
        uniform float _Wavesspeed;
        uniform float4 _WaveDirection;
        uniform float _EnableDepthTexture;
        uniform sampler2D_float _CameraDepthTexture;
        uniform half _EdgeFade;
        uniform half _Transparency;
        uniform float _Depth;
        uniform half4 _WaterShallowColor;
        uniform float4 _RimColor;
        uniform float _USE_VC_INTERSECTION;
        uniform half _Rimfalloff;
        uniform float _Rimtiling;
        uniform half _RimSize;
        uniform float _NormalTiling;
        uniform half _NormalStrength;
        uniform half _Glossiness;
    

uniform float _Unlit;
        uniform half4 _WaterColor;
        uniform half _Wavetint;
        uniform half _FoamOpacity;
        uniform float _FoamTiling;
        uniform float _FoamSpeed;
        uniform half _FoamSize;
        uniform float _WaveFoam;
        uniform float _Metallicness;

        void vertexDataFunc( inout appdata_full v, out Input o )
        {
            UNITY_INITIALIZE_OUTPUT( Input, o );
            float3 ase_vertexNormal = v.normal.xyz;
            float4 VertexColors729 = lerp(float4( 0,0,0,0 ),v.color,_ENABLE_VC);
            float3 ase_worldPos = mul( unity_ObjectToWorld, v.vertex );
            float2 Tiling21 = lerp(( -20.0 * v.texcoord.xy ),( (ase_worldPos).xz * float2( 0.1,0.1 ) ),_Worldspacetiling);
            float2 appendResult500 = (float2(_WaveDirection.x , _WaveDirection.z));
            float2 WaveSpeed40 = ( ( _Wavesspeed * _Time.x ) * appendResult500 );
            float2 HeightmapUV581 = ( ( ( Tiling21 * _WaveSize ) * float2( 0.1,0.1 ) ) + ( WaveSpeed40 * float2( 0.5,0.5 ) ) );
            float4 tex2DNode94 = tex2Dlod( _Shadermap, float4( HeightmapUV581, 0, 1.0) );
            float temp_output_95_0 = ( saturate( ( _WaveHeight - (VertexColors729).b ) ) * tex2DNode94.g );
            float3 Displacement100 = ( ase_vertexNormal * temp_output_95_0 );
            v.vertex.xyz += Displacement100;
            o.vertexToFrag713 = lerp(( -20.0 * v.texcoord.xy ),( (ase_worldPos).xz * float2( 0.1,0.1 ) ),_Worldspacetiling);
            o.vertexToFrag714 = ( ( _Wavesspeed * _Time.x ) * appendResult500 );
            #if defined(LIGHTMAP_ON) && ( UNITY_VERSION < 560 || ( defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) ) )//aselc
            float4 ase_lightColor = 0;
            #else //aselc
            float4 ase_lightColor = _LightColor0;
            #endif //aselc
            o.vertexToFrag746 = ase_lightColor.rgb;
            
        }

        inline half4 LightingStandardCustomLighting( inout SurfaceOutputCustomLightingCustom s, half3 viewDir, UnityGI gi )
        {
            UnityGIInput data = s.GIData;
            Input i = s.SurfInput;
            half4 c = 0;
            //Start - Stylized Water custom depth
            float4 ase_screenPos = float4( i.screenPos.xyz , i.screenPos.w + 0.00000000001 );
            float4 ase_screenPosNorm = ase_screenPos / ase_screenPos.w;
            ase_screenPosNorm.z = ( UNITY_NEAR_CLIP_VALUE >= 0 ) ? ase_screenPosNorm.z : ase_screenPosNorm.z * 0.5 + 0.5;
            float screenDepth795 = LinearEyeDepth(UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture,UNITY_PROJ_COORD(ase_screenPos))));
            float distanceDepth795 =  ( screenDepth795 - LinearEyeDepth( ase_screenPosNorm.z ) ) / (  lerp( 1.0 , ( 1.0 / _ProjectionParams.z ) , unity_OrthoParams.w) );
            #if SHADER_API_MOBILE && UNITY_VERSION >= 20183 //Build only, abs() function causes offset in depth on mobile in 2018.3
            #else
            distanceDepth795 = abs(distanceDepth795);
            #endif
            //End - Stylized Water custom depth
            float DepthTexture494 = distanceDepth795;
            float ColorDepth479 = lerp(1.0,saturate( ( DepthTexture494 / _Depth ) ),_EnableDepthTexture);
            float4 VertexColors729 = lerp(float4( 0,0,0,0 ),i.vertexColor,_ENABLE_VC);
            float2 Tiling21 = i.vertexToFrag713;
            float2 temp_output_24_0 = ( Tiling21 * _Rimtiling );
            float2 WaveSpeed40 = i.vertexToFrag714;
            float temp_output_30_0 = ( tex2D( _Shadermap, ( ( 0.5 * temp_output_24_0 ) + WaveSpeed40 ) ).b * tex2D( _Shadermap, ( temp_output_24_0 + ( 1.0 - WaveSpeed40 ) ) ).b );
            float Intersection42 = saturate( ( _RimColor.a * ( 1.0 - ( ( ( lerp(lerp(1.0,DepthTexture494,_EnableDepthTexture),( 1.0 - (VertexColors729).r ),_USE_VC_INTERSECTION) / _Rimfalloff ) * temp_output_30_0 ) + ( lerp(lerp(1.0,DepthTexture494,_EnableDepthTexture),( 1.0 - (VertexColors729).r ),_USE_VC_INTERSECTION) / _RimSize ) ) ) ) );
            float Opacity121 = saturate( ( ( lerp(1.0,saturate( ( DepthTexture494 / _EdgeFade ) ),_EnableDepthTexture) * saturate( ( ( _Transparency * saturate( ( ColorDepth479 + _WaterShallowColor.a ) ) ) + Intersection42 ) ) ) - (VertexColors729).g ) );
            float3 ase_worldPos = i.worldPos;
            #if defined(LIGHTMAP_ON) && UNITY_VERSION < 560 //aseld
            float3 ase_worldlightDir = 0;
            #else //aseld
            float3 ase_worldlightDir = normalize( UnityWorldSpaceLightDir( ase_worldPos ) );
            #endif //aseld
            half3 _BlankNormal = half3(0,0,1);
            float2 temp_output_705_0 = ( _NormalTiling * Tiling21 );
            #ifdef _NORMAL_MAP_ON
                float2 staticSwitch760 = ( ( float2( 0.25,0.25 ) * temp_output_705_0 ) + WaveSpeed40 );
            #else
                float2 staticSwitch760 = float2( 0,0 );
            #endif
            #ifdef _NORMAL_MAP_ON
                float2 staticSwitch761 = ( temp_output_705_0 + ( 1.0 - WaveSpeed40 ) );
            #else
                float2 staticSwitch761 = float2( 0,0 );
            #endif
            #ifdef _NORMAL_MAP_ON
                float3 staticSwitch763 = ( ( UnpackNormal( tex2D( _Normals, staticSwitch760 ) ) + UnpackNormal( tex2D( _Normals, staticSwitch761 ) ) ) / float3( 2,2,2 ) );
            #else
                float3 staticSwitch763 = _BlankNormal;
            #endif
            float3 lerpResult621 = lerp( _BlankNormal , staticSwitch763 , _NormalStrength);
            float3 NormalMap52 = lerpResult621;
            float dotResult741 = dot( ase_worldlightDir , normalize( WorldReflectionVector( i , NormalMap52 ) ) );
            float GlossParam754 = _Glossiness;
            float3 lerpResult478 = lerp( (_WaterShallowColor).rgb , (_WaterColor).rgb , ColorDepth479);
            float3 WaterColor350 = lerpResult478;
            float2 HeightmapUV581 = ( ( ( Tiling21 * _WaveSize ) * float2( 0.1,0.1 ) ) + ( WaveSpeed40 * float2( 0.5,0.5 ) ) );
            float4 tex2DNode94 = tex2D( _Shadermap, HeightmapUV581 );
            float Heightmap99 = tex2DNode94.g;
            float3 temp_cast_0 = (( Heightmap99 * _Wavetint )).xxx;
            float3 RimColor102 = (_RimColor).rgb;
            float3 lerpResult61 = lerp( ( WaterColor350 - temp_cast_0 ) , ( RimColor102 * 3.0 ) , Intersection42);
            float2 temp_output_634_0 = ( WaveSpeed40 * _FoamSpeed );
            float4 tex2DNode67 = tex2D( _Shadermap, ( ( _FoamTiling * Tiling21 ) + temp_output_634_0 + ( Heightmap99 * 0.1 ) ) );
            #ifdef _USEINTERSECTIONFOAM_ON
                float staticSwitch725 = ( 1.0 - tex2DNode67.b );
            #else
                float staticSwitch725 = saturate( ( 1000.0 * ( ( tex2D( _Shadermap, ( ( _FoamTiling * ( Tiling21 * float2( 0.5,0.5 ) ) ) + temp_output_634_0 ) ).r - tex2DNode67.r ) - _FoamSize ) ) );
            #endif
            float Foam73 = ( _FoamOpacity * staticSwitch725 );
            float3 temp_cast_1 = (2.0).xxx;
            float FoamTex244 = staticSwitch725;
            float WaveFoam221 = saturate( ( pow( ( tex2DNode94.g * _WaveFoam ) , 2.0 ) * FoamTex244 ) );
            float3 lerpResult223 = lerp( ( lerpResult61 + Foam73 ) , temp_cast_1 , WaveFoam221);
            float3 FinalColor114 = lerpResult223;
            #ifdef _LIGHTING_ON
                float3 staticSwitch769 = float3( 0,0,0 );
            #else
                float3 staticSwitch769 = ( saturate( ( pow( max( 0.0 , dotResult741 ) , ( GlossParam754 * 128.0 ) ) * GlossParam754 ) ) + lerp(( i.vertexToFrag746 * FinalColor114 ),FinalColor114,_Unlit) );
            #endif
            float3 CustomLighting753 = staticSwitch769;
            SurfaceOutputStandard s733 = (SurfaceOutputStandard ) 0;
            s733.Albedo = FinalColor114;
            s733.Normal = WorldNormalVector( i , NormalMap52 );
            s733.Emission = float3( 0,0,0 );
            s733.Metallic = _Metallicness;
            s733.Smoothness = GlossParam754;
            s733.Occlusion = 1.0;

            data.light = gi.light;

            UnityGI gi733 = gi;
            #ifdef UNITY_PASS_FORWARDBASE
            Unity_GlossyEnvironmentData g733 = UnityGlossyEnvironmentSetup( s733.Smoothness, data.worldViewDir, s733.Normal, float3(0,0,0));
            gi733 = UnityGlobalIllumination( data, s733.Occlusion, s733.Normal, g733 );
            #endif

            float3 surfResult733 = LightingStandard ( s733, viewDir, gi733 ).rgb;
            surfResult733 += s733.Emission;

            #ifdef UNITY_PASS_FORWARDADD//733
            surfResult733 -= s733.Emission;
            #endif//733
            #ifdef _LIGHTING_ON
                float3 staticSwitch734 = surfResult733;
            #else
                float3 staticSwitch734 = CustomLighting753;
            #endif
            c.rgb = staticSwitch734;
            c.a = Opacity121;
            return c;
        }

        inline void LightingStandardCustomLighting_GI( inout SurfaceOutputCustomLightingCustom s, UnityGIInput data, inout UnityGI gi )
        {
            s.GIData = data;
        }

        void surf( Input i , inout SurfaceOutputCustomLightingCustom o )
        {
            o.SurfInput = i;
            o.Normal = float3(0,0,1);
        }

        ENDCG
    }
}

我的代码

private void FixedUpdate()
    {
        RaycastHit hit;
        LayerMask mask = LayerMask.GetMask("ignore");
        Physics.Raycast(transform.position, Vector3.down, out hit, Mathf.Infinity, mask);
        MeshCollider meshCollider = hit.collider as MeshCollider;
        if (!(meshCollider == null || meshCollider.sharedMesh == null))
        {
            Mesh mesh = meshCollider.sharedMesh;
            mesh.RecalculateNormals();
            Vector3[] normals = mesh.normals;
            int[] triangles = mesh.triangles;

            // Extract local space normals of the triangle we hit
            Vector3 n0 = normals[triangles[hit.triangleIndex * 3 + 0]];
            Vector3 n1 = normals[triangles[hit.triangleIndex * 3 + 1]];
            Vector3 n2 = normals[triangles[hit.triangleIndex * 3 + 2]];

            // interpolate using the barycentric coordinate of the hitpoint
            Vector3 baryCenter = hit.barycentricCoordinate;

            // Use barycentric coordinate to interpolate normal
            Vector3 interpolatedNormal = n0 * baryCenter.x + n1 * baryCenter.y + n2 * baryCenter.z;
            // normalize the interpolated normal
            interpolatedNormal = interpolatedNormal.normalized;

            // Transform local space normals to world space
            Transform hitTransform = hit.collider.transform;
            interpolatedNormal = hitTransform.TransformDirection(interpolatedNormal);

            // Display with Debug.DrawLine
            Debug.DrawRay(gameObject.transform.position, interpolatedNormal * 10f, Color.black);
        }
        //0-1 on max speed
        currentShipScalar = ((shipSpeed - (shipSpeed - Body.velocity.magnitude)) / (shipSpeed));

这只是 returns 网格法线而不是着色器。我用这个 enter link description here

和这个enter link description here

作为我的代码源。我觉得很蠢,我只是精疲力尽。我不喜欢这样,我还不明白发生了什么,但我有一个星期的最后期限。如有任何帮助,我们将不胜感激。

您使用的资产只是一个着色器。着色器内部顶点位置的变化仅在 GPU 上,CPU 无法访问。该资产还声明,它不支持浮力,所以它真的只是一个视觉的东西。

为了能够访问波形失真,您需要有一个计算着色器或一些其他预处理步骤来为您计算您的更改,这些更改随后会在您的波形着色器中使用。

More information on the same problem

可能值得看看另一个解决方案(也许 boat attack repo 会很合适),但我不知道你的目标设备和项目范围(我猜你在现在内置渲染器)。