【问题标题】:custom clipping shader on top of standard shader? (unity)标准着色器之上的自定义剪切着色器? (统一)
【发布时间】:2018-02-11 15:22:01
【问题描述】:

我想用着色器代码 (hlsl) 在对象上画一条水平线。

裁剪着色器只是简单地获取到表面着色器中给定 Y 坐标的距离,并检查它是否高于给定值。

如果是这样,它将丢弃。结果是一个着色器,它简单地剪掉所有不在一条线上的像素。

void surf (Input IN, inout SurfaceOutputStandard o) {
    // Albedo comes from a texture tinted by color
    fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    float d = abs(_YClip - IN.worldPos.y); // _YClip is is the properties and can be changed

    if (d > _LineThickness) {
        discard;
    }
}

我能否在不更改代码的情况下将此着色器与标准统一着色器结合使用?

我计划有一个小工具着色器来渲染线条和各种东西。如果我可以告诉 unity 将这个 Gizmo 着色器渲染在顶部,那将非常实用。

【问题讨论】:

  • 我相信我已经做出了像你描述的那样的东西。这是一个男人在经过 Y 轴或 X 轴的某个点时换衣服的地方。我在这台计算机上没有脚本,但如果我正确理解您的需求,请回复,我会在明天或后天用我另一台计算机上的代码回复您。
  • 这听起来像一个类似的问题。所以你实际上为此使用了两个单独的着色器?如果我结合两个着色器,我只会得到结果。不过这有点不舒服。

标签: unity3d opengl shader


【解决方案1】:

我相信您可以根据您的目的使用或调整此着色器。

在到达 y 轴之前显示的图像。

显示期间的图像,其中一半高于截止 y 值,另一半低于截止值。请注意,它溶解的图案取决于您自己提供的纹理图案。所以应该有可能有一个严格的截止而不是一个更奇怪和不均匀的模式。

在对象完全通过截止 y 值之后。在这种情况下,我所做的是将一个对象隐藏在开始对象内,该对象比您看到的第一个对象略小。但如果你没有任何东西在里面,这个对象就会是不可见的,或者被剪掉了。

Shader "Dissolve/Dissolve"
{
Properties
{
    _MainTex ("Texture", 2D) = "white" {}
    _DissolveTexture("Dissolve Texture", 2D) = "white" {}
    _DissolveY("Current Y of the dissolve effect", Float) = 0
    _DissolveSize("Size of the effect", Float) = 2
    _StartingY("Starting point of the effect", Float) = -1 //the number is supposedly in meters. Is compared to the Y coordinate in world space I believe.
}
SubShader
{
    Tags { "RenderType"="Opaque" }
    LOD 100

    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        // make fog work
        //#pragma multi_compile_fog

        #include "UnityCG.cginc"

        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
            //UNITY_FOG_COORDS(1)
            float4 vertex : SV_POSITION;
            float3 worldPos : TEXCOORD1;
        };

        sampler2D _MainTex;
        float4 _MainTex_ST;
        sampler2D _DissolveTexture;
        float _DissolveY;
        float _DissolveSize;
        float _StartingY;

        v2f vert (appdata v) //"The vertex shader"
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.uv = TRANSFORM_TEX(v.uv, _MainTex);
            o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
            //UNITY_TRANSFER_FOG(o,o.vertex);
            return o;
        }

        fixed4 frag (v2f i) : SV_Target //"For drawing the pixel on top"
        {
        float transition = _DissolveY - i.worldPos.y; //Cutoff value where world position is taken into account.
        clip(_StartingY + (transition + (tex2D(_DissolveTexture, i.uv)) * _DissolveSize)); //Clip = cutoff if above 0.
        //My understanding: If StartingY for dissolve effect + transition value and uv mapping of the texture is taken into account, clip off using the _DissolveSize.
        //This happens to each individual pixel.

            // sample the texture
            fixed4 col = tex2D(_MainTex, i.uv);
            // apply fog
            //UNITY_APPLY_FOG(i.fogCoord, col);
            //clip(1 - i.vertex.x % 10); //"A pixel is NOT rendered if clip is below 0."
            return col;
        }
        ENDCG
    }
}
}

在这里您可以看到可用的检查器字段。

我有一个类似 x 轴的脚本。

【讨论】:

  • 谢谢!这正是我一直在寻找的
  • 太棒了。作为一个额外的说明,如果发现如果你向同一个对象添加额外的材质,你不需要下面的对象,那么它会将溶解材质放在顶部,而另一个会逐渐显示在下面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 2012-10-12
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
相关资源
最近更新 更多