unity3d - How to make Unity glass shader only refract objects behind it? -


i looking glass shader unity refracts objects behind it, or ideas how modify existing glass shader that.

this screenshot shows happens when use fx/glass/stained bumpdistort on curved plane mesh.

enter image description here

as can see, glass shader refracts both sphere in front of mesh , ground behind it. looking shader refract objects behind it.

here code shader, reference:

// per pixel bumped refraction. // uses normal map distort image behind, , // additional texture tint color.  shader "fx/glass/stained bumpdistort" { properties {     _bumpamt  ("distortion", range (0,128)) = 10     _maintex ("tint color (rgb)", 2d) = "white" {}     _bumpmap ("normalmap", 2d) = "bump" {} }  category {      // must transparent, other objects drawn before one.     tags { "queue"="transparent" "rendertype"="opaque" }       subshader {          // pass grabs screen behind object texture.         // can access result in next pass _grabtexture         grabpass {             name "base"             tags { "lightmode" = "always" }         }          // main pass: take texture grabbed above , use bumpmap perturb         // on screen         pass {             name "base"             tags { "lightmode" = "always" }  cgprogram #pragma vertex vert #pragma fragment frag #pragma multi_compile_fog #include "unitycg.cginc"  struct appdata_t {     float4 vertex : position;     float2 texcoord: texcoord0; };  struct v2f {     float4 vertex : sv_position;     float4 uvgrab : texcoord0;     float2 uvbump : texcoord1;     float2 uvmain : texcoord2;     unity_fog_coords(3) };  float _bumpamt; float4 _bumpmap_st; float4 _maintex_st;  v2f vert (appdata_t v) {     v2f o;     o.vertex = mul(unity_matrix_mvp, v.vertex);     #if unity_uv_starts_at_top     float scale = -1.0;     #else     float scale = 1.0;     #endif     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;     o.uvgrab.zw = o.vertex.zw;     o.uvbump = transform_tex( v.texcoord, _bumpmap );     o.uvmain = transform_tex( v.texcoord, _maintex );     unity_transfer_fog(o,o.vertex);     return o; }  sampler2d _grabtexture; float4 _grabtexture_texelsize; sampler2d _bumpmap; sampler2d _maintex;  half4 frag (v2f i) : sv_target {     // calculate perturbed coordinates     half2 bump = unpacknormal(tex2d( _bumpmap, i.uvbump )).rg; // optimize reading x & y without reconstructing z     float2 offset = bump * _bumpamt * _grabtexture_texelsize.xy;     i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;      half4 col = tex2dproj( _grabtexture, unity_proj_coord(i.uvgrab));     half4 tint = tex2d(_maintex, i.uvmain);     col *= tint;     unity_apply_fog(i.fogcoord, col);     return col; } endcg         }     }      // ------------------------------------------------------------------     // fallback older cards , unity non-pro      subshader {         blend dstcolor 0         pass {             name "base"             settexture [_maintex] { combine texture }         }     } }  } 

my intuition has way _grabtexture captured, i'm not entirely sure. i'd appreciate advice. thanks!

no simple answer this. cannot think refraction without thinking context in way, let's see:

basically, it's not easy define when object "behind" one. there different ways meassure point's distance camera, let alone accounting whole geometry. there many strange situations geometry intersects, , centers , bounds anywhere.

refraction easy think in raytracing algorithms (you march ray , calculate how bounces/refracts colors). here in raster graphics (used 99% of real-time graphics), objects rendered whole, , in turns.

what going on image background , ball rendered first, , glass later. glass doesn't "refract" anything, draws distortion of whatever written in render buffer before.

"before" key here. don't "behinds" in raster graphics, done being conscious of rendering order. let's see how refractions created:

  • manually set render queue tags shaders, know @ point in pipeline drawn
  • manually set each material's render queue
  • create script marshals scene , every frame calculates should drawn before or after glass according position or method want, , set render queues in materials
  • create script render scene filtering out (through various methods) objects shouldn't refracted, , use texture refract (depending on complexity of scene, necessary)

these options off top of head, depends on scene

my advice:

  • select ball's material
  • right-click on inspector window --> tick on "debug" mode
  • set custom render queue 2200 (after regular geometry drawn)
  • select glass' material
  • set custom render queue 2100 (after geometry, before ball)

Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -