unity3d - 着色器在 Unity 编辑器中工作正常,但在 WebGL 构建中变黑
问题描述
我正在开展一个项目,该项目将不同位置的传感器值编码为建筑物的 3d 热图。我为此使用了顶点着色器,这在 Editor: example中工作得很好,但是在我在 WebGL 中构建场景之后,结果是黑色的。
我尝试过使用常量循环索引或始终在项目设置等中包含此着色器,但这些都不起作用。以下是一些代码:
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.screenPos = ComputeScreenPos(o.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
//...
float2 boxIntersection(in float3 ro, in float3 rd, in float3 rad)
{
float3 m = 1.0 / rd;
float3 n = m * ro;
float3 k = abs(m) * rad;
float3 t1 = -n - k;
float3 t2 = -n + k;
float tN = max(max(t1.x, t1.y), t1.z);
float tF = min(min(t2.x, t2.y), t2.z);
if (tN > tF || tF < 0.0) return float2(-1.0, -1.0); // no intersection
return float2(tN, tF);
}
//p in object space
float SampleValue(float3 p) {
float totalValue = 0.0;
float denom = 0.0;
for (int i = 0; i < 34; ++i) { // _DataSize
float4 sd = _SensorData[i];
float dist = length(p - sd.xyz);
totalValue += sd.w / (dist * dist);
denom += 1.0 / (dist * dist);
}
if (denom == 0.0) {
return 0.0;
}
return totalValue / denom;
}
float4 transferFunction(float value) {
float tv = (value - _DataScale.x) / (_DataScale.y - _DataScale.x); // _DataScale.x, _DataScale.y
float4 col = tex2D(_TransferTexture, float2(0.5, tv));
col.w *= _Strength; // _Strength
return float4(col.xyz * col.w, col.w);
}
float4 rayMarch(float3 ro, float3 rd, float dp) {
float3 ro1 = mul(unity_WorldToObject, float4(ro, 1.0));
float3 rd1 = mul(unity_WorldToObject, rd);
float2 t = boxIntersection(ro1, rd1, float3(1, 1, 1) * 0.5);
t.x = length(mul(unity_ObjectToWorld, float4(ro1 + rd1 * max(t.x, 0.0), 1.0)) - ro);
t.y = length(mul(unity_ObjectToWorld, float4(ro1 + rd1 * t.y, 1.0)) - ro);
t.y = min(t.y, dp);
float4 acc = float4(0.0, 0.0, 0.0, 1.0);
float totalDelta = (t.y - t.x);
float delta = totalDelta / float(_RM_Samples - 1.0);
float3 p = ro + t.x * rd;
for (int i = 0; i < 34; ++i) { // _RM_Samples
float v = SampleValue(p);
float4 tf = transferFunction(v);
float tr = exp(-tf.w * delta);
acc.xyz += tf.xyz * acc.w * delta;
acc.w *= tr;
p += delta * rd;
}
return float4(acc.xyz, (1.0 - acc.w) * step(t.x, t.y));
}
fixed4 frag(v2f i) : SV_Target
{
float2 tc = i.screenPos.xy / i.screenPos.w;
float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, tc));
float eD = LinearEyeDepth(depth);
float3 ro = _WorldSpaceCameraPos;
float3 rd = normalize(i.worldPos - ro);
float4 col = rayMarch(ro, rd, eD);
//if (col.w < 1) col = float4(1, 0, 0, 1);
//else col = float4(0, 1, 0, 1);
if (wingCullPlaneValue(i.worldPos.xyz) == 0 || cullPlaneValue(i.worldPos.xyz) == 0) {
discard;
}
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
由于这在编辑器中运行良好,我认为没有任何错误boxIntersection
或rayMarching
功能。我想知道 WebGl 中是否有什么特别之处,它以不同的方式处理像素,我必须相应地调整一些代码。我是 WebGL 和 Shader 的新手,如果有任何帮助或建议,我将不胜感激,在此先感谢。
解决方案
那是因为阶跃函数。用你自己的 sigmoid 函数来近似它(可能很昂贵)
float emulated_step(float a, float x){
return 1.0/(1+pow(1000, -(x-a)*8192));
}
推荐阅读
- php - 在现有目录 PHP 中创建目录
- azure-devops - 如何自动创建 Azure DevOps Boards 备份以进行时间点还原?
- python-3.x - 使用 python 和 selenium 为每个选择选项标签获取控制台日志响应
- python - 如何使用 for 循环将整个 csv 文件写入字典
- typescript - 根据 TypeScript 中区分联合的参数自动推断返回类型
- c - 是什么导致我的 C 程序中出现此错误(分段错误(核心转储))?
- javascript - 由于活动课程,我如何更改图像?
- javascript - 有没有办法通过对象的键从对象中获取值?
- sql - 从 Snowflake 表中查询 60 列会比查询 20 列花费更多吗?
- gradle - 是否可以在 Gradle 中压缩和替换?