【Unity Shader】设置uniform

介绍

unity shader里会内置一些用于矩阵计算的变量和函数
在这里插入图片描述
在这里插入图片描述
但是有时候我们需要传入一些自定义计算的的矩阵用于shader中计算,但是发现Properties中没有矩阵类型的数据传入,因此引出本文。
在这里插入图片描述

两种方式引入uniform

1.单独的material引入uniform
2.全局material都引入uniform

1.单独方式引入

Shader "Unlit/shader01"
{
    Properties
    {
		_MyColor("color", Color) = (1,1,1,1)

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

			fixed4 _MyColor;
			// 注意这里的pvmMat会从外面传入
			float4x4 pvmMat;
			// 传入物体的模型矩阵
			float4x4 modelMatrix;

            v2f vert (appdata v)
            {
                v2f o;
                //o.vertex = UnityObjectToClipPos(v.vertex);
                // 下面的代码使用了自己构建的pvm矩阵,就是将对象顶点从本地坐标系转到裁剪坐标系,等同与UnityObjectToClipPos函数的作用,或者等于UNITY_MATRIX_MVP
                // 使用完全自己传入的pvm矩阵的话会导致scene窗口和game窗口不统一,而且渲染有问题,原因未知,比如下面这种
				// o.vertex = mul(pvmMat, v.vertex);
				// 建议使用下面这种
				o.vertex = mul(UNITY_MATRIX_VP, mul(modelMatrix, v.vertex));
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return _MyColor;
            }
            ENDCG
        }
    }
}

脚本 例子中是挂载到相机上的

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

public class test01 : MonoBehaviour
{
    void Update()
    {
        Matrix4x4 projectionMatrix = Camera.main.projectionMatrix;
        Matrix4x4 worldToCameraMatrix = Camera.main.worldToCameraMatrix;
        GameObject box = GameObject.Find("Cube");
        Matrix4x4 modelMatrix = box.transform.localToWorldMatrix;
        Matrix4x4 MVPMat = projectionMatrix * worldToCameraMatrix * modelMatrix;
        // 直接传方式不推荐
        box.GetComponent<Renderer>().material.SetMatrix("pvmMat", MVPMat);
        box.GetComponent<Renderer>().material.SetMatrix("modelMatrix", modelMatrix);
    }
}

2.全局方式引入

shader

Shader "Unlit/shader01"
{
    Properties
    {
		_MyColor("color", Color) = (1,1,1,1)

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

			fixed4 _MyColor;
			// 注意这里的pvmMat会从外面全局传入
			float4x4 pvmMat;

            v2f vert (appdata v)
            {
                v2f o;
				o.vertex = mul(UNITY_MATRIX_VP, mul(modelMatrix, v.vertex));
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return _MyColor;
            }
            ENDCG
        }
    }
}

脚本

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

public class test01 : MonoBehaviour
{
    void Update()
    {
        Matrix4x4 projectionMatrix = Camera.main.projectionMatrix;
        Matrix4x4 worldToCameraMatrix = Camera.main.worldToCameraMatrix;

        Matrix4x4 pvMat = projectionMatrix * worldToCameraMatrix;
        Matrix4x4 modelMatrix = Matrix4x4.identity ;
        modelMatrix[0] = 3;
        Shader.SetGlobalMatrix("pvmMat", pvMat* modelMatrix);
        box.GetComponent<Renderer>().material.SetMatrix("modelMatrix", modelMatrix);
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!要创建一个在Unity中实现月亮效果的Shader,您可以遵循以下步骤: 1. 创建一个新的着色器材质并将其分配给需要应用月亮效果的对象。 2. 在着色器中定义一个用于表示月亮位置的属性。例如,您可以使用一个名为"moonPosition"的属性来表示月亮的世界空间坐标。 3. 在顶点着色器中将该属性传递给片段着色器。 4. 在片段着色器中,计算从顶点到月亮位置的向量,并将其标准化。 5. 使用该向量和其他光照计算(例如漫反射和镜面反射)来模拟月亮照射场景的效果。您可以使用光照方程或其他技术来实现合适的着色效果。 6. 调整光照和材质属性以达到所需的效果。您可以尝试调整月亮的亮度、颜色和反射等因素来达到更逼真的效果。 这是一个简单的示例,用于将月亮的光照效果应用于场景中的对象。请注意,这只是一个基本的示例,并且您可以根据需要进行自定义和改进。 ```csharp Shader "Custom/MoonShader" { Properties { _MoonPosition ("Moon Position", Vector) = (0, 0, 0, 0) } SubShader { Tags { "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // 月亮位置属性 uniform float4 _MoonPosition; // 顶点着色器 struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float3 worldPos : TEXCOORD0; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; return o; } // 片段着色器 fixed4 frag (v2f i) : SV_Target { // 计算从顶点到月亮位置的向量 float3 moonVector = normalize(_MoonPosition.xyz - i.worldPos); // 在这里进行光照计算和其他着色操作 // 返回最终的颜色值 return fixed4(1, 1, 1, 1); } ENDCG } } } ``` 请确保将_MoonPosition属性设置为适当的月亮位置,以便正确计算月亮照射效果。此示例只提供了一个基本的框架,您可以根据自己的需求进行更多的定制和改进。希望这对您有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值