Shader在Unity Editor中工作正常,但在WebGL构建中变成黑色

时间:2019-10-22 16:32:30

标签: unity3d shader unity-webgl

我正在一个项目中,该项目将不同位置的传感器值编码到建筑物的3d热图中。我为此使用了一个顶点着色器,并且在Editor:example中可以正常工作,但是在WebGL中构建场景后,结果就是black

我尝试使用常量循环索引,或者始终在项目设置等中包含此着色器,但是这些都不起作用。以下是一些代码:

gbm.evals_result()

由于这在Editor中工作正常,所以我认为 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函数中没有任何错误。我想知道WebGl中是否有任何特殊之处可以不同地处理像素,我必须相应地调整一些代码。我是WebGL和Shader的新手,非常感谢您的帮助或建议。

1 个答案:

答案 0 :(得分:0)

那是因为阶跃函数。 用你自己的 sigmoid 函数近似它(可能很贵)

// get the uptime checks for past X hours
$uptimeData = UptimeChecks::where('user_id', 1)
                        ->where('monitor_id', 1)
                        ->where('checked_at', '>=', '2021-05-02 13:00:00')
                        ->where('checked_at', '<=', '2021-05-03 13:00:00')
                        ->orderBy('checked_at', 'asc')
                        ->select('event', 'checked_at')
                        ->get();

$uptimeDataTimeline = $uptimeData->groupBy(function ($item, $key) {
  $date = Carbon::parse($item->checked_at);

  // group by hour, how can I get say every 3 hours worth of data?
  return $date->format('Y-m-d H:00:00');
});

$uptimeDataTimeline = $uptimeDataTimeline->map(function ($checksInPeriod, $key) {
  $down = 0;
  $up = 0;
  $total = 0;
  $uptime = 0;
  $fill = '#1fc777'; // green

  // $checksInPeriod is all of the data for a given hour at the moment
  // I need to group by a bigger period, say, every 3 hours

  // add our events
  foreach ($checksInPeriod as $key => $value) {
    $total++;
    if (strtolower($value['event']) == 'down') $down++;
    if (strtolower($value['event']) == 'up') $up++;
  }

  // calculate uptime
  $uptime = floatval(number_format(round($up / $total, 5) * 100, 2, '.', ','));

  // fill colours
  if ($uptime < 100) $fill = '#9deab8'; // lighter green
  if ($uptime < 99) $fill = '#fbaa49'; // amber
  if ($uptime < 98) $fill = '#e0465e'; // red

  return [
    'total_events' => $total,
    'down_events' => $down,
    'up_events' => $up,
    'uptime' => $uptime,
    'fill' => $fill
  ];
});