我想做一个简单的单通道光线投射着色器。也就是说,我在vertexshader中传递顶点的世界位置,并在片段着色器中开始光线行进到Z轴(我使用正交投影)以获得世界坐标中的样本位置,然后我需要计算世界坐标到模型坐标以获得样本(纹理)在 3d 纹理中的位置,我现在被困在那里。我用opengl在cpp中做了同样的事情,我想在unity3d中尝试它并使用gui的好处。代码在这里,但它不能正常工作。感谢任何人的帮助,并为我糟糕的英语感到抱歉。
Shader "Customer/RayCast"
{
Properties
{
_Volume ("Volume (Scalar)", 3D) = "white"{}
//_VolumeGradient ("VolumeGradient (Scalar)", 3D) = "white"{}
//_TransferMap_Red ("TransferMap_Red", 2D) = "white"{}
//_TransferMap_Green ("TransferMap_Green", 2D) = "white"{}
//_TransferMap_Blue ("TransferMap_Blue", 2D) = "white"{}
//_TransferMap_Alpha ("TransferMap_Alpha", 2D) = "white"{}
_Slider("slider", Float) = 0.2
}
SubShader
{
Tags { "Queue" = "Transparent" }
Pass
{
Cull Back
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
// Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members eye_pos)
#pragma exclude_renderers d3d11 xbox360
#pragma target 3.0
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : POSITION;
float3 world_pos;
};
v2f vert(appdata_base v)
{
v2f output;
output.pos = mul (UNITY_MATRIX_MVP, v.vertex);
output.world_pos = mul(_Object2World, v.vertex);
return output;
}
sampler3D _Volume;
float _Slider;
float4 frag( v2f input ) : COLOR
{
float3 start = input.world_pos;
float4 dst = float4(0.0, 0.0, 0.0, 0.0);//final color.
float3 ray_step = 0.01 * float3(0.0f, 0.0f, 1.0f);//camera look at positive z- axis with ortho projection.
float4 value;
float3 sample_pos = start;
float3 offset = float3(0.5f, 0.5f, 0.5f);//model vertex is -0.5 to 0.5, make it 0 to 1.0.
for(int i = 0; i < 100; ++i)
{
sample_pos += (i * ray_step);
value = tex3D(_Volume, mul(_World2Object, sample_pos).xyz + offset);
value.a = 0.1f;
value.xyz *= value.a;
dst += (1.0 - dst.a) * value;
}
dst += float4(0.5f, 0.0f, 0.0f, 0.0f);
return dst;
}
ENDCG
}
}
}
psone 更多的问题是#program target 3.0 似乎不允许 for 循环超过 300 次,而在 opengl 中我使用 500 没有问题与同一个视频卡。并且不支持#program target 4.0,unity3d有什么办法改进吗?