问题
I am trying to implement a shader. It will use with Unity LineRenderer. Shader will have noise that scrolling overtime raltive to texture coordinates. For example in parallel to x axis of uv space of texture. I have an implementation, but i dont'know how to get direction relative to texture uv (consider the texture rotation) in a vert function. I am only have a world space-relativew scrolling.
Main problem - how to convert uv coordinates (for example (0, 0) or (1, 0)) to world space?
Here is a my shader:
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
}
}
}
Noise library getted form here: https://forum.unity.com/threads/2d-3d-4d-optimised-perlin-noise-cg-hlsl-library-cginc.218372/#post-2445598. Please help me.
回答1:
Texture coordinates are already in texture space. If I understand correctly, you should be able to just do this:
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;
}
回答2:
Option 1
Each of your UVs is associated with a specific vertex. Once you can establish which UV is assigned to which vertex, then look up the world position of the vertex.
Option 2
Another way to do this though may be with a texture that is a pre-baked image of the local space coordinates of the object. In the texture, the XYZ coords would map to RGB. Then you'll do a texture lookup and get to local object coordinates. You'll then have to multiply that vector by the world projection matrix in order to get the actual world space value.
When you create the texture, you'll have to account for the inability to store negative values. So first you'll have to set up the object so that it fits entirely inside the world coordinates of [-1, 1], in all three axes. Then, as part of the baking procedure, you'll have to divide all values by two, and then add .5. This will ensure that all your negative coordinate space values are stored from [0,.5) and all positive values are stored from [.5,1].
Note
I had a hard time understanding your exact request. I hope my options help with your program
来源:https://stackoverflow.com/questions/52852185/how-can-i-convert-uv-coordinates-to-world-space