def make_finalize(con_mesh): vert = con_mesh.vert frag = con_mesh.frag geom = con_mesh.geom tesc = con_mesh.tesc tese = con_mesh.tese # Additional values referenced in cycles # TODO: enable from cycles.py if frag.contains('dotNV') and not frag.contains('float dotNV'): frag.write_init('float dotNV = max(dot(n, vVec), 0.0);') write_wpos = False if frag.contains('vVec') and not frag.contains('vec3 vVec'): if is_displacement: tese.add_out('vec3 eyeDir') tese.add_uniform('vec3 eye', '_cameraPosition') tese.write('eyeDir = eye - wposition;') else: if not vert.contains('wposition'): write_wpos = True vert.add_out('vec3 eyeDir') vert.add_uniform('vec3 eye', '_cameraPosition') vert.write('eyeDir = eye - wposition;') frag.write_attrib('vec3 vVec = normalize(eyeDir);') export_wpos = False if frag.contains('wposition') and not frag.contains('vec3 wposition'): if not is_displacement: # Displacement always outputs wposition export_wpos = True if export_wpos: vert.add_uniform('mat4 W', '_worldMatrix') vert.add_out('vec3 wposition') vert.write_pre = True vert.write('wposition = vec4(W * spos).xyz;') vert.write_pre = False elif write_wpos: vert.add_uniform('mat4 W', '_worldMatrix') vert.write_pre = True vert.write('vec3 wposition = vec4(W * spos).xyz;') vert.write_pre = False frag_mpos = frag.contains('mposition') and not frag.contains('vec3 mposition') if frag_mpos: vert.add_out('vec3 mposition') vert.write_pre = True vert.write('mposition = spos.xyz;') vert.write_pre = False if tese != None: if frag_mpos: make_tess.interpolate(tese, 'mposition', 3, declare_out=True) elif tese.contains('mposition') and not tese.contains('vec3 mposition'): vert.add_out('vec3 mposition') vert.write_pre = True vert.write('mposition = spos.xyz;') vert.write_pre = False make_tess.interpolate(tese, 'mposition', 3, declare_out=False)
def make_deferred(con_mesh): wrd = bpy.data.worlds['Arm'] make_base(con_mesh, parse_opacity=False) frag = con_mesh.frag vert = con_mesh.vert tese = con_mesh.tese if '_Veloc' in wrd.rp_defs: frag.add_out('vec4[3] fragColor') if tese == None: vert.add_uniform('mat4 prevWVP', link='_prevWorldViewProjectionMatrix') vert.add_out('vec4 wvpposition') vert.add_out('vec4 prevwvpposition') vert.write('wvpposition = gl_Position;') vert.write('prevwvpposition = prevWVP * spos;') else: vert.add_uniform('mat4 prevW', link='_prevWorldMatrix') vert.add_out('vec3 prevwposition') vert.write('prevwposition = vec4(prevW * spos).xyz;') tese.add_out('vec4 wvpposition') tese.add_out('vec4 prevwvpposition') tese.add_uniform('mat4 prevVP', '_prevViewProjectionMatrix') tese.write('wvpposition = gl_Position;') make_tess.interpolate(tese, 'prevwposition', 3) tese.write('prevwvpposition = prevVP * vec4(prevwposition, 1.0);') else: frag.add_out('vec4[2] fragColor') # Pack gbuffer frag.add_include('../../Shaders/std/gbuffer.glsl') frag.write('n /= (abs(n.x) + abs(n.y) + abs(n.z));') frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);') # TODO: store_depth frag.write( 'fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), 1.0 - gl_FragCoord.z);' ) if '_SSS' in wrd.rp_defs: frag.add_uniform('int materialID') frag.write( 'fragColor[1] = vec4(basecol.rgb, materialID + clamp(occlusion, 0.0, 1.0 - 0.001));' ) else: frag.write('fragColor[1] = vec4(basecol.rgb, occlusion);') if '_Veloc' in wrd.rp_defs: frag.write('vec2 posa = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;') frag.write( 'vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;' ) frag.write('fragColor[2].rg = vec2(posa - posb);') return con_mesh
def write_tex_coords(con_mesh: ShaderContext, vert: Shader, frag: Shader, tese: Optional[Shader]): rpdat = arm.utils.get_rp() if con_mesh.is_elem('tex'): vert.add_out('vec2 texCoord') vert.add_uniform('float texUnpack', link='_texUnpack') if mat_state.material.arm_tilesheet_flag: if mat_state.material.arm_particle_flag and rpdat.arm_particles == 'On': make_particle.write_tilesheet(vert) else: vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset') vert.write_attrib( 'texCoord = tex * texUnpack + tilesheetOffset;') else: vert.write_attrib('texCoord = tex * texUnpack;') if tese is not None: tese.write_pre = True make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord')) tese.write_pre = False if con_mesh.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.add_uniform('float texUnpack', link='_texUnpack') vert.write_attrib('texCoord1 = tex1 * texUnpack;') if tese is not None: tese.write_pre = True make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1')) tese.write_pre = False
def make_base(con_mesh, parse_opacity): global is_displacement global write_material_attribs global write_material_attribs_post global write_vertex_attribs wrd = bpy.data.worlds['Arm'] vert = con_mesh.make_vert() frag = con_mesh.make_frag() geom = None tesc = None tese = None vert.add_uniform('mat3 N', '_normalMatrix') vert.write_attrib('vec4 spos = vec4(pos.xyz, 1.0);') vattr_written = False rpdat = arm.utils.get_rp() is_displacement = mat_utils.disp_linked(mat_state.output_node) if is_displacement: if rpdat.arm_rp_displacement == 'Vertex': frag.ins = vert.outs else: # Tessellation tesc = con_mesh.make_tesc() tese = con_mesh.make_tese() tesc.ins = vert.outs tese.ins = tesc.outs frag.ins = tese.outs make_tess.tesc_levels(tesc, rpdat.arm_tess_mesh_inner, rpdat.arm_tess_mesh_outer) make_tess.interpolate(tese, 'wposition', 3, declare_out=True) make_tess.interpolate(tese, 'wnormal', 3, declare_out=True, normalize=True) # No displacement else: frag.ins = vert.outs if write_vertex_attribs != None: vattr_written = write_vertex_attribs(vert) frag.add_include('compiled.inc') written = False if write_material_attribs != None: written = write_material_attribs(con_mesh, frag) if written == False: frag.write('vec3 basecol;') frag.write('float roughness;') frag.write('float metallic;') frag.write('float occlusion;') frag.write('float specular;') if '_Emission' in wrd.world_defs: frag.write('float emission;') if parse_opacity: frag.write('float opacity;') cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity) if write_material_attribs_post != None: write_material_attribs_post(con_mesh, frag) vert.add_out('vec3 wnormal') make_attrib.write_norpos(con_mesh, vert) frag.write_attrib('vec3 n = normalize(wnormal);') if not is_displacement and not vattr_written: make_attrib.write_vertpos(vert) make_attrib.write_tex_coords(con_mesh, vert, frag, tese) if con_mesh.is_elem('col'): vert.add_out('vec3 vcolor') vert.write_attrib('vcolor = col.rgb;') if tese is not None: tese.write_pre = True make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor')) tese.write_pre = False if con_mesh.is_elem('tang'): if tese is not None: tese.add_out('mat3 TBN') tese.write_attrib( 'vec3 wbitangent = normalize(cross(wnormal, wtangent));') tese.write_attrib('TBN = mat3(wtangent, wbitangent, wnormal);') else: vert.add_out('mat3 TBN') vert.write_attrib('vec3 tangent = normalize(N * tang.xyz);') vert.write_attrib( 'vec3 bitangent = normalize(cross(wnormal, tangent));') vert.write_attrib('TBN = mat3(tangent, bitangent, wnormal);') if is_displacement: if rpdat.arm_rp_displacement == 'Vertex': sh = vert else: sh = tese if (con_mesh.is_elem('ipos')): vert.write('wposition = vec4(W * spos).xyz;') sh.add_uniform('mat4 VP', '_viewProjectionMatrix') sh.write('wposition += wnormal * disp;') sh.write('gl_Position = VP * vec4(wposition, 1.0);')
def make_deferred(con_mesh, rpasses): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() arm_discard = mat_state.material.arm_discard parse_opacity = arm_discard or 'translucent' in rpasses make_base(con_mesh, parse_opacity=parse_opacity) frag = con_mesh.frag vert = con_mesh.vert tese = con_mesh.tese if parse_opacity: if arm_discard: opac = mat_state.material.arm_discard_opacity else: opac = '0.9999' # 1.0 - eps frag.write('if (opacity < {0}) discard;'.format(opac)) gapi = arm.utils.get_gapi() if '_gbuffer2' in wrd.world_defs: frag.add_out('vec4 fragColor[3]') if '_Veloc' in wrd.world_defs: if tese == None: vert.add_uniform('mat4 prevWVP', link='_prevWorldViewProjectionMatrix') vert.add_out('vec4 wvpposition') vert.add_out('vec4 prevwvpposition') vert.write('wvpposition = gl_Position;') if is_displacement: vert.add_uniform('mat4 invW', link='_inverseWorldMatrix') vert.write( 'prevwvpposition = prevWVP * (invW * vec4(wposition, 1.0));' ) else: vert.write('prevwvpposition = prevWVP * spos;') else: tese.add_out('vec4 wvpposition') tese.add_out('vec4 prevwvpposition') tese.write('wvpposition = gl_Position;') if is_displacement: tese.add_uniform('mat4 invW', link='_inverseWorldMatrix') tese.add_uniform('mat4 prevWVP', '_prevWorldViewProjectionMatrix') tese.write( 'prevwvpposition = prevWVP * (invW * vec4(wposition, 1.0));' ) else: vert.add_uniform('mat4 prevW', link='_prevWorldMatrix') vert.add_out('vec3 prevwposition') vert.write('prevwposition = vec4(prevW * spos).xyz;') tese.add_uniform('mat4 prevVP', '_prevViewProjectionMatrix') make_tess.interpolate(tese, 'prevwposition', 3) tese.write( 'prevwvpposition = prevVP * vec4(prevwposition, 1.0);') else: frag.add_out('vec4 fragColor[2]') # Pack gbuffer frag.add_include('std/gbuffer.glsl') if mat_state.material.arm_two_sided: frag.write('if (!gl_FrontFacing) n *= -1;' ) # Flip normal when drawing back-face frag.write('n /= (abs(n.x) + abs(n.y) + abs(n.z));') frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);') if '_Emission' in wrd.world_defs or '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs: frag.write('uint matid = 0;') if '_Emission' in wrd.world_defs: frag.write('if (emission > 0) { basecol *= emission; matid = 1; }') if '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs: frag.add_uniform('int materialID') frag.write('if (materialID == 2) matid = 2;') else: frag.write('const uint matid = 0;') frag.write( 'fragColor[0] = vec4(n.xy, roughness, packFloatInt16(metallic, matid));' ) frag.write( 'fragColor[1] = vec4(basecol, packFloat2(occlusion, specular));') if '_gbuffer2' in wrd.world_defs: if '_Veloc' in wrd.world_defs: frag.write( 'vec2 posa = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;') frag.write( 'vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;' ) frag.write('fragColor[2].rg = vec2(posa - posb);') if mat_state.material.arm_ignore_irradiance: frag.write('fragColor[2].b = 1.0;') return con_mesh
def make_deferred(con_mesh): wrd = bpy.data.worlds['Arm'] rpdat = arm.utils.get_rp() arm_discard = mat_state.material.arm_discard parse_opacity = arm_discard or rpdat.arm_voxelgi_refraction make_base(con_mesh, parse_opacity=parse_opacity) frag = con_mesh.frag vert = con_mesh.vert tese = con_mesh.tese if arm_discard: opac = mat_state.material.arm_discard_opacity frag.write('if (opacity < {0}) discard;'.format(opac)) gapi = arm.utils.get_gapi() if '_gbuffer2' in wrd.world_defs: frag.add_out('vec4[3] fragColor') if '_Veloc' in wrd.world_defs: if tese == None: vert.add_uniform('mat4 prevWVP', link='_prevWorldViewProjectionMatrix') vert.add_out('vec4 wvpposition') vert.add_out('vec4 prevwvpposition') vert.write('wvpposition = gl_Position;') vert.write('prevwvpposition = prevWVP * spos;') else: vert.add_uniform('mat4 prevW', link='_prevWorldMatrix') vert.add_out('vec3 prevwposition') vert.write('prevwposition = vec4(prevW * spos).xyz;') tese.add_out('vec4 wvpposition') tese.add_out('vec4 prevwvpposition') tese.add_uniform('mat4 prevVP', '_prevViewProjectionMatrix') tese.write('wvpposition = gl_Position;') make_tess.interpolate(tese, 'prevwposition', 3) tese.write( 'prevwvpposition = prevVP * vec4(prevwposition, 1.0);') elif gapi.startswith('direct3d'): vert.add_out('vec4 wvpposition') vert.write('wvpposition = gl_Position;') frag.add_out('vec4[2] fragColor') else: frag.add_out('vec4[2] fragColor') # Pack gbuffer frag.add_include('std/gbuffer.glsl') if mat_state.material.arm_two_sided: frag.write('if (!gl_FrontFacing) n *= -1;' ) # Flip normal when drawing back-face frag.write('n /= (abs(n.x) + abs(n.y) + abs(n.z));') frag.write('n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);') # TODO: store_depth if gapi.startswith('direct3d'): frag.write( 'fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), 1.0 - ((wvpposition.z / wvpposition.w) * 0.5 + 0.5));' ) else: frag.write( 'fragColor[0] = vec4(n.xy, packFloat(metallic, roughness), 1.0 - gl_FragCoord.z);' ) frag.write( 'fragColor[1] = vec4(basecol.rgb, packFloat2(occlusion, specular));') if '_gbuffer2' in wrd.world_defs: if '_Veloc' in wrd.world_defs: frag.write( 'vec2 posa = (wvpposition.xy / wvpposition.w) * 0.5 + 0.5;') frag.write( 'vec2 posb = (prevwvpposition.xy / prevwvpposition.w) * 0.5 + 0.5;' ) frag.write('fragColor[2].rg = vec2(posa - posb);') if rpdat.arm_voxelgi_refraction: frag.write('fragColor[2].b = opacity;') if '_SSS' in wrd.world_defs or '_Hair' in wrd.world_defs: frag.add_uniform('int materialID') frag.write('fragColor[2].a = materialID;') return con_mesh
def make_base(con_mesh, parse_opacity): global is_displacement global write_material_attribs global write_material_attribs_post global write_vertex_attribs vert = con_mesh.make_vert() frag = con_mesh.make_frag() geom = None tesc = None tese = None vert.add_uniform('mat3 N', '_normalMatrix') vert.write_attrib(' vec4 spos = vec4(pos, 1.0);') vattr_written = False rpdat = arm.utils.get_rp() is_displacement = mat_utils.disp_linked(mat_state.output_node) if is_displacement: if rpdat.arm_rp_displacement == 'Vertex': frag.ins = vert.outs else: # Tessellation tesc = con_mesh.make_tesc() tese = con_mesh.make_tese() tesc.ins = vert.outs tese.ins = tesc.outs frag.ins = tese.outs make_tess.tesc_levels(tesc, rpdat.arm_tess_mesh_inner, rpdat.arm_tess_mesh_outer) make_tess.interpolate(tese, 'wposition', 3, declare_out=True) make_tess.interpolate(tese, 'wnormal', 3, declare_out=True, normalize=True) # No displacement else: frag.ins = vert.outs if write_vertex_attribs != None: vattr_written = write_vertex_attribs(vert) frag.add_include('compiled.glsl') written = False if write_material_attribs != None: written = write_material_attribs(con_mesh, frag) if written == False: frag.write('vec3 basecol;') frag.write('float roughness;') frag.write('float metallic;') frag.write('float occlusion;') frag.write('float specular;') if parse_opacity: frag.write('float opacity;') cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity) if write_material_attribs_post != None: write_material_attribs_post(con_mesh, frag) if not is_displacement and not vattr_written: write_vertpos(vert) if con_mesh.is_elem('tex'): vert.add_out('vec2 texCoord') if mat_state.material.arm_tilesheet_mat: if mat_state.material.arm_particle == 'gpu': make_particle.write_tilesheet(vert) else: vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset') vert.write_attrib('texCoord = tex + tilesheetOffset;') else: vert.write_attrib('texCoord = tex;') if tese != None: tese.write_pre = True make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord')) tese.write_pre = False if con_mesh.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write_attrib('texCoord1 = tex1;') if tese != None: tese.write_pre = True make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1')) tese.write_pre = False if con_mesh.is_elem('col'): vert.add_out('vec3 vcolor') vert.write_attrib('vcolor = col;') if tese != None: tese.write_pre = True make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor')) tese.write_pre = False if con_mesh.is_elem('tang'): if tese != None: vert.add_out('vec3 wnormal') vert.add_out('vec3 wtangent') write_norpos(con_mesh, vert) vert.write('wtangent = normalize(N * tang);') tese.add_out('mat3 TBN') make_tess.interpolate(tese, 'wtangent', 3, normalize=True) tese.write( 'vec3 wbitangent = normalize(cross(wnormal, wtangent));') tese.write('TBN = mat3(wtangent, wbitangent, wnormal);') else: vert.add_out('mat3 TBN') write_norpos(con_mesh, vert, declare=True) vert.write('vec3 tangent = normalize(N * tang);') vert.write('vec3 bitangent = normalize(cross(wnormal, tangent));') vert.write('TBN = mat3(tangent, bitangent, wnormal);') else: vert.add_out('vec3 wnormal') write_norpos(con_mesh, vert) frag.write_attrib('vec3 n = normalize(wnormal);') if is_displacement: if rpdat.arm_rp_displacement == 'Vertex': sh = vert else: sh = tese sh.add_uniform('mat4 VP', '_viewProjectionMatrix') sh.write('wposition += wnormal * disp * 0.1;') sh.write('gl_Position = VP * vec4(wposition, 1.0);')
def make_base(con_mesh, parse_opacity): global is_displacement global write_material_attribs global write_material_attribs_post global write_vertex_attribs vert = con_mesh.make_vert() frag = con_mesh.make_frag() geom = None tesc = None tese = None vert.add_uniform('mat3 N', '_normalMatrix') vert.write_main_header(' vec4 spos = vec4(pos, 1.0);') vattr_written = False is_displacement = mat_utils.disp_linked(mat_state.output_node) if is_displacement: tesc = con_mesh.make_tesc() tese = con_mesh.make_tese() tesc.ins = vert.outs tese.ins = tesc.outs frag.ins = tese.outs vert.add_uniform('mat4 W', '_worldMatrix') vert.add_out('vec3 wposition') vert.write('wposition = vec4(W * spos).xyz;') make_tess.tesc_levels(tesc, mat_state.material.arm_tess_inner, mat_state.material.arm_tess_outer) make_tess.interpolate(tese, 'wposition', 3, declare_out=True) make_tess.interpolate(tese, 'wnormal', 3, declare_out=True, normalize=True) # No displacement else: frag.ins = vert.outs if write_vertex_attribs != None: vattr_written = write_vertex_attribs(vert) frag.add_include('../../Shaders/compiled.glsl') written = False if write_material_attribs != None: written = write_material_attribs(con_mesh, frag) if written == False: frag.write('vec3 basecol;') frag.write('float roughness;') frag.write('float metallic;') frag.write('float occlusion;') if parse_opacity: frag.write('float opacity;') cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity) if write_material_attribs_post != None: write_material_attribs_post(con_mesh, frag) if not is_displacement and not vattr_written: billboard = mat_state.material.arm_billboard particle = mat_state.material.arm_particle wrd = bpy.data.worlds['Arm'] # Particles if particle != 'off': if particle == 'gpu': make_particle.write(vert, particle_info=cycles.particle_info) # Billboards if billboard == 'spherical': vert.add_uniform('mat4 WV', '_worldViewMatrix') vert.add_uniform('mat4 P', '_projectionMatrix') vert.write( 'gl_Position = P * (WV * vec4(0.0, 0.0, spos.z, 1.0) + vec4(spos.x, spos.y, 0.0, 0.0));' ) else: vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix') vert.write('gl_Position = WVP * spos;') else: # Billboards if billboard == 'spherical': vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixSphere') elif billboard == 'cylindrical': vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixCylinder') else: # off vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix') vert.write('gl_Position = WVP * spos;') if con_mesh.is_elem('tex'): vert.add_out('vec2 texCoord') if mat_state.material.arm_tilesheet_mat: if mat_state.material.arm_particle == 'gpu': make_particle.write_tilesheet(vert) else: vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset') vert.write('texCoord = tex + tilesheetOffset;') else: vert.write('texCoord = tex;') if tese != None: # TODO: also includes texCoord1 tese.write_pre = True make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord')) tese.write_pre = False if con_mesh.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') if tese != None: tese.write_pre = True make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1')) tese.write_pre = False if con_mesh.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col;') if tese != None: tese.write_pre = True make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor')) tese.write_pre = False if con_mesh.is_elem('tang'): if tese != None: vert.add_out('vec3 wnormal') vert.add_out('vec3 wtangent') write_norpos(con_mesh, vert) vert.write('wtangent = normalize(N * tang);') tese.add_out('mat3 TBN') make_tess.interpolate(tese, 'wtangent', 3, normalize=True) tese.write( 'vec3 wbitangent = normalize(cross(wnormal, wtangent));') tese.write('TBN = mat3(wtangent, wbitangent, wnormal);') else: vert.add_out('mat3 TBN') write_norpos(con_mesh, vert, declare=True) vert.write('vec3 tangent = normalize(N * tang);') vert.write('vec3 bitangent = normalize(cross(wnormal, tangent));') vert.write('TBN = mat3(tangent, bitangent, wnormal);') else: vert.add_out('vec3 wnormal') write_norpos(con_mesh, vert) frag.prepend_header('vec3 n = normalize(wnormal);') if tese != None: tese.add_uniform('mat4 VP', '_viewProjectionMatrix') # TODO: Sample disp at neightbour points to calc normal tese.write('wposition += wnormal * disp * 0.2;') tese.write('gl_Position = VP * vec4(wposition, 1.0);')
def make(context_id, rpasses): is_disp = mat_utils.disp_linked( mat_state.output_node) and mat_state.material.height_tess_shadows vs = [{'name': 'pos', 'size': 3}] if is_disp: vs.append({'name': 'nor', 'size': 3}) con_shadowmap = mat_state.data.add_context({ 'name': context_id, 'vertex_structure': vs, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False }) vert = con_shadowmap.make_vert() frag = con_shadowmap.make_frag() geom = None tesc = None tese = None gapi = arm.utils.get_gapi() if gapi == 'direct3d9': frag.add_out( 'vec4 fragColor' ) # Definition requred for d3d9 - pixel shader must minimally write all four components of COLOR0 vert.write_main_header('vec4 spos = vec4(pos, 1.0);') parse_opacity = 'translucent' in rpasses or mat_state.material.discard_transparent if parse_opacity: frag.write('vec3 n;') # Discard at compile time frag.write('float dotNV;') frag.write('float opacity;') if con_shadowmap.is_elem('bone'): make_skin.skin_pos(vert) if con_shadowmap.is_elem('off'): vert.write('spos.xyz += off;') if is_disp: tesc = con_shadowmap.make_tesc() tese = con_shadowmap.make_tese() tesc.ins = vert.outs tese.ins = tesc.outs frag.ins = tese.outs vert.add_out('vec3 wposition') vert.add_out('vec3 wnormal') vert.add_uniform('mat4 W', '_worldMatrix') vert.add_uniform('mat3 N', '_normalMatrix') vert.write('wnormal = normalize(N * nor);') vert.write('wposition = vec4(W * spos).xyz;') const = {} const['name'] = 'tessLevel' const['vec2'] = [ mat_state.material.height_tess_shadows_inner, mat_state.material.height_tess_shadows_outer ] mat_state.bind_constants.append(const) tesc.add_uniform('vec2 tessLevel') make_tess.tesc_levels(tesc) make_tess.interpolate(tese, 'wposition', 3) make_tess.interpolate(tese, 'wnormal', 3, normalize=True) cycles.parse(mat_state.nodes, con_shadowmap, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=parse_opacity) if con_shadowmap.is_elem('tex'): vert.add_out('vec2 texCoord') vert.write('texCoord = tex;') tese.write_pre = True make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord')) tese.write_pre = False if con_shadowmap.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') tese.write_pre = True make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1')) tese.write_pre = False if con_shadowmap.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col;') tese.write_pre = True make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor')) tese.write_pre = False tese.add_uniform('mat4 LVP', '_lampViewProjectionMatrix') tese.write('wposition += wnormal * disp * 0.2;') tese.write('gl_Position = LVP * vec4(wposition, 1.0);') # No displacement else: frag.ins = vert.outs vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix') vert.write('gl_Position = LWVP * spos;') if parse_opacity: cycles.parse(mat_state.nodes, con_shadowmap, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=True) if con_shadowmap.is_elem('tex'): vert.add_out('vec2 texCoord') vert.write('texCoord = tex;') if con_shadowmap.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') if con_shadowmap.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col;') # TODO: interleaved buffer has to match vertex structure of mesh context if not bpy.data.worlds['Arm'].arm_deinterleaved_buffers: con_shadowmap.add_elem('nor', 3) if mat_state.material.export_uvs: con_shadowmap.add_elem('tex', 2) # TODO: pass vbuf with proper struct if gapi.startswith('direct3d') and bpy.data.worlds[ 'Arm'].arm_deinterleaved_buffers == False: vert.write('vec3 t1 = nor; // TODO: Temp for d3d') if con_shadowmap.is_elem('tex'): vert.write('vec2 t2 = tex; // TODO: Temp for d3d') if parse_opacity: opac = mat_state.material.discard_transparent_opacity_shadows frag.write('if (opacity < {0}) discard;'.format(opac)) # frag.write('fragColor = vec4(0.0);') make_mesh.make_finalize(con_shadowmap) return con_shadowmap
def make(context_id, rpasses, shadowmap=False): is_disp = mat_utils.disp_linked(mat_state.output_node) vs = [{'name': 'pos', 'data': 'short4norm'}] if is_disp: vs.append({'name': 'nor', 'data': 'short2norm'}) con_depth = mat_state.data.add_context({ 'name': context_id, 'vertex_elements': vs, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise', 'color_writes_red': [False], 'color_writes_green': [False], 'color_writes_blue': [False], 'color_writes_alpha': [False] }) vert = con_depth.make_vert() frag = con_depth.make_frag() geom = None tesc = None tese = None vert.write_attrib('vec4 spos = vec4(pos.xyz, 1.0);') parse_opacity = 'translucent' in rpasses or mat_state.material.arm_discard if parse_opacity: frag.write('vec3 n;') # Discard at compile time frag.write('float dotNV;') frag.write('float opacity;') if con_depth.is_elem('bone'): make_skin.skin_pos(vert) if con_depth.is_elem('ipos'): make_inst.inst_pos(con_depth, vert) rpdat = arm.utils.get_rp() if mat_state.material.arm_particle_flag and rpdat.arm_particles == 'On': make_particle.write(vert, shadowmap=shadowmap) if is_disp: if rpdat.arm_rp_displacement == 'Vertex': frag.ins = vert.outs vert.add_uniform('mat3 N', '_normalMatrix') vert.write('vec3 wnormal = normalize(N * vec3(nor.xy, pos.w));') cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=parse_opacity) if con_depth.is_elem('tex'): vert.add_out('vec2 texCoord') ## vs only, remove out vert.add_uniform('float texUnpack', link='_texUnpack') vert.write_attrib('texCoord = tex * texUnpack;') if con_depth.is_elem('tex1'): vert.add_out('vec2 texCoord1') ## vs only, remove out vert.add_uniform('float texUnpack', link='_texUnpack') vert.write_attrib('texCoord1 = tex1 * texUnpack;') if con_depth.is_elem('col'): vert.add_out('vec3 vcolor') vert.write_attrib('vcolor = col.rgb;') vert.write('wposition += wnormal * disp;') if shadowmap: vert.add_uniform('mat4 LVP', '_lightViewProjectionMatrix') vert.write('gl_Position = LVP * vec4(wposition, 1.0);') else: vert.add_uniform('mat4 VP', '_viewProjectionMatrix') vert.write('gl_Position = VP * vec4(wposition, 1.0);') else: # Tessellation tesc = con_depth.make_tesc() tese = con_depth.make_tese() tesc.ins = vert.outs tese.ins = tesc.outs frag.ins = tese.outs vert.add_out('vec3 wnormal') vert.add_uniform('mat3 N', '_normalMatrix') vert.write('wnormal = normalize(N * vec3(nor.xy, pos.w));') make_tess.tesc_levels(tesc, rpdat.arm_tess_shadows_inner, rpdat.arm_tess_shadows_outer) make_tess.interpolate(tese, 'wposition', 3) make_tess.interpolate(tese, 'wnormal', 3, normalize=True) cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=parse_opacity) if con_depth.is_elem('tex'): vert.add_out('vec2 texCoord') vert.add_uniform('float texUnpack', link='_texUnpack') vert.write('texCoord = tex * texUnpack;') tese.write_pre = True make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord')) tese.write_pre = False if con_depth.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') tese.write_pre = True make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1')) tese.write_pre = False if con_depth.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col.rgb;') tese.write_pre = True make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor')) tese.write_pre = False if shadowmap: tese.add_uniform('mat4 LVP', '_lightViewProjectionMatrix') tese.write('wposition += wnormal * disp;') tese.write('gl_Position = LVP * vec4(wposition, 1.0);') else: tese.add_uniform('mat4 VP', '_viewProjectionMatrix') tese.write('wposition += wnormal * disp;') tese.write('gl_Position = VP * vec4(wposition, 1.0);') # No displacement else: frag.ins = vert.outs billboard = mat_state.material.arm_billboard if shadowmap: if billboard == 'spherical': vert.add_uniform('mat4 LWVP', '_lightWorldViewProjectionMatrixSphere') elif billboard == 'cylindrical': vert.add_uniform('mat4 LWVP', '_lightWorldViewProjectionMatrixCylinder') else: # off vert.add_uniform('mat4 LWVP', '_lightWorldViewProjectionMatrix') vert.write('gl_Position = LWVP * spos;') else: if billboard == 'spherical': vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixSphere') elif billboard == 'cylindrical': vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixCylinder') else: # off vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix') vert.write('gl_Position = WVP * spos;') if parse_opacity: cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=True) if con_depth.is_elem('tex'): vert.add_out('vec2 texCoord') vert.add_uniform('float texUnpack', link='_texUnpack') if mat_state.material.arm_tilesheet_flag: vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset') vert.write('texCoord = tex * texUnpack + tilesheetOffset;') else: vert.write('texCoord = tex * texUnpack;') if con_depth.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') if con_depth.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col.rgb;') if parse_opacity: if mat_state.material.arm_discard: opac = mat_state.material.arm_discard_opacity_shadows else: opac = '1.0' frag.write('if (opacity < {0}) discard;'.format(opac)) make_finalize.make(con_depth) assets.vs_equal(con_depth, assets.shader_cons['depth_vert']) assets.fs_equal(con_depth, assets.shader_cons['depth_frag']) return con_depth
def make(con_mesh): vert = con_mesh.vert frag = con_mesh.frag geom = con_mesh.geom tesc = con_mesh.tesc tese = con_mesh.tese # Additional values referenced in cycles # TODO: enable from cycles.py if frag.contains('dotNV') and not frag.contains('float dotNV'): frag.write_init('float dotNV = max(dot(n, vVec), 0.0);') write_wpos = False if frag.contains('vVec') and not frag.contains('vec3 vVec'): if tese != None: tese.add_out('vec3 eyeDir') tese.add_uniform('vec3 eye', '_cameraPosition') tese.write('eyeDir = eye - wposition;') else: if not vert.contains('wposition'): write_wpos = True vert.add_out('vec3 eyeDir') vert.add_uniform('vec3 eye', '_cameraPosition') vert.write('eyeDir = eye - wposition;') frag.write_attrib('vec3 vVec = normalize(eyeDir);') export_wpos = False if frag.contains('wposition') and not frag.contains('vec3 wposition'): export_wpos = True if tese != None: export_wpos = True if vert.contains('wposition'): write_wpos = True if export_wpos: vert.add_uniform('mat4 W', '_worldMatrix') vert.add_out('vec3 wposition') vert.write_attrib('wposition = vec4(W * spos).xyz;') elif write_wpos: vert.add_uniform('mat4 W', '_worldMatrix') vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;') frag_mpos = ( frag.contains('mposition') and not frag.contains('vec3 mposition')) or vert.contains('mposition') if frag_mpos: vert.add_out('vec3 mposition') vert.write_attrib('mposition = spos.xyz;') if tese != None: if frag_mpos: make_tess.interpolate(tese, 'mposition', 3, declare_out=True) elif tese.contains( 'mposition') and not tese.contains('vec3 mposition'): vert.add_out('vec3 mposition') vert.write_pre = True vert.write('mposition = spos.xyz;') vert.write_pre = False make_tess.interpolate(tese, 'mposition', 3, declare_out=False) frag_bpos = ( frag.contains('bposition') and not frag.contains('vec3 bposition')) or vert.contains('bposition') if frag_bpos: vert.add_out('vec3 bposition') vert.add_uniform('vec3 dim', link='_dim') vert.add_uniform('vec3 hdim', link='_halfDim') vert.write_pre = True vert.write('bposition = (spos.xyz + hdim) / dim;') vert.write_pre = False if tese != None: if frag_bpos: make_tess.interpolate(tese, 'bposition', 3, declare_out=True) elif tese.contains( 'bposition') and not tese.contains('vec3 bposition'): vert.add_out('vec3 bposition') vert.write_pre = True vert.write('bposition = spos.xyz;') vert.write_pre = False make_tess.interpolate(tese, 'bposition', 3, declare_out=False) frag_wtan = ( frag.contains('wtangent') and not frag.contains('vec3 wtangent')) or vert.contains('wtangent') if frag_wtan: # Indicate we want tang attrib in finalizer to prevent TBN generation con_mesh.add_elem('tex', 'short2norm') con_mesh.add_elem('tang', 'short4norm') vert.add_out('vec3 wtangent') vert.write_pre = True vert.write('wtangent = normalize(N * tang.xyz);') vert.write_pre = False if tese != None: if frag_wtan: make_tess.interpolate(tese, 'wtangent', 3, declare_out=True) elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'): vert.add_out('vec3 wtangent') vert.write_pre = True vert.write('wtangent = normalize(N * tang.xyz);') vert.write_pre = False make_tess.interpolate(tese, 'wtangent', 3, declare_out=False) if frag.contains('vVecCam'): vert.add_out('vec3 eyeDirCam') vert.add_uniform('mat4 WV', '_worldViewMatrix') vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;') frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);')
def make_base(con_mesh, parse_opacity): global is_displacement global write_material_attribs global write_material_attribs_post global write_vertex_attribs vert = con_mesh.make_vert() frag = con_mesh.make_frag() geom = None tesc = None tese = None vert.add_uniform('mat3 N', '_normalMatrix') vert.write_main_header('vec4 spos = vec4(pos, 1.0);') if mat_utils.disp_linked(mat_state.output_node): is_displacement = True tesc = con_mesh.make_tesc() tese = con_mesh.make_tese() tesc.ins = vert.outs tese.ins = tesc.outs frag.ins = tese.outs vert.add_uniform('mat4 W', '_worldMatrix') vert.add_out('vec3 wposition') vert.write('wposition = vec4(W * spos).xyz;') make_tess.tesc_levels(tesc, mat_state.material.arm_tess_inner, mat_state.material.arm_tess_outer) make_tess.interpolate(tese, 'wposition', 3, declare_out=True) make_tess.interpolate(tese, 'wnormal', 3, declare_out=True, normalize=True) # No displacement else: is_displacement = False frag.ins = vert.outs written = False if write_vertex_attribs != None: written = write_vertex_attribs(vert) if written == False: vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix') vert.write('gl_Position = WVP * spos;') frag.add_include('../../Shaders/compiled.glsl') written = False if write_material_attribs != None: written = write_material_attribs(con_mesh, frag) if written == False: frag.write('vec3 basecol;') frag.write('float roughness;') frag.write('float metallic;') frag.write('float occlusion;') if parse_opacity: frag.write('float opacity;') cycles.parse(mat_state.nodes, con_mesh, vert, frag, geom, tesc, tese, parse_opacity=parse_opacity) if write_material_attribs_post != None: write_material_attribs_post(con_mesh, frag) if con_mesh.is_elem('tex'): vert.add_out('vec2 texCoord') vert.write('texCoord = tex;') if tese != None: # TODO: also includes texCoord1 tese.write_pre = True make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord')) tese.write_pre = False if con_mesh.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') if tese != None: tese.write_pre = True make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1')) tese.write_pre = False if con_mesh.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = pow(col, vec3(2.2));') if tese != None: tese.write_pre = True make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor')) tese.write_pre = False if con_mesh.is_elem('tang'): if tese != None: vert.add_out('vec3 wnormal') vert.add_out('vec3 wtangent') write_norpos(con_mesh, vert) vert.write('wtangent = normalize(N * tang);') tese.add_out('mat3 TBN') make_tess.interpolate(tese, 'wtangent', 3, normalize=True) tese.write( 'vec3 wbitangent = normalize(cross(wnormal, wtangent));') tese.write('TBN = mat3(wtangent, wbitangent, wnormal);') else: vert.add_out('mat3 TBN') write_norpos(con_mesh, vert, declare=True) vert.write('vec3 tangent = normalize(N * tang);') vert.write('vec3 bitangent = normalize(cross(wnormal, tangent));') vert.write('TBN = mat3(tangent, bitangent, wnormal);') else: vert.add_out('vec3 wnormal') write_norpos(con_mesh, vert) frag.write_pre = True frag.write_main_header('vec3 n = normalize(wnormal);') frag.write_pre = False if tese != None: tese.add_uniform('mat4 VP', '_viewProjectionMatrix') # TODO: Sample disp at neightbour points to calc normal tese.write('wposition += wnormal * disp * 0.2;') tese.write('gl_Position = VP * vec4(wposition, 1.0);')
def make(context_id, rpasses, shadowmap=False): is_disp = mat_utils.disp_linked( mat_state.output_node) and mat_state.material.arm_tess_shadows vs = [{'name': 'pos', 'size': 3}] if is_disp: vs.append({'name': 'nor', 'size': 3}) con_depth = mat_state.data.add_context({ 'name': context_id, 'vertex_structure': vs, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False }) vert = con_depth.make_vert() frag = con_depth.make_frag() geom = None tesc = None tese = None vert.write_main_header('vec4 spos = vec4(pos, 1.0);') parse_opacity = 'translucent' in rpasses or mat_state.material.arm_discard if parse_opacity: frag.write('vec3 n;') # Discard at compile time frag.write('float dotNV;') frag.write('float opacity;') if con_depth.is_elem('bone'): make_skin.skin_pos(vert) if con_depth.is_elem('off'): vert.write('spos.xyz += off;') wrd = bpy.data.worlds['Arm'] if mat_state.material.arm_particle == 'gpu': make_particle.write(vert) if is_disp: tesc = con_depth.make_tesc() tese = con_depth.make_tese() tesc.ins = vert.outs tese.ins = tesc.outs frag.ins = tese.outs vert.add_out('vec3 wposition') vert.add_out('vec3 wnormal') vert.add_uniform('mat4 W', '_worldMatrix') vert.add_uniform('mat3 N', '_normalMatrix') vert.write('wnormal = normalize(N * nor);') vert.write('wposition = vec4(W * spos).xyz;') make_tess.tesc_levels(tesc, mat_state.material.arm_tess_shadows_inner, mat_state.material.arm_tess_shadows_outer) make_tess.interpolate(tese, 'wposition', 3) make_tess.interpolate(tese, 'wnormal', 3, normalize=True) cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=parse_opacity) if con_depth.is_elem('tex'): vert.add_out('vec2 texCoord') vert.write('texCoord = tex;') tese.write_pre = True make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord')) tese.write_pre = False if con_depth.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') tese.write_pre = True make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1')) tese.write_pre = False if con_depth.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col;') tese.write_pre = True make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor')) tese.write_pre = False if shadowmap: tese.add_uniform('mat4 LVP', '_lampViewProjectionMatrix') tese.write('wposition += wnormal * disp * 0.2;') tese.write('gl_Position = LVP * vec4(wposition, 1.0);') else: tese.add_uniform('mat4 VP', '_viewProjectionMatrix') tese.write('wposition += wnormal * disp * 0.2;') tese.write('gl_Position = VP * vec4(wposition, 1.0);') # No displacement else: frag.ins = vert.outs billboard = mat_state.material.arm_billboard if shadowmap: if billboard == 'spherical': vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrixSphere') elif billboard == 'cylindrical': vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrixCylinder') else: # off vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix') vert.write('gl_Position = LWVP * spos;') else: if billboard == 'spherical': vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixSphere') elif billboard == 'cylindrical': vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixCylinder') else: # off vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix') vert.write('gl_Position = WVP * spos;') if parse_opacity: cycles.parse(mat_state.nodes, con_depth, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=True) if con_depth.is_elem('tex'): vert.add_out('vec2 texCoord') if mat_state.material.arm_tilesheet_mat: vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset') vert.write('texCoord = tex + tilesheetOffset;') else: vert.write('texCoord = tex;') if con_depth.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') if con_depth.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col;') # TODO: interleaved buffer has to match vertex structure of mesh context if not bpy.data.worlds['Arm'].arm_deinterleaved_buffers: con_depth.add_elem('nor', 3) if mat_state.con_mesh != None: if mat_state.con_mesh.is_elem('tex'): con_depth.add_elem('tex', 2) if mat_state.con_mesh.is_elem('tex1'): con_depth.add_elem('tex1', 2) if mat_state.con_mesh.is_elem('col'): con_depth.add_elem('col', 3) if mat_state.con_mesh.is_elem('tang'): con_depth.add_elem('tang', 4) # TODO: pass vbuf with proper struct gapi = arm.utils.get_gapi() if gapi.startswith('direct3d') and bpy.data.worlds[ 'Arm'].arm_deinterleaved_buffers == False: vert.write('vec3 t1 = nor; // TODO: Temp for d3d') if con_depth.is_elem('tex'): vert.write('vec2 t2 = tex; // TODO: Temp for d3d') if parse_opacity: opac = mat_state.material.arm_discard_opacity_shadows frag.write('if (opacity < {0}) discard;'.format(opac)) make_mesh.make_finalize(con_depth) assets.vs_equal(con_depth, assets.shader_cons['depth_vert']) assets.fs_equal(con_depth, assets.shader_cons['depth_frag']) return con_depth
def make(con_mesh: ShaderContext): vert = con_mesh.vert frag = con_mesh.frag geom = con_mesh.geom tesc = con_mesh.tesc tese = con_mesh.tese # Additional values referenced in cycles # TODO: enable from cycles.py if frag.contains('dotNV') and not frag.contains('float dotNV'): frag.write_init('float dotNV = max(dot(n, vVec), 0.0);') # n is not always defined yet (in some shadowmap shaders e.g.) if not frag.contains('vec3 n'): vert.add_out('vec3 wnormal') vert.add_uniform('mat3 N', '_normalMatrix') vert.write_attrib('wnormal = normalize(N * vec3(nor.xy, pos.w));') frag.write_attrib('vec3 n = normalize(wnormal);') # If not yet added, add nor vertex data vertex_elems = con_mesh.data['vertex_elements'] has_normals = False for elem in vertex_elems: if elem['name'] == 'nor': has_normals = True break if not has_normals: vertex_elems.append({'name': 'nor', 'data': 'short2norm'}) write_wpos = False if frag.contains('vVec') and not frag.contains('vec3 vVec'): if tese is not None: tese.add_out('vec3 eyeDir') tese.add_uniform('vec3 eye', '_cameraPosition') tese.write('eyeDir = eye - wposition;') else: if not vert.contains('wposition'): write_wpos = True vert.add_out('vec3 eyeDir') vert.add_uniform('vec3 eye', '_cameraPosition') vert.write('eyeDir = eye - wposition;') frag.write_attrib('vec3 vVec = normalize(eyeDir);') export_wpos = False if frag.contains('wposition') and not frag.contains('vec3 wposition'): export_wpos = True if tese is not None: export_wpos = True if vert.contains('wposition'): write_wpos = True if export_wpos: vert.add_uniform('mat4 W', '_worldMatrix') vert.add_out('vec3 wposition') vert.write_attrib('wposition = vec4(W * spos).xyz;') elif write_wpos: vert.add_uniform('mat4 W', '_worldMatrix') vert.write_attrib('vec3 wposition = vec4(W * spos).xyz;') frag_mpos = ( frag.contains('mposition') and not frag.contains('vec3 mposition')) or vert.contains('mposition') if frag_mpos: vert.add_out('vec3 mposition') vert.add_uniform('float posUnpack', link='_posUnpack') vert.write_attrib('mposition = spos.xyz * posUnpack;') if tese is not None: if frag_mpos: make_tess.interpolate(tese, 'mposition', 3, declare_out=True) elif tese.contains( 'mposition') and not tese.contains('vec3 mposition'): vert.add_out('vec3 mposition') vert.write_pre = True vert.add_uniform('float posUnpack', link='_posUnpack') vert.write('mposition = spos.xyz * posUnpack;') vert.write_pre = False make_tess.interpolate(tese, 'mposition', 3, declare_out=False) frag_bpos = ( frag.contains('bposition') and not frag.contains('vec3 bposition')) or vert.contains('bposition') if frag_bpos: vert.add_out('vec3 bposition') vert.add_uniform('vec3 dim', link='_dim') vert.add_uniform('vec3 hdim', link='_halfDim') vert.add_uniform('float posUnpack', link='_posUnpack') vert.write_attrib('bposition = (spos.xyz * posUnpack + hdim) / dim;') vert.write_attrib('if (dim.z == 0) bposition.z = 0;') vert.write_attrib('if (dim.y == 0) bposition.y = 0;') vert.write_attrib('if (dim.x == 0) bposition.x = 0;') if tese is not None: if frag_bpos: make_tess.interpolate(tese, 'bposition', 3, declare_out=True) elif tese.contains( 'bposition') and not tese.contains('vec3 bposition'): vert.add_out('vec3 bposition') vert.add_uniform('vec3 dim', link='_dim') vert.add_uniform('vec3 hdim', link='_halfDim') vert.add_uniform('float posUnpack', link='_posUnpack') vert.write_attrib( 'bposition = (spos.xyz * posUnpack + hdim) / dim;') make_tess.interpolate(tese, 'bposition', 3, declare_out=False) frag_wtan = ( frag.contains('wtangent') and not frag.contains('vec3 wtangent')) or vert.contains('wtangent') if frag_wtan: # Indicate we want tang attrib in finalizer to prevent TBN generation con_mesh.add_elem('tex', 'short2norm') con_mesh.add_elem('tang', 'short4norm') vert.add_out('vec3 wtangent') vert.write_pre = True vert.write('wtangent = normalize(N * tang.xyz);') vert.write_pre = False if tese is not None: if frag_wtan: make_tess.interpolate(tese, 'wtangent', 3, declare_out=True) elif tese.contains('wtangent') and not tese.contains('vec3 wtangent'): vert.add_out('vec3 wtangent') vert.write_pre = True vert.write('wtangent = normalize(N * tang.xyz);') vert.write_pre = False make_tess.interpolate(tese, 'wtangent', 3, declare_out=False) if frag.contains('vVecCam'): vert.add_out('vec3 eyeDirCam') vert.add_uniform('mat4 WV', '_worldViewMatrix') vert.write('eyeDirCam = vec4(WV * spos).xyz; eyeDirCam.z *= -1;') frag.write_attrib('vec3 vVecCam = normalize(eyeDirCam);') if frag.contains('nAttr'): vert.add_out('vec3 nAttr') vert.write_attrib('nAttr = vec3(nor.xy, pos.w);') wrd = bpy.data.worlds['Arm'] if '_Legacy' in wrd.world_defs: frag.replace('sampler2DShadow', 'sampler2D') frag.replace('samplerCubeShadow', 'samplerCube')
def make(context_id, rpasses): con_shadowmap = mat_state.data.add_context({ 'name': context_id, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise', 'color_write_red': False, 'color_write_green': False, 'color_write_blue': False, 'color_write_alpha': False }) vert = con_shadowmap.make_vert() frag = con_shadowmap.make_frag() geom = None tesc = None tese = None # frag.add_out('vec4 fragColor') vert.write_main_header('vec4 spos = vec4(pos, 1.0);') # TODO: pass vbuf with proper struct vert.write('vec3 t1 = nor; // TODO: Temp for d3d') if mat_state.data.is_elem('tex'): vert.write('vec2 t2 = tex; // TODO: Temp for d3d') parse_opacity = 'translucent' in rpasses if parse_opacity: frag.write('vec3 n;') # Discard at compile time frag.write('float dotNV;') frag.write('float opacity;') if mat_state.data.is_elem('bone'): make_skin.skin_pos(vert) if mat_state.data.is_elem('off'): vert.write('spos.xyz += off;') if mat_utils.disp_linked( mat_state.output_node) and mat_state.material.height_tess_shadows: tesc = con_shadowmap.make_tesc() tese = con_shadowmap.make_tese() tesc.ins = vert.outs tese.ins = tesc.outs frag.ins = tese.outs vert.add_out('vec3 wposition') vert.add_out('vec3 wnormal') vert.add_uniform('mat4 W', '_worldMatrix') vert.add_uniform('mat3 N', '_normalMatrix') vert.write('wnormal = normalize(N * nor);') vert.write('wposition = vec4(W * spos).xyz;') const = {} const['name'] = 'tessLevel' const['vec2'] = [ mat_state.material.height_tess_shadows_inner, mat_state.material.height_tess_shadows_outer ] mat_state.bind_constants.append(const) tesc.add_uniform('vec2 tessLevel') make_tess.tesc_levels(tesc) make_tess.interpolate(tese, 'wposition', 3) make_tess.interpolate(tese, 'wnormal', 3, normalize=True) cycles.parse(mat_state.nodes, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=parse_opacity) if mat_state.data.is_elem('tex'): vert.add_out('vec2 texCoord') vert.write('texCoord = tex;') tese.write_pre = True make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord')) tese.write_pre = False if mat_state.data.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') tese.write_pre = True make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1')) tese.write_pre = False if mat_state.data.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col;') tese.write_pre = True make_tess.interpolate(tese, 'vcolor', 3, declare_out=frag.contains('vcolor')) tese.write_pre = False tese.add_uniform('mat4 LVP', '_lampViewProjectionMatrix') tese.write('wposition += wnormal * disp * 0.2;') tese.write('gl_Position = LVP * vec4(wposition, 1.0);') # No displacement else: frag.ins = vert.outs vert.add_uniform('mat4 LWVP', '_lampWorldViewProjectionMatrix') vert.write('gl_Position = LWVP * spos;') if parse_opacity: cycles.parse(mat_state.nodes, vert, frag, geom, tesc, tese, parse_surface=False, parse_opacity=True) if mat_state.data.is_elem('tex'): vert.add_out('vec2 texCoord') vert.write('texCoord = tex;') if mat_state.data.is_elem('tex1'): vert.add_out('vec2 texCoord1') vert.write('texCoord1 = tex1;') if mat_state.data.is_elem('col'): vert.add_out('vec3 vcolor') vert.write('vcolor = col;') if parse_opacity: frag.write('if (opacity < 0.5) discard;') # frag.write('fragColor = vec4(0.0);') make_mesh.make_finalize(con_shadowmap) return con_shadowmap