c# - 我的着色器在桌面上工作,但屏幕在 Android 上变黑

标签 c# android unity-game-engine mobile shader

您可以在下面找到着色器代码。我在 Unity 中将其作为“图像效果着色器”来完成。然后我将它与 C# 脚本(在着色器下方)一起应用于我的相机。在桌面上看起来不错,但在 Android 上它只会使屏幕变黑。我可能正在使用不适用于 Android 的东西,也许有人可以指出正确的方向来修复它?

    //#<!--
//#    CRT-simple shader
//#
//#    Copyright (C) 2011 DOLLS. Based on cgwg's CRT shader.
//#
//#    Modified by fontmas: 2015-03-06
//#
//#    This program is free software; you can redistribute it and/or modify it
//#    under the terms of the GNU General Public License as published by the Free
//#    Software Foundation; either version 2 of the License, or (at your option)
//#    any later version.
//#    -->
Shader "Custom/CRT"
{
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }

    SubShader
    {
        Pass
        {

        CGPROGRAM
        #pragma vertex vert_img
        #pragma fragment frag
        #include "UnityCG.cginc"
        #define CURVATURE
        #pragma target 3.0
        #define PI 3.141592653589
        uniform sampler2D _MainTex;
        uniform float2 _InputSize;
        uniform float2 _OutputSize;
        uniform float2 _TextureSize;
        uniform float2 _One;
        uniform float2 _Texcoord;
        uniform float _Factor;
        uniform float _Distortion = 0.1f; // 0.1f
        uniform float _Gamma = 1.0f; // 1.0f
        uniform float _curvatureSet1 = 0.5f; // 0.5f
        uniform float _curvatureSet2 = 0.5f; // 0.5f
        uniform float _YExtra = 0.5f; // 0.5f;
        uniform float _rgb1R = 1.0f; // 1.0f
        uniform float _rgb1G = 1.0f; // 1.0f
        uniform float _rgb1B = 1.0f; // 1.0f
        uniform float _rgb2R = 1.0f; // 1.0f
        uniform float _rgb2G = 1.0f; // 1.0f
        uniform float _rgb2B = 1.0f; // 1.0f
        uniform float _dotWeight = 2.0f; // 2.0f
        float2 RadialDistortion(float2 coord)
        {
            coord *= _TextureSize / _InputSize;
            float2 cc = coord - _curvatureSet1;
            float dist = dot(cc, cc) * _Distortion;
            return (coord + cc * (_curvatureSet2 + dist) * dist) * _InputSize / _TextureSize;
        }

        float4 ScanlineWeights(float distance, float4 color)
        {
            float4 width = 2.0f + 2.0f * pow(color, float4(4.0f, 4.0f, 4.0f, 4.0f));
            float4 weights = float4(distance / 0.5f, distance / 0.5f, distance / 0.5f, distance / 0.5f);
            return 1.4f * exp(-pow(weights * rsqrt(0.5f * width), width)) / (0.3f + 0.2f * width);
        }

        float4 frag(v2f_img i) : COLOR
        {
            _Texcoord = i.uv;
            _One = 1.0f / _TextureSize;
            _OutputSize = _TextureSize;
            _InputSize = _TextureSize;
            _Factor = _Texcoord.x * _TextureSize.x * _OutputSize.x / _InputSize.x;

            //float4 ScreenGamma = pow(tex2D(_MainTex, _Texcoord), _Gamma);

            #ifdef CURVATURE
            float2 xy = RadialDistortion(_Texcoord);
            #else
            float2 xy = _Texcoord;
            #endif

            float2 ratio = xy * _TextureSize - float2(0.5f, 0.5f);
            float2 uvratio = frac(ratio);

            xy.y = (floor(ratio.y) + _YExtra) / _TextureSize;
            float4 col = tex2D(_MainTex, xy);
            float4 col2 = tex2D(_MainTex, xy + float2(0.0f, _One.y));

            float4 weights = ScanlineWeights(uvratio.y, col);
            float4 weights2 = ScanlineWeights(1.0f - uvratio.y, col2);
            float3 res = (col * weights + col2 * weights2).rgb;

            float3 rgb1 = float3(_rgb1R, _rgb1G, _rgb1B);
            float3 rgb2 = float3(_rgb2R, _rgb2G, _rgb2B);

            float3 dotMaskWeights = lerp(rgb1, rgb2, floor(fmod(_Factor, _dotWeight)));
            res *= dotMaskWeights;

            return float4(pow(res, float3(1.0f / _Gamma, 1.0f / _Gamma, 1.0f / _Gamma)), 1.0f);
            //return float4(pow(res, float3(1.0f / ScreenGamma.x, 1.0f / ScreenGamma.y, 1.0f / ScreenGamma.z)), 1.0f);


        }
        ENDCG
        }
    }
}



using UnityEngine;
using System.Collections;

public enum CRTScanLinesSizes { S32 = 32, S64 = 64, S128 = 128, S256 = 256, S512 = 512, S1024 = 1024 };

[ExecuteInEditMode]
public class CRT : MonoBehaviour
{

    #region Variables
    public Shader curShader;
    public float Distortion = 0.1f;
    public float Gamma = 1.0f;
    public float YExtra = 0.5f;
    public float CurvatureSet1 = 0.5f;
    public float CurvatureSet2 = 1.0f;
    public float DotWeight = 1.0f;
    public CRTScanLinesSizes scanSize = CRTScanLinesSizes.S512;
    public Color rgb1 = Color.white;
    public Color rgb2 = Color.white;
    private Material curMaterial;

    #endregion

    #region Properties
    Material material
    {
        get
        {
            if (curMaterial == null)
            {
                curMaterial = new Material(curShader);
                curMaterial.hideFlags = HideFlags.HideAndDontSave;
            }
            return curMaterial;
        }
    }
    #endregion
    // Use this for initialization
    void Start()
    {
        if (!SystemInfo.supportsImageEffects)
        {
            enabled = false;
            return;
        }
    }

    void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
    {
        if (curShader != null)
        {
            material.SetFloat("_Distortion", Distortion);
            material.SetFloat("_Gamma", Gamma);
            material.SetFloat("_curvatureSet1", CurvatureSet1);
            material.SetFloat("_curvatureSet2", CurvatureSet2);
            material.SetFloat("_YExtra", YExtra);
            material.SetFloat("_rgb1R", rgb1.r);
            material.SetFloat("_rgb1G", rgb1.g);
            material.SetFloat("_rgb1B", rgb1.b);
            material.SetFloat("_rgb2R", rgb2.r);
            material.SetFloat("_rgb2G", rgb2.g);
            material.SetFloat("_rgb2B", rgb2.b);
            material.SetFloat("_dotWeight", DotWeight);
            material.SetVector("_TextureSize", new Vector2((float)scanSize, (float)scanSize));
            Graphics.Blit(sourceTexture, destTexture, material);
        }
        else
        {
            Graphics.Blit(sourceTexture, destTexture);
        }


    }

    // Update is called once per frame
    void Update()
    {

    }

    void OnDisable()
    {
        if (curMaterial)
        {
            DestroyImmediate(curMaterial);
        }

    }


}

最佳答案

可能是 RenderTexture ,将深度缓冲区更改为 0,如果您在 Unity 中创建 RenderTexture,请这样做:

 rt = new RenderTexture(*width*, *height*, 0, RenderTextureFormat.ARGB32);

如果您在 Unity 中创建 RenderTexture,请将“深度缓冲区”设置为“无深度缓冲区”,

如果改变深度没有任何影响,它也可能是 Graphics.Blit()。

关于c# - 我的着色器在桌面上工作,但屏幕在 Android 上变黑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59231836/

相关文章:

c# - SetFocus 只能在 PreRender 之前和期间调用

c# - 如何将 "123"添加到字符串的开头并将其填充为正好 12 个字符?

c# - 'System.ComponentModel.PropertyChangedEventHandler' 不能派生自特殊类 'System.MulticastDelegate'

android - 为什么注入(inject)后我的字段是 `null`?我如何注入(inject)我的对象?

unity-game-engine - 如何将游戏对象的变换位置传递给我的 CG 着色器?

c# - 如何在 WPF 中使用 MVVM 将 Windows 窗体控件绑定(bind)到 "Grid"面板

android - canvas.toDataURL 不会产生图像/jpeg 数据

android模拟器的wifi说 "connected no internet"

unity-game-engine - Unity可以触发碰撞器激活OnCollisionEnter

ios - 由于链接器错误,Google Analytics 游戏无法构建