ugui显示3d模型及可能遇到的问题

不带特效模型

1) 使用一个单独的Camera对准3d模型,Camera的结果输出到RenderTexture上

这边新建了一张512x512的RenderTexture

2) ugui使用RawImage显示该RenderTexture

 

上面存在2个问题:

1) RawImage把相机的白色背景也显示出来了,原因相机使用了半透明背景色来做Clear,解决办法:把相机背景设为透明的(alpha设为0)

2) 整个画面被压扁了,原因RenderTexture大小和RawImage大小不匹配,解决办法:RawImage的大小要和RenderTexture大小一致,或等比放大或缩小

 

带特效模型

1) 我们会看到:场景中的炸弹上的火光是火红的不带任何白色,但是RawImage上的炸弹的火却有白色色块。原因:Shader的中某些计算公式或者混合模式,把相机的白色背景(透明)还原出来了。 

2) 解决办法:这边参考了这边

GitHub - garsonlab/RenderTuxture-AlphaBlend: 解决Unity粒子在使用AlphaBlend模式时,在摄像机拍摄渲染RenderTexture时与相机背景融合问题

原理就是:使用两个相机,一个白色背景,一个黑色背景,用默认混合模式将带特效模型先跟白色背景混合,再跟黑色背景混合,然后我们可以通过一些列的公式,还原出原来正确的SrcColor和SrcAlpha。

 

3a) 创建一个黑色背景的相机,相机参数和RTCamera设置成一样,Camera结果输出到一张新的贴图RT_Camera_Black上

b) 创建一个GRender的材质,赋给RawImage,贴图设置为RT_Camera_Black,然后就可以看到正常的炸弹火光了。

 

其他参考方案

【Unity Shader】半透明特效在RenderTexture上的显示问题_rendertexture 半透明遮挡_coffeecato的博客-CSDN博客

使用RenderTexture实现3D模型与UI的组合显示_coffeecato的博客-CSDN博客

UGUI研究院之在UI上使用RenderTexture显示模型+AlphaBlend特效(二十五) | 雨松MOMO程序研究院 (xuanyusong.com)

 

最后贴上GRenderShader

Shader "UI/GRenderShader"
{
    Properties
    {
        [PerRendererData] _MainTex("White Texture", 2D) = "white" {}
        _BlackTex("Black Texture", 2D) = "black" {}
        _Color("Color", Color) = (1,1,1,1)

        [Toggle]_Grey("Grey", Float) = 0

        _StencilComp("Stencil Comparison", Float) = 8
        _Stencil("Stencil ID", Float) = 0
        _StencilOp("Stencil Operation", Float) = 0
        _StencilWriteMask("Stencil Write Mask", Float) = 255
        _StencilReadMask("Stencil Read Mask", Float) = 255

        _ColorMask("Color Mask", Float) = 15
    }

    SubShader
    {
        Tags
        {
            "Queue" = "Transparent"
            "IgnoreProjector" = "True"
            "RenderType" = "Transparent"
            "PreviewType" = "Plane"
            "CanUseSpriteAtlas" = "True"
        }

        Stencil
        {
            Ref[_Stencil]
            Comp[_StencilComp]
            Pass[_StencilOp]
            ReadMask[_StencilReadMask]
            WriteMask[_StencilWriteMask]
        }

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest[unity_GUIZTestMode]
        Fog { Mode Off }
        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask[_ColorMask]

        Pass
        {
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color : COLOR;
                half2 texcoord  : TEXCOORD0;
            };

            fixed4 _Color;

            v2f vert(appdata_t IN)
            {
                v2f OUT;
                OUT.vertex = UnityObjectToClipPos(IN.vertex);
                OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
                OUT.vertex.xy += (_ScreenParams.zw - 1.0)*float2(-1,1);
#endif
                OUT.color = IN.color*_Color;
                return OUT;
            }

            sampler2D _MainTex;
            sampler2D _BlackTex;
            half _Grey;

            fixed4 frag(v2f IN) : SV_Target
            {
                half4 white = tex2D(_MainTex, IN.texcoord);
                half4 black = tex2D(_BlackTex, IN.texcoord);

                half alpha = white.r - black.r;
                alpha = 1 - alpha;

                fixed4 color;
                if (alpha == 0) {
                    color.rgb = fixed3(0,0,0);
                } else {
                    color.rgb = black.rgb / alpha;
                }

                if (_Grey) {
                    color.rgb = dot(color.rgb, fixed3(0.22, 0.707, 0.071));
                }

                color.a = alpha;
                clip(color.a - 0.01);
                return color;
            }

        ENDCG
        }
    }

}

 

posted @ 2023-03-08 00:18  yanghui01  阅读(536)  评论(0编辑  收藏  举报