首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >HLSL在搅拌器中与“纹理坐标”节点中的“对象”数据相等

HLSL在搅拌器中与“纹理坐标”节点中的“对象”数据相等
EN

Game Development用户
提问于 2019-02-13 05:53:11
回答 1查看 514关注 0票数 1

我用Blender中的节点编辑器模拟了一个着色器。现在我试着用HLSL编写它。在Blender中有一个名为“纹理坐标”的节点组。如果我使用组中的" uv“节点,它的行为就像一个普通的未光照的框架着色器,但是如果我使用" object”节点给出纹理的坐标,它就会忽略uv数据,而只是像一幅叠加在物体上的图像一样映射纹理。

这就是我想要的效果。但是,我无法找到在HLSL中复制这一功能的方法。据我所见,我可以使用TEXCOORD0POSITION作为纹理坐标,分别为对象上的纹理生成uv映射和世界映射。也许我想要的是对象映射?

如果有关系的话,我用的是生成的纹理

EN

回答 1

Game Development用户

回答已采纳

发布于 2019-02-13 10:25:47

纹理坐标节点通常用于纹理的坐标,通常用作纹理节点的矢量输入的输入。

对象节点

代码语言:javascript
运行
复制
Shader "Blender/ObjectNode"
{
    SubShader
    {

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

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 worldPos : TEXCOORD2;
            };

            float4 _Pos;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                o.uv = v.uv;
                return o;
            }
            
            sampler2D _MainTex;

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

生成节点

您可以通过从-1,1到1,0的世界位置来实现生成节点。

代码语言:javascript
运行
复制
 Shader "Blender/GeneratedNode"
{
    SubShader
    {

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

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 worldPos : TEXCOORD2;
            };

            float4 _Pos;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                o.uv = v.uv;
                return o;
            }
            
            sampler2D _MainTex;

            fixed4 frag (v2f i) : SV_Target
            {
                return i.worldPos*0.5+0.5;
            }
            ENDCG
        }
    }
}

重新映射是扩展坐标的一种方法:

重置位置

现在,当我们在搅拌器中移动对象时,我们得到了这样的结果:

但是,在团结中,我们没有相同的结果:

我们应该重新定位来解决这个问题:

代码语言:javascript
运行
复制
Shader "Blender/ObjectNode"
{
    Properties
    {
        _Pos("Pos",Vector) = (0,0,0,0)
    }
    SubShader
    {

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

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 worldPos : TEXCOORD2;
            };

            float4 _Pos;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex-_Pos);
                o.uv = v.uv;
                return o;
            }
            
            sampler2D _MainTex;

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

然后将此脚本附加到对象以更新位置:

代码语言:javascript
运行
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class ResetPos : MonoBehaviour {
    void Update () {
        GetComponent<MeshRenderer>().material.SetVector("_Pos",transform.position);     
    }
}

更新

ObjectNode

代码语言:javascript
运行
复制
Shader "ObjectNode" {
    Properties {
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
 
        CGPROGRAM
        #pragma surface surf Lambert vertex:vert
 
        struct Input {
            float3 objPos;
        };
 
        void vert (inout appdata_full v, out Input o) {
            UNITY_INITIALIZE_OUTPUT(Input,o);
            o.objPos = v.vertex;
        }
 
        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = IN.objPos;
            o.Alpha = 1;
        }
        ENDCG
    }
}

GeneratedNode

代码语言:javascript
运行
复制
Shader "GeneratedNode" {
    Properties {
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
 
        CGPROGRAM
        #pragma surface surf Lambert vertex:vert
 
        struct Input {
            float3 objPos;
        };
 
        void vert (inout appdata_full v, out Input o) {
            UNITY_INITIALIZE_OUTPUT(Input,o);
            o.objPos = v.vertex;
        }
 
        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = IN.objPos*0.5+0.5;
            o.Alpha = 1;
        }
        ENDCG
    }
}
票数 0
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/168018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档