unity3d - 如何在表面着色器中获取纹理坐标?
问题描述
我被要求使用表面着色器在两个给定点之间画一条线。该点以纹理坐标(0 到 1 之间)给出,并直接进入 Unity 中的表面着色器。我想通过计算像素位置并查看它是否在那条线上来做到这一点。所以我要么尝试将纹理坐标转换为世界位置,要么我得到像素相对于该纹理坐标的位置。
但我只在统一着色器手册中找到了 worldPos 和 screenPos。有什么方法可以让我获得纹理坐标中的位置(或者至少获得世界 pos 中纹理对象的大小?)
解决方案
这是一个简单的例子:
Shader "Line" {
Properties {
// Easiest way to get access of UVs in surface shaders is to define a texture
_MainTex("Texture", 2D) = "white"{}
// We can pack both points into one vector
_Line("Start Pos (xy), End Pos (zw)", Vector) = (0, 0, 1, 1)
}
SubShader {
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
float4 _Line;
struct Input {
// This UV value will now represent the pixel coordinate in UV space
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
float2 start = _Line.xy;
float2 end = _Line.zw;
float2 pos = IN.uv_MainTex.xy;
// Do some calculations
return fixed4(1, 1, 1, 1);
}
ENDCG
}
}
这是一篇关于如何计算一个点是否在一条线上的好帖子:
假设您使用以下签名定义了一个函数:
inline bool IsPointOnLine(float2 p, float2 l1, float2 l2)
然后对于返回值,你可以这样写:
return IsPointOnLine(pos, start, end) ? _LineColor : _BackgroundColor
如果您想要不使用纹理的 UV 坐标,我建议改为制作顶点片段着色器并float2 uv : TEXCOORD0
在 appdata/VertexInput 结构内定义。然后,您可以将其传递给顶点函数内的片段着色器。
推荐阅读
- accessibility - 单击按钮时出现蓝色阴影
- html - 如何在 wordpress 中自定义侧边栏并在其中添加可折叠菜单?
- java - Knime中多行的正则表达式
- react-native - 为 React Native 和 styled-components 配置 stylelint
- batch-file - cmd新窗口存储输出
- spring-boot - 在 spring boot 2.1.1 自动配置中没有调用 addInterceptors
- broadleaf-commerce - 在“关于我们”的页面上写下 Broadleaf Commerce
- php - 将数组移动 N 并保留原始数组
- python - 将正态分布转换为 softmax
- python - 我如何获得当前 FFT 阵列的频率?