适用UNITY URP的音频可视化着色器,支持VR,实现材质随音乐律动效果。

Yun 发布于 2025-10-26 220 次阅读


适合3D物体,如球体。

Shader "Custom/AudioReactiveSphere"
{
    Properties
    {
        _BaseColor ("Base Color", Color) = (0.2, 0.6, 1, 1)
        _PulseColor ("Pulse Color", Color) = (1, 0.2, 0.5, 1)
        _Displacement ("Displacement Strength", Range(0, 1)) = 0.2
        _LowBand ("Low Band", Float) = 0
        _MidBand ("Mid Band", Float) = 0
        _HighBand ("High Band", Float) = 0
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalRenderPipeline" }
        LOD 200

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing  // ← 必须添加!启用 instancing(VR 依赖)

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID // ← 可选但推荐
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                // ↓ 关键:自动处理 stereo 输出(包含 SV_RenderTargetArrayIndex)
                UNITY_VERTEX_OUTPUT_STEREO
            };

            float4 _BaseColor;
            float4 _PulseColor;
            float _Displacement;
            float _LowBand;
            float _MidBand;
            float _HighBand;

            v2f vert(appdata v)
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(v);          // ← 设置实例 ID
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); // ← 初始化 stereo(关键!)

                float displacement = _LowBand * _Displacement;
                v.vertex.xyz += v.normal * displacement;

                o.vertex = TransformObjectToHClip(v.vertex.xyz);
                o.uv = v.uv;
                return o;
            }

            half4 frag(v2f i) : SV_Target
            {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); // ← 可选(用于 per-eye logic)
                float pulse = _MidBand * 0.8 + _HighBand * 0.5;
                half4 color = lerp(_BaseColor, _PulseColor, pulse);
                return color;
            }
            ENDHLSL
        }
    }
}

扩展成适合粒子特效的音乐可视化shader。

Shader "Custom/AudioReactiveParticleURP_VR"
{
    Properties
    {
        _MainTex ("Particle Texture", 2D) = "white" {}
        _TintColor ("Tint Color", Color) = (1,1,1,1)
        _LowBand ("Low Band", Float) = 0.0
        _MidBand ("Mid Band", Float) = 0.0
        _HighBand ("High Band", Float) = 0.0
    }

    SubShader
    {
        Tags {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "RenderPipeline"="UniversalRenderPipeline"
        }
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
        Cull Off

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing          // 启用 instancing(VR 必需)
            #pragma multi_compile_fragment _ _GBUFFER_NORMALS

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                float4 color : COLOR;
                float2 uv : TEXCOORD0;
                float4 uv2 : TEXCOORD1;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct Varyings
            {
                float2 uv : TEXCOORD0;
                float4 color : COLOR;
                float4 positionCS : SV_POSITION;
                // ❌ 不要手动写这一行 ↓
                // uint stereoTarget : SV_RenderTargetArrayIndex;
                // ✅ 只需保留下面这行宏即可自动处理 stereo
                UNITY_VERTEX_OUTPUT_STEREO
            };

            TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
            float4 _MainTex_ST;
            half4 _TintColor;
            half _LowBand, _MidBand, _HighBand;

            Varyings vert(Attributes input)
            {
                Varyings output;
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); // ← 自动设置 stereoTarget

                float sizeBoost = 1.0 + _LowBand * 1.5;
                float3 posWS = TransformObjectToWorld(input.positionOS.xyz * sizeBoost);
                output.positionCS = TransformWorldToHClip(posWS);

                output.uv = TRANSFORM_TEX(input.uv, _MainTex);
                half4 baseColor = input.color * _TintColor;
                baseColor.rgb += _MidBand * 0.6;
                baseColor.a *= (0.4 + _HighBand * 0.8);
                output.color = baseColor;

                return output;
            }

            half4 frag(Varyings input) : SV_Target
            {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
                half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv) * input.color;
                clip(col.a - 0.01);
                return col;
            }
            ENDHLSL
        }
    }
}
最后更新于 2025-10-26