Как я могу конвертировать ультрафиолетовые координаты в мировое пространство?
Я пытаюсь реализовать шейдер. Это будет использовать с Unity LineRenderer. Шейдер будет иметь шум, который сверхурочно прокручивается к координатам текстуры. Например, параллельно оси x ультрафиолетового пространства текстуры. У меня есть реализация, но я не знаю, как получить направление относительно текстуры uv (рассмотрим поворот текстуры) в функции vert. У меня есть только мировая космическая прокрутка.
Основная проблема - как преобразовать ультрафиолетовые координаты (например, (0, 0) или (1, 0)) в мировое пространство?
Вот мой шейдер:
Shader "LineRendering/Test"
{
Properties
{
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
_Freq("Frequency", Float) = 1
_Speed("Speed", Float) = 1
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
LOD 200
Cull Off
Lighting Off
ZWrite Off
Fog { Mode Off }
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#pragma enable_d3d11_debug_symbols
#include "noiseSimplex.cginc"
struct appdata_t
{
fixed4 vertex : POSITION;
fixed2 uv : TEXCOORD0;
};
struct v2f
{
fixed4 vertex : SV_POSITION;
fixed2 texcoord : TEXCOORD0;
fixed2 srcPos : TEXCOORD1;
};
uniform fixed _Freq;
uniform fixed _Speed;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.uv;
OUT.srcPos = mul(unity_ObjectToWorld, IN.vertex).xy;
OUT.srcPos *= _Freq;
//This is my trying to convert uv coordinates to world coodinates, but it is still unsuccessfully.
//fixed2 v0Pos = mul(unity_WorldToObject, fixed3(0, 0, 0)).xy;
//fixed2 v1Pos = mul(unity_WorldToObject, fixed3(1, 0, 0)).xy;
//fixed2 scrollOffset = v1Pos - v0Pos;
fixed2 scrollOffset = fixed2(1, 0);
OUT.srcPos.xy -= fixed2(scrollOffset.x, scrollOffset.y) * _Time.y * _Speed;
return OUT;
}
fixed4 frag(v2f IN) : COLOR
{
fixed4 output;
float ns = snoise(IN.srcPos) / 2 + 0.5f;
output.rgb = fixed3(ns, ns, ns);
output.a = ns;
output.rgb *= output.a;
return output;
}
ENDCG
}
}
}
Библиотеку шума можно получить здесь: https://forum.unity.com/threads/2d-3d-4d-optimised-perlin-noise-cg-hlsl-library-cginc.218372/. Пожалуйста, помогите мне.
2 ответа
Координаты текстуры уже находятся в текстурном пространстве. Если я правильно понимаю, вы должны просто сделать это:
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.uv;
OUT.srcPos = IN.uv;
OUT.srcPos *= _Freq;
fixed2 scrollOffset = fixed2(1, 0);
OUT.srcPos.xy -= fixed2(scrollOffset.x, scrollOffset.y) * _Time.y * _Speed;
return OUT;
}
Опция 1
Каждый из ваших UV связан с определенной вершиной. Как только вы сможете установить, какой UV назначен какой вершине, посмотрите на мировую позицию вершины.
Вариант 2
Хотя другой способ сделать это может быть с текстурой, которая является предварительно запеченным изображением локальных пространственных координат объекта. В текстуре координаты XYZ будут отображаться в RGB. Затем вы выполните поиск текстуры и получите координаты локального объекта. Затем вам нужно будет умножить этот вектор на матрицу проекции мира, чтобы получить реальное значение мирового пространства.
Когда вы создаете текстуру, вы должны учитывать невозможность хранить отрицательные значения. Поэтому сначала вам нужно настроить объект так, чтобы он полностью вписывался в мировые координаты [-1, 1] по всем трем осям. Затем, как часть процедуры выпечки, вам придется разделить все значения на два, а затем добавить.5. Это гарантирует, что все ваши отрицательные значения координатного пространства сохраняются из [0,.5), а все положительные значения сохраняются из [.5,1].
Заметка
Мне было трудно понять ваш точный запрос. Я надеюсь, что мои варианты помогут с вашей программой