Fix world shader compilation for various input coordinate types
This commit is contained in:
parent
6b797b75ae
commit
860594266c
|
@ -62,6 +62,8 @@ def create_world_shaders(world: bpy.types.World):
|
|||
frag.add_in('vec3 normal')
|
||||
frag.add_out('vec4 fragColor')
|
||||
|
||||
frag.write_attrib('vec3 n = normalize(normal);')
|
||||
|
||||
vert.write('''normal = nor;
|
||||
vec4 position = SMVP * vec4(pos, 1.0);
|
||||
gl_Position = vec4(position);''')
|
||||
|
@ -157,7 +159,6 @@ def build_node_tree(world: bpy.types.World, frag: Shader, vert: Shader, con: Sha
|
|||
frag.write('fragColor.rgb = pow(fragColor.rgb, vec3(2.2));')
|
||||
|
||||
if '_EnvClouds' in world.world_defs:
|
||||
frag.write_init('vec3 n = normalize(normal);')
|
||||
frag.write('if (n.z > 0.0) fragColor.rgb = mix(fragColor.rgb, traceClouds(fragColor.rgb, n), clamp(n.z * 5.0, 0, 1));')
|
||||
|
||||
if '_EnvLDR' in world.world_defs:
|
||||
|
@ -171,8 +172,22 @@ def build_node_tree(world: bpy.types.World, frag: Shader, vert: Shader, con: Sha
|
|||
if frag_bpos:
|
||||
frag.add_in('vec3 bposition')
|
||||
vert.add_out('vec3 bposition')
|
||||
# Use normals for now
|
||||
vert.write('bposition = nor;')
|
||||
|
||||
frag_mpos = (frag.contains('mposition') and not frag.contains('vec3 mposition')) or vert.contains('mposition')
|
||||
if frag_mpos:
|
||||
frag.add_in('vec3 mposition')
|
||||
vert.add_out('vec3 mposition')
|
||||
# Use normals for now
|
||||
vert.write('mposition = nor;')
|
||||
|
||||
if frag.contains('texCoord') and not frag.contains('vec2 texCoord'):
|
||||
frag.add_in('vec2 texCoord')
|
||||
vert.add_out('vec2 texCoord')
|
||||
# World has no UV map
|
||||
vert.write('texCoord = vec2(1.0, 1.0);')
|
||||
|
||||
|
||||
def parse_world_output(world: bpy.types.World, node_output: bpy.types.Node, frag: Shader, con: ShaderContext) -> bool:
|
||||
"""Parse the world's output node. Return `False` when the node has
|
||||
|
|
|
@ -3,7 +3,7 @@ from typing import Union
|
|||
|
||||
import arm.material.cycles as c
|
||||
import arm.material.cycles_functions as c_functions
|
||||
from arm.material.parser_state import ParserState
|
||||
from arm.material.parser_state import ParserState, ParserContext
|
||||
from arm.material.shader import floatstr, vec3str
|
||||
import arm.utils
|
||||
|
||||
|
@ -120,24 +120,42 @@ def parse_hairinfo(node: bpy.types.ShaderNodeHairInfo, out_socket: bpy.types.Nod
|
|||
def parse_objectinfo(node: bpy.types.ShaderNodeObjectInfo, out_socket: bpy.types.NodeSocket, state: ParserState) -> Union[floatstr, vec3str]:
|
||||
# Location
|
||||
if out_socket == node.outputs[0]:
|
||||
if state.context == ParserContext.WORLD:
|
||||
return c.to_vec3((0.0, 0.0, 0.0))
|
||||
return 'wposition'
|
||||
|
||||
# TODO: Color
|
||||
elif out_socket == node.outputs[1]:
|
||||
return 'wposition' # c.to_vec3(object.color)
|
||||
if state.context == ParserContext.WORLD:
|
||||
# Use world strength like Blender
|
||||
background_node = c.node_by_type(state.world.node_tree.nodes, 'BACKGROUND')
|
||||
if background_node is None:
|
||||
return c.to_vec3((0.0, 0.0, 0.0))
|
||||
return c.to_vec3([background_node.inputs[1].default_value] * 3)
|
||||
|
||||
# TODO: Implement object color in Iron
|
||||
# state.curshader.add_uniform('vec3 objectInfoColor', link='_objectInfoColor')
|
||||
# return 'objectInfoColor'
|
||||
return c.to_vec3((1.0, 1.0, 1.0))
|
||||
|
||||
# Object Index
|
||||
elif out_socket == node.outputs[2]:
|
||||
if state.context == ParserContext.WORLD:
|
||||
return '0.0'
|
||||
state.curshader.add_uniform('float objectInfoIndex', link='_objectInfoIndex')
|
||||
return 'objectInfoIndex'
|
||||
|
||||
# Material Index
|
||||
elif out_socket == node.outputs[3]:
|
||||
if state.context == ParserContext.WORLD:
|
||||
return '0.0'
|
||||
state.curshader.add_uniform('float objectInfoMaterialIndex', link='_objectInfoMaterialIndex')
|
||||
return 'objectInfoMaterialIndex'
|
||||
|
||||
# Random
|
||||
elif out_socket == node.outputs[4]:
|
||||
if state.context == ParserContext.WORLD:
|
||||
return '0.0'
|
||||
state.curshader.add_uniform('float objectInfoRandom', link='_objectInfoRandom')
|
||||
return 'objectInfoRandom'
|
||||
|
||||
|
@ -204,7 +222,9 @@ def parse_texcoord(node: bpy.types.ShaderNodeTexCoord, out_socket: bpy.types.Nod
|
|||
elif out_socket == node.outputs[4]: # Camera
|
||||
return 'vec3(0.0)' # 'vposition'
|
||||
elif out_socket == node.outputs[5]: # Window
|
||||
return 'vec3(0.0)' # 'wvpposition'
|
||||
# TODO: Don't use gl_FragCoord here, it uses different axes on different graphics APIs
|
||||
state.frag.add_uniform('vec2 screenSize', link='_screenSize')
|
||||
return f'vec3(gl_FragCoord.xy / screenSize, 0.0)'
|
||||
elif out_socket == node.outputs[6]: # Reflection
|
||||
return 'vec3(0.0)'
|
||||
|
||||
|
|
|
@ -351,7 +351,6 @@ def parse_tex_sky(node: bpy.types.ShaderNodeTexSky, out_socket: bpy.types.NodeSo
|
|||
|
||||
state.radiance_written = True
|
||||
|
||||
curshader.write_init('vec3 n = normalize(normal);')
|
||||
curshader.write('float cos_theta = clamp(n.z, 0.0, 1.0);')
|
||||
curshader.write('float cos_gamma = dot(n, hosekSunDirection);')
|
||||
curshader.write('float gamma_val = acos(cos_gamma);')
|
||||
|
@ -458,8 +457,6 @@ def parse_tex_environment(node: bpy.types.ShaderNodeTexEnvironment, out_socket:
|
|||
if rpdat.arm_irradiance and rpdat.arm_radiance and not mobile_mat:
|
||||
wrd.world_defs += '_Rad'
|
||||
|
||||
curshader.write_init('vec3 n = normalize(normal);')
|
||||
|
||||
return 'texture(envmap, envMapEquirect(n)).rgb * envmapStrength'
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue