Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Vertex attribute support #618

Closed
wants to merge 1,709 commits into from

Conversation

jombo23
Copy link
Contributor

@jombo23 jombo23 commented Apr 25, 2023

Here goes nothing...

PURPOSE

Adding vertex attribute support to RPR

EFFECT OF CHANGE

Named Vertex attributes such as colors, vectors, and floats will now be usable in materials.

TECHNICAL STEPS

Added mesh_attribute_names to RPRContext
Added set_primvar to pyrpr
Added a basic ShaderNodeAttribute Implementation that uses prior mesh_attribute_names
Added ShaderNodeAttribute into the input nodes list in rpr_nodes
Changed ShaderNodeLookup "Vertex Colors" to look up the new primvar version
Added basic attribute parsing to the mesh export

NOTES FOR REVIEWERS

There are some comments where I couldnt reasonably figure things out.
Bools, strings, and ints are not passed through as primvars, as I wasnt sure what the proper way to handle them in the material node section would be regarding rounding the numbers/clamping/rolling/etc, and of course, where could strings possibly go.

ShaderNodeAttribute doesnt care what 'attribute_type' is currently, and just uses the value straight from prorender.

The attributes are stored PER VERTEX, I did not implement handling them per face, as that requires a triangulated mesh, and I wasnt sure how to do that and maintain face order with the rest of the renderer.

There might be redundant casts in set_primvar in pyrpr. I figured cast > no cast. Python isnt my language

Updating attributes AFTER enabling viewport rendering causes them to all read 0. Im not sure how to fix the desync. This doesnt impact renders as I guess its synced every frame.

Enabling viewport rendering AFTER switching to edit/paint mode causes an out of bounds access in export.mesh.vertex_attributes because the attributes still exist but the data doesnt when youre in edit/paint mode?

I probably did things totally wrong with horrible syntax, but I honestly dont know any better, this is just about the second time I've ever touched python, so feel free to let loose with the criticism, I dont think what I did was done particularly well.

This is in multiple commits because I did this through the web interface instead of updating my local prorender build, so its likely that I may have missed an indent somewhere, or forgotten some line of code, but I dont **think** I did.

This is mostly for review only, and ill likely set up a proper fork locally if needed, So I'm marking this as a draft.

acb6d746-5075-4fe2-a835-a4b496d96e2f70d04a076d

tada

radeonprorender and others added 30 commits July 1, 2021 21:23
…DKs#312)

PURPOSE

Add Volume Scatter shader node support.

EFFECT OF CHANGE

Added support for Volume Scatter node.
Shader Editor -> Add -> Shader -> Volume Scatter
…DKs#316)

PURPOSE

Add Volume Scatter shader node support.

EFFECT OF CHANGE

Added support for Volume Scatter node.
Shader Editor -> Add -> Shader -> Volume Scatter
…ositor (GPUOpen-LibrariesAndSDKs#314)

PURPOSE

Need to add Outline render output for Compositor that will be useful for users and will add more options for render results.

EFFECT OF CHANGE

Outline pass appears in RenderLayers node when Full quality render option and Outline Rendering are enabled.
…dSDKs#319)

PURPOSE

Fix wrong destination path for datafiles

EFFECT OF CHANGE

Fix path issue causing material previews not working.
PURPOSE

Core 2.02.5.beta is available.

EFFECT OF CHANGE

Updated Core to 2.02.5.beta.
…t render. (GPUOpen-LibrariesAndSDKs#325)

Activate shadow catcher without error.
Fix an issue get KeyError 10 with shadow catcher activation. when Viewport render starts with activated reflection catcher.

EFFECT OF CHANGE

Fixed an issue get KeyError 10 with shadow catcher activation.
…t. (GPUOpen-LibrariesAndSDKs#324)

PURPOSE

Load image sequence in ShaderNodeTexImage and get correct result in Render and Viewport.
Investigate work of Cyclic and Auto Refresh options, and make them work as expected.

EFFECT OF CHANGE

Now Viewport and Render works as expected, compare to blender Image texture node in SEQUENCE mode.
Added support for Cyclic and Auto Refresh options in Image texture node.
Added support for also only numeric Image filenames for Image texture node .
…dSDKs#328)

PURPOSE

Improve the "hide in viewport" option, because it not hide objects correctly in some cases

EFFECT OF CHANGE

Added viewport update for hide/unhide object
Added viewport update for create/delete object
PURPOSE

Upscale filter should use 16 bit float

EFFECT OF CHANGE

Less memory usage with viewport upscale, also fixes GPUOpen-LibrariesAndSDKs#327 for me.
…PUOpen-LibrariesAndSDKs#335)

PURPOSE

Make Emission Strength in Principled BSDF work as expected. Add support for a value >1.

EFFECT OF CHANGE

Added Emission Strength support for Principled BSDF.
…tion End of Frame. (GPUOpen-LibrariesAndSDKs#336)

PURPOSE

Motion blur isn't applicable to camera motion with position End of Frame + there are other issues with setting required frame.

EFFECT OF CHANGE

Fixed issues with motion blur for frame positions 'Center of Frame', 'End of Frame'.
radeonprorender and others added 21 commits April 6, 2023 00:28
)

* Outline for work to be done.

* add space

* Separated quality for viewport and final renderer
Turned on blender denoiser via nodes isnstead regular.
Rename High to Interactive if hybrid pro is diabled.

* Now preset is executed in manner of Blender using bpy.ops.script.execute_preset.
Presets are located in rprblender/properties/presets.

* Fixed device selection.

* Made presets separately for FULL2, HIGH, HYBRIDPRO.
Added debug log messages if preset is applied.

* Removed RPR_RENDER_PT_denoiser pannel from UI.
Fixed error if denoiser node is None.

* Turned off upscaler and denoiser for NorthStar and Hybrid.
Removed upscaler and denoiser UI elements if Viewport Mode and NorthStar or Hybrid

* Removed settings denoiser and upscaler duplication for HybridPro.
Set default upscaler quality to FSR2_QUALITY_MODE_ULTRA_PERFORMANCE.
Removed unused math import.

---------
…ion 2.2.0 at the moment RadeonProRenderSDK provide OCIO 2.1.1 (GPUOpen-LibrariesAndSDKs#600)

* RPRBLND-2270: Improve OCIO support, Blender 3.5 upgraded OCIO to version 2.2.0 at the moment RadeonProRenderSDK provide OCIO 2.1.1.
Added constants BLENDER_OCIO_VERSION, SDK_OCIO_VERSION.
Implemented ocio_config_path, it returns ocio config depending of blender ocio version.
Put ocion config version 2.1.1 to rprblender/ocio.It was taken from blender 3.4
Added log messages.

* Switched to blender OCIO config.
Removed oico folder.
* RPRBLND-2275: instancing issue in RPR.
Implemented key function for mesh object.

* Use name_full instead of id.
Added missing UI elements:
RPR_RENDER_PT_advanced panel for Render Mode Final
adapt_viewport_resolution for Viewport Mode Final
…ndSDKs#602)

* RPRBLND-2269: Add Open VDB support in Blender 3.5.
Implemented support for VDB volumes using pyopenvdb module. It's built in Blender from version 3.5.
Added required code to create_grid_sampler_node function.

* Removed comments
…PUOpen-LibrariesAndSDKs#608)

PURPOSE
Regular Hybrid

Fix error when changing viewport render quality while viewport rendering AttributeError: module 'pyrpr' has no attribute 'RENDER_QUALITY_FULL2'.

Added validation for regular Hybrid plugin registration. Creation of empty context causes error -23 on some low-performance GPUs. (i. e. mx460).

NorthStar

Added missing UI element "Texture Compression".
EFFECT OF CHANGE
Fix error when changing viewport render quality while viewport rendering (regression).
Added missing UI element "Texture Compression" (regression).
…-LibrariesAndSDKs#586)

* RPRBLND-2251: Enable HIP / CUDA with RPR 3.0
Added hipbin dir, it contains precompiled HIP/CUDA kernels.
Adjusted create_zip_addon.py.
Updated RadeonProRenderSDK to the latest master Core 3.01.0.
Fixed build procces excluding "rprSetLogFunction", "RPR_GET_SUPPORTED_DEVICES_FUNC_NAME".
Added new string property "hipbin_dir" to RPR_RenderProperties.
Added property "hipbin_dir", Render->Debug->Hip Kernels.

* Removed hipbin_dir property from UI.

* Removed hipbin property.
Added hipbin_dir fuction.

* Update to the latest SDK master.
Improved condition for unsupported GPUs
pyrpr.ERROR_INTERNAL_ERROR == Error: Fatal error: Unable to create Vulkan device, VkResult=-8
pyrpr.ERROR_OUT_OF_VIDEO_MEMORY == Error: Can't create pool, VkResult=-2

* Improved warning.

* Fixed normal maps for hybridpro.

* Updated to the latest master.
Switch to submodule hipbin.
Improved build process.
Removed unused files.

* Update SDK to latest master (hotfix for multi GPU support in Northstar).

* Updated to the latest master HybridPro RC4.

* Updated to the latest master HybridPro RC7.

* Disabled RESTIR GI. Only regular RESTIR is enabled.

* Updated to the latest master Radeon ProRender 3.1.1.

* Updated to the latest master HybridPro RC8.
@bsavery bsavery requested a review from VascoPi April 26, 2023 22:05
@@ -561,14 +561,23 @@ def mark_static(self, is_static):
def set_vertex_value(self, index: int, indices, values):
ShapeSetVertexValue(self, index, ffi.cast("rpr_int *", indices.ctypes.data),
ffi.cast("float *", values.ctypes.data), len(indices))


def set_primvar(self, key: int, data, floatcount: int, count: int, interop):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename some variables:
float_count
interop -> interp or interp_type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do, was mostly following the names from the sdk. I thought interop was weird as well but didn't want to use and other term that was used somewhere else (which is why I figured they did it)

vColors = np.array(colors)
vColors = vColors.flatten()
vColors = np.ascontiguousarray(vColors, dtype=np.float32)
self.set_primvar(99,vColors, len(vColors), 4, PRIMVAR_INTERPOLATION_VERTEX)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the key here "99" ? I'm assuming this is a test. You could make a dictionary of primvar names -> number

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used 99 here based off of the sdk again. In terms of vertex color attributes, the name can be different between two meshes.

eg, mesh1 vertex color's attribute might be named "Attribute" (default) and mesh2's might be named "color"
there could even be a mesh3 which has two color attributes. one named "Attribute" and one named "color".

Assigning a static value to the active color attribute is the only way I can see to keep the active stuff active as the 'vertex color' attribute referenced elsewhere.

figure mesh1 would get 100, mesh 2 would get 101, and mesh 3 would have 100 and 102. How would the vertex color attribute know which to pick unless another list of what the active color attributes are per mesh was made.

I could be entirely misunderstanding, but that's how I interpreted it.

The sdk example started at 100, so so did I.

# Ints and Int8s are currently excluded as well, and byte color is stored as float anyway(?)
# Ignoring givens: uvmap and position
# Returning list of lists, [AttName, AttSize, AttData, AttInterop] Interop stored for future implementation Face/Edge types (im assuming which are far less common)
validAtts = [e for e in mesh.attributes if e.data_type in ['FLOAT', 'FLOAT_VECTOR', 'FLOAT_COLOR', 'BYTE_COLOR', 'FLOAT2']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again use snake case valid_attrs for variable names

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a slip by me, thanks. I normally write in camelcase with underscores for prefixing the "class" the function would belong to, lol.

@@ -112,6 +113,38 @@ def init_from_mesh(mesh: bpy.types.Mesh, calc_area=False, obj=None):

if calc_area:
data.area = sum(tri.area for tri in mesh.loop_triangles)

# Not possible to store strings/ bools in primvars. If the type was bool, it would be possible to just pass 1 or 0, and let it be interpolated, and then round it, but that would require extra code in the shaderattribute node
# Also cannot currently handle anything besides vertex attributes (point/corner), without triangulating the mesh first, which is over my head.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm not clear here. Why would you need to triangulate a mesh? Blender gives you attribues in what interpolation? Vertex / Uniform / Constant?

Anything thats varying across vertices is handled at the renderer to interpolate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In blender if you have a cube, and create an attribute with the domain of "face" you will get six values across the entire cube. The mesh is triangulated before it is sent to prorender, and I'm not sure how to get triangle level attributes out of blender after triangulation occurs. if you try to submit the six values to prorender as primvars, it throws a parameter error because the total values don't match the mesh triangle count

if data.vertex_attributes is not None:
for att in data.vertex_attributes:
if att[0] not in rpr_context.mesh_attribute_names:
rpr_context.mesh_attribute_names.append(att[0])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I would do it such that the mesh_attribute_names is a dictionary where the key:value is

attribute_name : index

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure of the proper way to go about this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably it's a good idea to use key: value, where key is the combination of a mesh key and attribute name, and the value is an index.
To make it easy to access attributes of a specific mesh during sync_update is the purpose.

@VascoPi
Copy link
Contributor

VascoPi commented May 1, 2023

Added the updates in #617 (reply in thread)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants