UnityShader:选择Pass渲染通道

上一篇博客讲了MRT多重渲染,这篇接着学习通过一个shader输出不同效果的另一种方法——指定不同的渲染通道。

渲染通道在unity Shader中就是SubShader中的Pass。之前的shader中都只有一个Pass,也就是单通道渲染,这样的话如果要对同一个RenderTexture在不同的时刻进行不同的渲染效果输出就需要不停的更换shader。当然,也可以使用多重渲染,但是如果一次只用一个效果,用多重渲染则有些浪费。这个时候就需要多通道渲染。

多通道渲染就是在一个shader中有多个Pass,玩家可以根据需求设定通过哪个Pass来进行渲染,从而实现在不同的时候对使用同一个shader对同一个对象进行不同的效果处理。

1. Shader

先上Shader代码:

Shader "Custom/PassTest" {
    Properties{
        _MainTex("Base (RGB)", 2D) = "white" {}
    }

        CGINCLUDE

        #include "UnityCG.cginc"

        sampler2D _CameraDepthTexture;
        uniform sampler2D _MainTex;

        struct v2f {
            float4 pos : SV_POSITION;
            float4 scrPos:TEXCOORD0;
            float2 uv : TEXCOORD1;
        };
        //Vertex Shader
        v2f vert(appdata_base v) {
            v2f o;
            o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
            o.scrPos = ComputeScreenPos(o.pos);
            o.uv = v.texcoord.xy;
            return o;
        }

        //Reverse frag
        float4 fragReverse(v2f i) :COLOR{
            fixed4 col = tex2D(_MainTex, i.uv);
            // just invert the colors
            col = 1 - col;
            return col;
        }
        //Dept frag
        float4 fragDepth(v2f i) :COLOR{
            float depthValue = 1 - Linear01Depth(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.scrPos)).r);
            return float4(depthValue, depthValue, depthValue, 1.0f);
        }

        ENDCG

    Subshader {
        Tags{ "RenderType" = "Opaque" }
        //Pass 0
        Pass{
            ZTest Always Cull Off ZWrite Off
            Fog{ Mode off }

            CGPROGRAM
            #pragma glsl
            #pragma fragmentoption ARB_precision_hint_fastest
            #pragma vertex vert
            #pragma fragment fragReverse
            #pragma target 3.0
            ENDCG
        }
        //Pass 1
        Pass{
            ZTest Always Cull Off ZWrite Off
            Fog{ Mode off }

            CGPROGRAM
            #pragma glsl
            #pragma fragmentoption ARB_precision_hint_fastest
            #pragma vertex vert
            #pragma fragment fragDepth
            #pragma target 3.0
            ENDCG
        }
    }

    Fallback "Diffuse"
}

shader并不难,所有的方法和变量都放在了SubShader外面,其中,vert是顶点方法,fragReverse是颜色反向的片段方法,fragDepth是深度图的片段方法。

在SubShader中有两个Pass,从上到下分别对应0,1,2……。Shader的主体,包括顶点和片段方法的指定都在这些对应的Pass中。这里由于两个Pass共用同一个顶点方法,所以vertex都是vert,第一个Pass调用fragReverse来实现颜色反向效果,二第二个Pass调用fragDepth来输出深度图。

现在shader有了,再来看看如何在脚本中修改渲染通道。

2. 修改渲染通道

先上代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum PassType
{
    Reverse,
    Depth
}
public class CameraRanderPass : MonoBehaviour {

    public PassType showType = PassType.Reverse;
    public Material Mat;

    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        Graphics.Blit(src, dest, Mat, (int)showType);
    }
}

C#脚本也很简单,和之前差不多,关键的不同是Graphics.Blit(src, dest, Mat, (int)showType);的最后多了个参数。Graphics.Blit的第四个参数是通道指定参数,可省略,默认为0,也就是第一个Pass。

通常写shader都只有一个Pass,省略这个参数将会默认调用这个Pass,现在有了两个Pass,我们就可以通过传入不同的值(int)来指定通过不同的通道进行渲染。在这里,为了方便调用,我定义了一个PassType枚举,Reverse表示颜色反向,Depth表示深度,和Shader中对应。

转载请注明出处:http://blog.csdn.net/ylbs110/article/details/53560444

下面来看看选择这两个Pass后的不同输出效果:
Reverse:
这里写图片描述
Depth:
这里写图片描述

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Projective texture mapping in Unity Shader is a technique used to project a texture onto an object in a way that simulates the effect of a slide projector. It can be used to create various effects like projecting a spotlight texture onto a surface, projecting a decal onto a curved surface, or creating a shadow map for an object. To implement projective texture mapping in Unity Shader, you need to use a combination of vertex and fragment shaders. The vertex shader calculates the projective transformation matrix, which is used to transform the texture coordinates in the fragment shader. The fragment shader samples the texture and applies it to the object's surface. Here's a simple example of a vertex shader that calculates the projective transformation matrix: ``` Shader "Custom/ProjectiveTextureMapping" { Properties { _MainTex ("Texture", 2D) = "white" {} _Projector ("Projector", 3D) = "" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag uniform sampler2D _MainTex; uniform float4x4 unity_Projector; float4x4 unity_ObjectToWorld; struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = mul(unity_Projector, v.vertex).xy; return o; } fixed4 frag (v2f i) : SV_Target { return tex2D(_MainTex, i.uv); } ENDCG } } } ``` In this example, the `_MainTex` property is the texture to be projected, and the `_Projector` property is the object that will project the texture. The `unity_Projector` variable is a matrix that transforms the texture coordinates from object space to clip space. The `vert` function calculates the transformed texture coordinates and passes them to the fragment shader in the `v2f` struct. The fragment shader simply samples the texture using the transformed texture coordinates and returns the color. You can use this shader by assigning it to a material and setting the `_MainTex` and `_Projector` properties to appropriate textures and objects, respectively.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值